Waiting for 5 microseconds

Is it a way to wait (sleep or blocking) for 5 microseconds in TinyClr ?

Did you mean Thread.Sleep(0.05) ;

I belive you need to do on rlp code level

Thread.Sleep(0.05) ; would be great but only takes int !!!
For RPL, I’ve never used it, do you have examples ? (with tinyclr if possible !)

what’s the use case? Tight timing for some hardware / sensor?

It’s for a sensor, with two digital lines. A high level must send for 5 microsecond. so what I would obtain is:
pin.Write(High);
wait(5 micro);
pin.Write(Low);

I hope it is clearer.

clear, yes. Think you will need to go to RLP (netmf) or the interop (I think that’s the tinyclr OS equivalent?) to get that level of control. You might want to elaborate on the sensor and how it’s control works so the GHI team can suggest the most appropriate mechanism

I think a sleep of 5 Micro seconds in managed Code is a bit pointless.
If you want ta have a more or less exact 5 Micro second pulse, you Need to it completely (set, wait and clear of pin) in RLP (or whatever it’s called in tinyCLR).

To se if it would make sens:
Just try to toggle a pin in managed Code without a any delay in a Loop and check the frequency with an scope.
Only used G120 so far, but I guess even a g400 would not manage to toggle a pin every 5 Micro senconds from managed Code.

Then all that needs to be done in the interops, not just the sleep.

I’m trying interops, but I’m a little lost (maybe a tech talk soon :slight_smile: ).
I’ve created my native class:

    public static class Core
    {
        [MethodImpl(MethodImplOptions.InternalCall)]
        public static extern void WaitMicrosecond(uint param1);
    }

and create implementation of method:

#include "testNativeInterop.h"

TinyCLR_Result Interop_testNativeInterop_testNativeInterop_Core::WaitMicrosecond___STATIC___VOID__U4(const TinyCLR_Interop_MethodData md) {
	auto ip = (const TinyCLR_Interop_Provider*)md.ApiProvider.FindDefault(&md.ApiProvider, TinyCLR_Api_Type::InteropProvider);
	TinyCLR_Interop_ManagedValue self;
	// TinyCLR_Interop_ManagedValue ret;
	TinyCLR_Interop_ManagedValue field;

	// ret.Type = TinyCLR_Interop_ManagedValueType::U4;

	ip->GetThisObject(ip, md.Stack, self);
	ip->GetField(ip, self, InteropTest_InteropTest_MyNativeClass::FIELD___field___U4, field);

	auto tp = (const TinyCLR_Time_Provider*)md.ApiProvider.FindDefault(&md.ApiProvider, TinyCLR_Api_Type::TimeProvider);

	tp->Delay(tp, field);


    return TinyCLR_Result::Success;
}

I’ve already installed gcc but I launch build.bat I have a message saying there is no make command !

It’s possible GCC wasn’t added to the path. Make for me is found at C:\Program Files\ARM\bin\win_32-pentium\make.exe

One other thing to keep in mind, the overhead of invoking a native method is likely far greater than 5 microseconds. Your best bet is to implement the entire algorithm in native interops so you have precise control over all timings.

@John_Brochue : thanks for advice of overhead. For now, I just try to get familiar with interops, and I would like to see if I can do it entirely in visual studio (compilation of interop binary). After that, I implement all with interop.

Which version of gcc do you use ? For me (following doc at http://docs.ghielectronics.com/tinyclr/porting/intro.html) it’s gnu arm tool chain 6 2017 q2, but there is no make.exe

Sorry about that, that’s coming from a different tool. To get make, you could install something like MinGW or, if you’re on Windows 10, use the Windows Subsystem for Linux.

1 Like

Good idea !

Is it possible to have an example of a code method using ip->GetArgument I can’t use it.
What I’ve begun with is:

TinyCLR_Result Interop_testNativeInterop_testNativeInterop_Core::WaitMicrosecond___STATIC___VOID__U4(const TinyCLR_Interop_MethodData md) {
	auto ip = (const TinyCLR_Interop_Provider*)md.ApiProvider.FindDefault(&md.ApiProvider, TinyCLR_Api_Type::InteropProvider);

	TinyCLR_Interop_ManagedValue self;
	TinyCLR_Interop_ManagedValue argument;

	ip->GetThisObject(ip, md.Stack, self);
	ip->GetArgument(ip, md.Stack, Interop_testNativeInterop_testNativeInterop_Core::WaitMicrosecond___STATIC___VOID__U4, argument);
// Error with Interop_testNativeInterop_testNativeInterop_Core::WaitMicrosecond___STATIC___VOID__U4 param

	auto tp = (const TinyCLR_Time_Provider*)md.ApiProvider.FindDefault(&md.ApiProvider, TinyCLR_Api_Type::TimeProvider);

	tp->Delay(tp, argument);


    return TinyCLR_Result::Success;
}

But it seems there is a error with param size.

GetArgument is to extract an argument passed to the function, however, you’re passing an argument index based on a field: “WaitMicrosecond___STATIC___VOID__U4”. You’ll just want to pass an integer based on the argument number. Start at 0. If the method is an instance method, the this pointer is always argument 0, so the real arguments start at 1.

Since yours is static, try something like:

ip->GetArgument(ip, md.Stack, 0, argument);

Idea for this

could you add into source pice of code for example like

TARGETS/STM32F4/ STM32F4_INTEROPT.h ,
STM32F4_INTEROPT.cpp

on MAIN/main.cpp

but commented so in this case people in this way can
easy could extend their firmware without compiling separate way and through this can done marshalling

We can look into something like that. In the mean time, just put the cpp interop files in one of the folders where they can be compiled and call TinyCLR_Interop_Provider::Add in main. You can get an instance of the API provider on startup from the parameter passed to the soft reset handler (it’s invoked on startup too, not just after soft reset).

yes idea is just to simplifying procedure for that so people could add their needed api

and not need on startup (just for after startup is ok) much more simple like case above with problem
with adding 5 microseconds wait …

It’s fantastic !
Now, after some tweaks, I can build image inside VS !
What I’ve done: install Windows subsystem linux (WSL).
Install gcc for arm with : sudo apt install gcc-arm-none-eabi build-essential gdbserver openssh-server
Enable ssh: sudo ssh-keygen -A
Launch ssh:sudo service ssh start (this command must be called each time you start a new bash session)
Create a Makefile project and import all the files generated by c# project in pe/Interop folder (*.cpp and *.h).
Set remote build machine with localhost and use user create by installing WSL.
So VS copy all necessary file (.cpp,.h and don’t forget to put makefile, scatterfile, and TinyClr.h), build on remote machine and you can retrieve .bin file from remote system (Warning: a bug in VC++ for linux makes the project fails if you leave default settings for remote folder: ~/projects, you must replace it by a fullpath: /user/dev/projects for example)

2 Likes