IoT Raspberry Pi 2 - Forcing load onto it - c#

My project contains of measuring temperature at different "loads" put onto the raspberry pi's capability to see whether making the raspberry work "harder" or not will affect the temperature sensor input. I am using windows 10 on my raspberry pi 2 model B and am having trouble finding enough sources about this, hence asking here.
Is it possible to somehow place a load upon the raspberry programmatically from Visual Studio as a universal application for the raspberry, in terms of perhaps forcing it to increase usage of the available RAM or perhaps limiting it? If so, what would be the best solution for this?
Is there any way to check, programmatically how much RAM it is using in total, by already implemented functions in a universal application project?
Is there any other way to "place loads" on the raspberry and being able to measure how much load you are forcing it to work?
Any type of help is very appreciated, thank you in advanced for the effort placed to answer these questions!

Is there any way to check, programmatically how much RAM it is using
in total, by already implemented functions in a universal application
project?
There is no direct API of getting total RAM in use but you can get available RAM will be used, in C#, do it like this:
[StructLayout(LayoutKind.Sequential)]
private class MEMORYSTATUSEX
{
public uint dwLength;
public uint dwMemoryLoad;
public ulong ullTotalPhys;
public ulong ullAvailPhys;
public ulong ullTotalPageFile;
public ulong ullAvailPageFile;
public ulong ullTotalVirtual;
public ulong ullAvailVirtual;
public ulong ullAvailExtendedVirtual;
public MEMORYSTATUSEX()
{
this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
}
}
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer);
// Alternate Version Using "ref," And Works With Alternate Code Below.
// Also See Alternate Version Of [MEMORYSTATUSEX] Defined As A Structure.
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", EntryPoint = "GlobalMemoryStatusEx", SetLastError = true)]
static extern bool _GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);
void GetProcessUsage()
{
MEMORYSTATUSEX data = new MEMORYSTATUSEX();
GlobalMemoryStatusEx(data);
System.Diagnostics.Debug.WriteLine(data.ullTotalPageFile + "\t\t" + data.ullAvailPageFile);
}
Is there any other way to "place loads" on the raspberry and being
able to measure how much load you are forcing it to work?
You may try this:
List<byte[]> list = new List<byte[]>();
while (true)
{
var buf = new byte[1024 * 1024 * 50];
list.Add(buf);
System.Diagnostics.Debug.WriteLine("Allocating memory");
await Task.Delay(1000);
}
Memory can be used for app is 390MB of Raspberry Pi 3 with 1GB RAM. For 512 MB models seems to be 185MB. You can use Windows.System.MemoryManager.AppMemoryUsageLimit to confirm your device.

Related

stackoverflow with dllimport from IIS

