Main Site Documentation

[CLOSED] A very simple tasking example?


#1

Converting basic methods from C# to C in order to execute them faster,
is not a big problem, but once it get’s down to all this native cpu stuff I’m lost.

I have taken a look at the examples in the RLP zip file,
but there’s to much information there which I don’t understand.

What I want to do is hopefully simple.

On the managed side I want to generate data (a byte[]).
This data will be generated at random times, triggered by external factors.

Then I want to set up a “timer” in RLP. Every time the timer is triggered,
it should fetch the byte[] from C# (as you cannot pin byte arrays in the native code right?)
and process it.

I’ve seen the Timer1_Init and PIN_ISR methods in the examples,
but I have absolutely no idea what information is relevant to me…

Can somebody show me a skeleton solution,
that only includes what is absolutely required to achieve what I want to do ?
And when cpu level stuff is included, perhaps try to explain it to me as if I’m a total n00b ?

Thank you


#2

I’ve only take a short look at the rlp stuff, but maybe it make sense to set the timer in managed code and the proccesing of the byte[] in rlp. i see no need to make a timer in rlp ?
but maybe i’m wrong ;D

cu
Andreas


#3

A tutorial page is in the works which RLP is part of … stay tuned.


#4

On the managed side many things will happen, with lower priority

  • Handle http requests
  • Accept Socket connections
  • Accept RS232 connections (not at the same time as a socket connection)

Meanwhile I need to create a 25fps update to an external screen,
screens are already updated using RLP (transforming and sending data to the screen is done in rlp)
so I was thinking about having the RLP code fetch the data to be transformed and send at a
constant interval, and I guessed doing this in RLP might cause it to take highest priority (simply interupting all managed threads) , speed and stability.


#5

Ok so right now you know how to schedule a task that will update the screen and reschedule itself in order to get 25 fps? The problem is you can’t keep reference to byte array in native code and wait for manages side to update it since GC can changed data allocation in memory (you mentioned that but i wanted to clarify this for others). You can however use RLP to trigger event on managed side:

void PostManagedEvent(unsigned int data)
http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/Index.html

triggers

RLP.RLPEvent
http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/Index.html

Using this, native side can request data update from managed side (manage side in response to event calls some update method on native side with new data argument all doesn’t do anything if no new data is available). Just calculate how often should the native side ask for new data (the less often the better)


#6

You can also use a native task that triggers itself. Take a look at tasks in RLP extensions and examples.


#7

Why request a managed byte array when nothing was changed? I would allocate a static buffer in native code and write rlp procedures to update the data. Rlp code always has access to the allocated buffer.

See my rlp rotation demo where I keep a sprite in a native static buffer.


#8

Indeed Wouter you’re right, that’s a better approach


#9

All sounds great guys,
but the point is that my knowledge of C is rather limited so some things
sound like chinese to me, the differnce being I understand quite a bit of chinese :slight_smile:

The examples have little to no meaning to me as there’s to much in there
of what I have idea what it does or if it’s even required.

What I know is this:

  • I know how to get a byte[] from C# to C
  • I know how to “output” this byte[] in C to the outputports

I’ve seen the documentation, read it over and over again,
but I’m afraid that if you don’t have a C background there’s just to much information missing.


#10

All sounds great guys,
but the point is that my knowledge of C is rather limited so some things
sound like chinese to me, the differnce being I understand quite a bit of chinese :slight_smile:

The examples have little to no meaning to me as there’s to much in there
of what I have idea what it does or if it’s even required.

What I know is this:

  • I know how to get a byte[] from C# to C
  • I know how to “output” this byte[] in C to the outputports

I’ve seen the documentation, read it over and over again,
but I’m afraid that if you don’t have a C background there’s just to much information missing.

@ Gralin:
"Ok so right now you know how to schedule a task that will update the screen and reschedule itself in order to get 25 fps? "

No I don’t, that’s the example I’m looking for, but with EVERYTHING that is not required removed.
Once I see the barebone of the solution, I’m sure something in my head will say “click”.


#11

The code below will show you how fast floating operations are using RLP (you can compare that to a managed solution). Just call it like this:


_blinkProcedure = RLP.GetProcedure(elfFile, "ToggleLed");
_blinkProcedure.Invoke((int)ledPin, 0);


 #include "RLP.h"

RLP_Task setPinHighTask;
RLP_Task setPinLowTask;
unsigned pin;

void DoCalculation()
{
	unsigned i;
	double result;
	
	for (i=0; i<100000; i++)
	{
		result = 17.1/18.2;
	}
}

void SetPinHighCallback()
{
	DoCalculation();
	RLPext->GPIO.WritePin(pin, 1);
	RLPext->Task.Schedule(&setPinLowTask);
}

void SetPinLowCallback()
{
	DoCalculation();
	RLPext->GPIO.WritePin(pin, 0);
	RLPext->Task.Schedule(&setPinHighTask);
}

int ToggleLed(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
	pin = *(unsigned char*)args[0];
	unsigned initialState = *(unsigned char*)args[1];
	
	RLPext->GPIO.EnableOutputMode(pin, initialState);
	RLPext->Task.Initialize(&setPinHighTask, SetPinHighCallback, 0, RLP_FALSE);
	RLPext->Task.Initialize(&setPinLowTask, SetPinLowCallback, 0, RLP_FALSE);
	
	if (initialState == 0)
		RLPext->Task.Schedule(&setPinHighTask);
	else
		RLPext->Task.Schedule(&setPinLowTask);
		
	return 0;
}


#12

@ Gralin Thank you !
Exactly what I needed. The no bullshit version.

It’s simple examples like these that make it easy to understand something :slight_smile:


#13

You’re welcome :slight_smile:


#14

Based on the example you’ve given me I am now able to understand the documentation better.
Another example, in case somebody else needs it. This time with ScheduleTimeOffset()


 #include "RLP.h"

RLP_Task renderTask;

int FPS_30_US = 33300;

unsigned outputPin;
unsigned outputState;


void Render()
{
	outputState = outputState == 0 ? 1 : 0;
	
	RLPext->GPIO.WritePin(outputPin, outputState);	
	RLPext->Task.ScheduleTimeOffset(&renderTask, FPS_30_US);
}
 
int InitializeRenderLoop(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
	outputPin = *(unsigned char*)args[0];
	outputState = 0;
	
	RLPext->GPIO.EnableOutputMode(outputPin, 0);

	RLPext->Task.Initialize(&renderTask, Render, 0, RLP_TRUE);
	RLPext->Task.ScheduleTimeOffset(&renderTask, FPS_30_US);
}

Basically it will invert the outputport 33 times per second.
(Notice the isKernelMode has been set to RLP_TRUE to insure the timming)