I am trying to get the RLPext functionality to work on my Cobra. I am using the following RLP native code:
#include "RLP.h"
/****************************************************************************************************
* Requires 7 unsigned int arguments: *
* DOGInitialize.Invoke(csPinNbr, clkPinNbr, cmdPinNbr, rstPinNbr,datPinNbr, blPinNbr, byteArray); *
***************************************************************************************************/
int Initialize(unsigned int *generalArray, void **args, unsigned int argsCount, unsigned int *argSize)
{
// save the control pin numbers
unsigned int LCDCS = *(unsigned char*)args[0];
unsigned int LCDCLK = *(unsigned char*)args[1];
unsigned int LCDCMD = *(unsigned char*)args[2];
unsigned int LCDRST = *(unsigned char*)args[3];
unsigned int LCDDAT = *(unsigned char*)args[4];
unsigned int LCDBL = *(unsigned char*)args[5];
unsigned char* byteArray = (unsigned char*)args[6];
byteArray[0] = LCDCS;
byteArray[1] = LCDCLK;
byteArray[2] = LCDCMD;
byteArray[3] = LCDRST;
byteArray[4] = LCDDAT;
byteArray[5] = LCDBL;
RLPext->GPIO.WritePin(LCDBL, RLP_TRUE); // backlight is on
return 5; // return some value
}
I created a wrapper class for the native code as follows:
using System;
using Microsoft.SPOT;
using GHIElectronics.NETMF.Native;
using Microsoft.SPOT.Hardware;
namespace DogLcdRlpWrapperClass
{
class DogLcdRlpWrapper
{
RLP.Procedure DOGInitialize;
/// <summary>
/// Creates an instance of the DOG LCD wrapper class
/// </summary>
/// <param name="elfImage">
/// The ELF image to load
/// </param>
public DogLcdRlpWrapper(byte[] elfImage)
{
// InitializeElf(elfImage);
// load the ELF image
RLP.LoadELF(elfImage);
// init the BSS memory region to zeros
RLP.InitializeBSSRegion(elfImage);
// get the all the RLP procedures
DOGInitialize = RLP.GetProcedure(elfImage, "Initialize");
}
/// <summary>
/// Initializes the LCD
/// </summary>
/// <returns></returns>
public int Initialize(byte csPin, byte clkPin, byte cmdPin, byte rstPin, byte datPin, byte blPin)
{
byte[] array = new byte[10] {1,2,3,4,5,6,7,8,9,0};
int result = DOGInitialize.Invoke(csPin, clkPin, cmdPin, rstPin, datPin, blPin, array);
return result;
}
}
}
And my test program is as follows:
using System;
using System.IO;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.Native;
using DogLcdRlpWrapperClass;
using SDCardFilesystemClass;
namespace DOG_LCD_Interface_Test
{
public class Program
{
static byte[] elfImage = null;
static OutputPort LCDCS;
static OutputPort LCDCLK;
static OutputPort LCDCMD;
static OutputPort LCDRST;
static OutputPort LCDDAT;
static OutputPort LCDBL;
public static void Main()
{
RLP.Unlock( /* <my unlock code is inserted here> */ );
SDCardFilesystem sdFS = new SDCardFilesystem();
if (sdFS != null)
{
FileStream fs = sdFS.OpenFile("\\SD\\RLPExtTest.elf", FileMode.Open, FileAccess.Read);
if (fs != null)
{
try
{
fs.Seek(0, SeekOrigin.End);
int flen = (int)fs.Position;
fs.Seek(0, SeekOrigin.Begin);
elfImage = new byte[flen];
int bytesRead = sdFS.ReadFile(fs, ref elfImage, elfImage.Length);
if (bytesRead != elfImage.Length)
{
elfImage = null;
}
}
catch (Exception ex)
{
elfImage = null;
Debug.Print(ex.Message);
}
}
sdFS.Unmount();
}
if (elfImage != null)
{
DogLcdRlpWrapper dogLcd = new DogLcdRlpWrapper(elfImage);
if (dogLcd != null)
{
// the following GPIO pin definitions are for the
// Cobra connected to the remote control I/O panel
byte csPin = 9;
byte clkPin = 12;
byte cmdPin = 11;
byte rstPin = 10;
byte datPin = 13;
byte blPin = 14;
// create the output ports to access the LCD hardware
LCDCS = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO9, true);
LCDCLK = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO12, false);
LCDCMD = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO11, false);
LCDRST = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO10, false);
LCDDAT = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO13, false);
LCDBL = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.IO14, false);
// initialize the LCD in native code
int stat = dogLcd.Initialize(csPin, clkPin, cmdPin, rstPin, datPin, blPin);
}
}
// Blink board LED
bool ledState = false;
OutputPort led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, ledState);
while (true)
{
// Sleep for 500 milliseconds
Thread.Sleep(500);
// toggle LED state
ledState = !ledState;
led.Write(ledState);
}
}
}
}
I created the ELF file for the native code using the yagarto tools and copied the ELF file to a SD card to load onto the Cobra. I then built the test appplication in VS2010 Express.
When I tested the application using the VS debugger to step through the code everything works until I get to the line of code that calls the native function “Initialize” in the RLP wrapper class. The code never returns from that call. In fact the results of that call was to render the Cobra unusable until I reloaded the firmware using the boot loader.
I then commented out the following line in the native code:
RLPext->GPIO.WritePin(LCDBL, RLP_TRUE); // backlight is on
and tried the application again. This time the call to Initialize returned as expected and the contents of array were as expected. This indicates that the native function Initialize executes properly. It also seems to indicate that the RLPext call is the problem.
I am using the latest GHI NETMF SDK (ver 4.1.5.0)
Any suggestions as to what I am doing wrong?
Any help will be appreciated.
Regards,
Synapsys