Scenario
I made a Wrapper class for a C dll so I can call its functions from managed code and I can access them from a c# WCF Service. Everyting seems fine, but when allocating a lot of memory in the C library. IIS does not seems to like it. It will give me a stackoverflow exception.
Question
When allocating memory in the C dll. It breaks in IIS.
char stmt[163840+1]; // allocation a lot of memory
char stmt2[163840+1]; // allocation a lot of memory
Does IIS have special setting to allow more memory to be allocated from the C module?
Code which expose C dll functions
Steps:
1. use SetDllDirectory
2. LoadLibrary
3. then call my function with DLLImport
4. FreeLibrary
The NativeClassWrapper code (Simplefied)
[SuppressUnmanagedCodeSecurity]
public static class NativeClassWrapper
{
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr LoadLibrary(string hModule);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);
[DllImport("myCDll.dll", EntryPoint = "MyFunction", ExactSpelling = false, SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
public static extern int MyFunction(
);
}
C code
long MyFunction () {
char stmt[163840+1]; // allocation alot of memory
char stmt2[163840+1];
long lReturn = 0L;
*stmt = '\0';
*stmt2 = '\0';
return lReturn;
}
char stmt[163840+1]; // allocation alot of memory
char stmt2[163840+1];
These allocations are responsible for the stack overflow. You are attempting to allocate large arrays on the stack, and the stack is not large enough. The default stack for a Windows application is 1MB. The arrays on their own will not overflow such a stack. However, it's quite plausible that IIS uses smaller stacks, or that there is not code that you have not shown that makes similar large stack allocations.
If you really need to allocate such large arrays, you'll should do so on the heap.
thanks David Heffernan for youre response. I accpet his answer because it helped me to this solution. The solution I choose was to Start the process that communicates with the C Dll on a different thread and allocate the stacksize to 1MB instead of the default 256KB
public void StartNewThread()
{
const int stacksize = 1024*1024; // 1MB
var thread = new Thread(NativeDllProcess, stacksize);
thread.Start();
thread.Join(); // Wait till thread is ready
// .. rest of code here
}
private void NativeDllProcess(object info)
{
// ..... Code thats calls C dll functions
}
More information here :
maximum / default stack size IIS
By default, the maximum stack size of a thread that is created in a native IIS process is 256 KB
 Email
 Print
SUMMARY
By default, the maximum stack size of a thread that is created by a native Microsoft Internet Information Services (IIS) process is 256 KB prior to Windows Server 2008. For example, when Inetinfo.exe, DLLHost.exe, or W3wp.exe creates a thread in IIS 5.0 or IIS 6.0, the maximum stack size of the thread is 256 KB by default. You can also explicitly call the CreateThread function to specify the stack size of the thread. In Microsoft Windows 2000, if the Microsoft ASP.NET Worker Process (ASPNet_wp.exe) creates a thread, the maximum stack size of the thread is 1 MB. In Windows Server 2008 and higher, the maximum stack size of a thread running on 32-bit version of IIS is 256 KB, and on an x64 server is 512 KB.
NOTE: Internet Information Services is a multi-threaded web application platform that allows application code running inside of each worker process to utilize hundreds or more threads at once as necessary. Each thread is bound by the same stack size limit in order to keep the virtual memory usage of the process within manageable limits.

Get current sound volume windows 8

The result of the sound level is always 0, wether i have the sound muted or at max volume.
What is wrong ?
[DllImport("winmm.dll")]
private static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
public int GetCurrentSoundValue()
{
uint currentVolume;
int result = waveOutGetVolume(IntPtr.Zero, out currentVolume);
return result;
}
Ever since Windows 7/Vista, microsoft changed the permissions to modify low level audio. Instead you have to use CoreAudio API. I can't provide too much info as I haven't really played around with it, but here's a link: CoreAudio API
Good luck!

How to set MinWorkingSet and MaxWorkingSet in a 64-bit .NET process?

How do I set MinWorkingSet and MaxWorking set for a 64-bit .NET process?
p.s. I can set the MinWorkingSet and MaxWorking set for a 32-bit process, as follows:
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern IntPtr MyGetCurrentProcess();
// In main():
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, int.MaxValue, int.MaxValue);
Don't pinvoke this, just use the Process.CurrentProcess.MinWorkingSet property directly.
Very high odds that this won't make any difference. Soft paging faults are entirely normal and resolved very quickly if the machine has enough RAM. Takes ~0.7 microseconds on my laptop. You can't avoid them, it is the behavior of a demand_paged virtual memory operating system like Windows. Very cheap, as long as there is a free page readily available.
But if it "blips" you program performance then you need to consider the likelihood that it isn't readily available and triggered a hard page fault in another process. The paging fault does get expensive if the RAM page must be stolen from another process, its content has to be stored in the paging file and has to be reset back to zero first. That can add up quickly, hundreds of microseconds isn't unusual.
The basic law of "there is no free lunch", you need to run less processes or buy more RAM. With the latter option the sane choice, 8 gigabytes sets you back about 75 bucks today. Complete steal.
All you have to do is change your declaration like so:
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize",
SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess,
long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize);
The reason is because of the definition of the SetProcessWorkingSetSize function:
BOOL WINAPI SetProcessWorkingSetSize(
_In_ HANDLE hProcess,
_In_ SIZE_T dwMinimumWorkingSetSize,
_In_ SIZE_T dwMaximumWorkingSetSize
);
Note that it doesn't use a DWORD (as 32-bit integer) but a SIZE_T, which is defined as:
The maximum number of bytes to which a pointer can point. Use for a
count that must span the full range of a pointer. This type is
declared in BaseTsd.h as follows:
typedef ULONG_PTR SIZE_T;
This means that it's a 64-bit value, hence the ability to change to a long and have the function work on 64-bit systems. Also, from the section of MSDN titled "Common Visual C++ 64-bit Migration Issues":
size_t, time_t, and ptrdiff_t are 64-bit values on 64-bit Windows operating systems.
However, this presents a bit of a dilemma, in that you don't want to have to compile platform-specific assemblies (that would be a PITA). You can get around this by taking advantage of the EntryPoint field on the DllImportAttribute class (which you're already doing) to have two method declarations:
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize",
SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize32(IntPtr pProcess,
int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize);
[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize",
SetLastError = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool SetProcessWorkingSetSize64(IntPtr pProcess,
long dwMinimumWorkingSetSize, long dwMaximumWorkingSetSize);
Now you have two separate signatures. However, knowing which signature to call is still an issue. You don't want to place conditional checks everywhere. To that end, I'd recommend creating a method that performs the check for you and call that.
You'll want to use the Is64BitProcess property on the Environment class to make this determination. Don't use the Is64BitOperatingSystem property. You want the former because 32-bit processes can be run on 64-bit operating systems, and you want to make sure that your code is resilient to that; just checking to see if the operating system is 64 bit doesn't give you the entire picture.

C# : How to detect if screen reader is running?

How to detect if screen reader is running (JAWS)?
As I understand in .NET 4 we can use AutomationInteropProvider.ClientsAreListening from System.Windows.Automation.Provider namespace, but what if I have to do it for .NET 2.0?
I tried to inspect ClientsAreListening source code, it calls external RawUiaClientsAreListening method from UIAutomationCore.dll library.
Do you have any ideas how to implement JAWS detection in .NET 2.0?
Use the SystemParametersInfo function passing a uiAction of SPI_GETSCREENREADER.
You will need to use P/Invoke for this, for example:
internal class UnsafeNativeMethods
{
public const uint SPI_GETSCREENREADER = 0x0046;
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref bool pvParam, uint fWinIni);
}
public static class ScreenReader
{
public static bool IsRunning
{
get
{
bool returnValue = false;
if (!UnsafeNativeMethods.SystemParametersInfo(UnsafeNativeMethods.SPI_GETSCREENREADER, 0, ref returnValue, 0))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "error calling SystemParametersInfo");
}
return returnValue;
}
}
}
This is possibly better than using the ClientsAreListening property as this property appears to return true for any automation client, not just screen readers.
Also see:
Using SystemParametersInfo from C# (SPI_GETSCREENREADER SPI_SETSCREENREADER) (Stack Overflow)
INFO: How Clients and Servers Should Use SPI_SETSCREENREADER and SPI_GETSCREENREADER (Microsoft KB)
You should also listen for the WM_SETTINGCHANGE message to detect if a screen reader starts / stops running.
Update (in response to BrendanMcK's comments):
Although this is never explicitly documented in as many words, looking at the description of the flag I think the purpose of this flag is relatively clear:
Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information in situations where it would otherwise present the information graphically.
What this is saying is that applications set this flag whenever an application wishes the UI to behave as if a screen reader is running, regardless of whether or not that application is actually a screen reader or not.
Suitable things to do in response to this flag is to add text in order to "read" otherwise intuitive UI state to the user. If radical changes are needed to make your UI screen reader accessible then the chances are that your UI also isn't that intuitive to sigted users and could probably do with a re-think.

Accessing GPS Data From a .Net Winform Application

Does anyone out there have any experience programatically retreiving the lat/long from a GPS attached to a mobile PC? A team I'm on is currently looking at hardware options--as the programmer who will eventually have to live with whatever is selected I was wondering if anyone out there has had experience writing .Net programs that interface with a GPS? Any recomendations for hardware and/or programming would be greatly appreciated.
As I envision it, my application will need to ask the GPS for the current lat/long perhaps once every 10 to 20 seconds.
I've written such an application before.
As Henk said, you listen on a COM port. Build a component that reads the com stream in, in say a 1024 buffer. that'll be plenty to contain at least 1 complete NMEA sentence. From there, read the input until you find the start of a sentence and parse it. If for some reason you don't have the full sentence, read in another buffer, append and continue/try again.
If you're willing to be dependent on Windows 7, there's a Location API that handles the NMEA decoding for you.
If the Gps is integrated within your windows CE PC or windows mobile phone, you can simply use the GPS Intermediate Driver to pool for information.
Since you are in a .net environment, you could create a .Net wrapper to this native API.
public class GpsHardware
{
private const string gpsLibraryName = "gpsapi.dll";
private const string coreLibraryName = "coredll.dll";
[DllImport(GpsHardware.coreLibraryName, SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EventModify(IntPtr hEvent, uint function);
[DllImport(GpsHardware.gpsLibraryName, SetLastError = true, CharSet = CharSet.Unicode)]
private static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, uint dwFlags);
[DllImport(GpsHardware.gpsLibraryName, SetLastError = true)]
private static extern uint GPSCloseDevice(IntPtr hGPSDevice);
[DllImport(GpsHardware.gpsLibraryName, SetLastError = true)]
private static extern uint GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, uint dwMaximumAge, uint dwFlags);
[DllImport(GpsHardware.gpsLibraryName, SetLastError = true)]
private static extern uint GPSGetDeviceState(IntPtr pGPSDevice);
...
}
Of course you will have to deal with marshaling and all the great interop things :)

Categories

Resources