RLP method does not invoke after transition to NetFm 4.3 and Gadgeteer Packager 2014 R2 Beta 3

The following code worked fine with netfm 4.2 and Gadgeteer Package 2014 R1.


var elfFile = Resource.GetBytes(Resource.BinaryResources.RLPext_example);
RuntimeLoadableProcedures.LoadElfImage(elfFile);
RuntimeLoadableProcedures.InitializeBssRegion();
_programPinsAsInput = new RuntimeLoadableProcedures.NativeFunction("ProgamPinsAsInput");
_read = new RuntimeLoadableProcedures.NativeFunction("Read");
elfFile = null;

var response = new byte[9];
_read.Invoke(response);

Currently the RLP method does not fill the response byte array.

RLP has changed a bit in 4.3. There are some samples for each of the boards at https://www.ghielectronics.com/downloads/NETMF/RLPNativeSamples.zip that are known to work. I would first check to make sure that your compilation settings match those in the above scripts.

Skipping the managed part, could you be more specific about the changes at native part?

@ Simon from Vilnius - I believe it is mostly the addresses that have moved around a bit for some boards. I also improved the RLP header we provide a bit to make it easier to use and I made a few tweaks to the code itself that should increase calling efficiency a little bit.

Jeez guys could you be specific for once!!! :slight_smile: I have commercial customers, and they do lots of unpleasant things to my bottom when something “moves around a bit”! And when that happens I’m very keen to go to the Great Lakes and transfer some of those bad things to someone else! :wall:

So… I want to know exactly what has changed. I’m already aware that RLP address was fixed to 0x201A0000 for Cerberus, and that now I need an “–omagic” flag to make it work (still waiting for comments on that). RLP.h looks better, ok. Anything else? Especially about that “moving around a bit” thingy?

I added return value inside RLP method and I am able to read the value correctly at managed side. However It looks that changes made in input byte array inside RLP method are no longer marshaled back to managed side.

@ Simon from Vilnius - Cerberus is the only changed address. As for the --omagic flag, it is needed so we can correctly parse the ELF file. Cerberus did not support parsing ELFs before 4.3 so it wasn’t needed.

No board needed it so far (even Cerberus 4.2), and it looks like Cerberus 4.3 is the only one that requires it. What about G120, G400 and EMX then?.. Why don’t they require this option?..

@ Simon from Vilnius - The RLP makefile we ship with 4.2 for EMX has the --omagic flag in it. I started with RLP_User\EMX\RLP_Extensions_Example\Native\Makefile from 4.2 as a base for 4.3 EMX, G120, G400, and Cerberus. Cerberus 4.2 didn’t need it because we didn’t support ELF parsing for Cerberus back then. The --omagic flag is related to how the final ELF image is created as I understand it.

@ pgierasi - I am looking into that issue and will get back to you.

I have one more issue with RLP. The following code currently always return -1 (RLP->GPIO.Readpin returns 1). It worked properly before transition to Netfm 4.3. I am invoking the ReadPin method for pins: 61, 58, 60, 70 (9, 5, 7, 3 on Fez Spider socket 12)


int Read(unsigned int* generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
    char* bytes = args[0];

    RLP->GPIO.EnableInputMode(bytes[0], RLP_GPIO_RESISTOR_DISABLED);

    int counter = 0;
    int conunterMaxValue = 1000 * 15; // 15 ms timeout
    while (1)
    {			
	    if(counter++ >= conunterMaxValue || RLP->GPIO.Readpin(bytes[0]) == 0)     
              break;

  	    RLP->Delay(1);
    }
    if(counter++ >= conunterMaxValue)  return -1 * RLP->GPIO.Readpin(bytes[0]);

    ...
}

@ pgierasi - I am assuming that the code you posted last is the same code used for RLP in the first post. _read.Invoke(response); calls the int Invoke(byte[] generalArray, params object[] argList) overload. So your byte array is passed as the generalArray, not the first argument. Since you didn’t pass any other arguments, args[0] is undefined so you cannot rely on the results from the GPIO functions that use it. Try changing the third line to char* bytes = (char*)generalArray;

You are right. In SDK 4.2 the Invoke method had only 2 overloads:


Invoke()
Invoke(params object[])

There were also 7 methods with different name - InvokeEx

Now, all the methods have a name Invoke and the compiler picked Invoke(byte[], params object[] instead of Invoke(params [object[]).

I have changed my C# invocation to _read.Invoke(new byte[0], response) and now everything works correctly.