This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

IOM Driver as an XDC Module

Other Parts Discussed in Thread: SYSBIOS

Hello,

I'm looking to build an IOM driver as an XDC module to add extra configurability in the .cfg file. I am running into some issues with getting the driver functions table setup correctly. Below are some applicable code snippets:

Driver.xdc:

import ti.sysbios.io.DEV;
import ti.sysbios.io.GIO;
import ti.sysbios.knl.Queue;

module Driver
{
   struct Channel_s
   {
      Bool InUse;
      Int Mode;
      Int ProtocolId;
      Int TransportId;
      //Queue_Struct* PendingPackets;
      ti.sysbios.knl.Queue.Handle PendingPackets;
      Ptr NextPacket;
      Fxn CbFxn;
      Ptr CbArgs;
   };

   struct ChannelArgs_s
   {
      Int ProtocolId;
      Int TransportId;
   };

   config Int NumRxDescriptors = 8;
   config Int NumTxDescriptors = 8;
   config Int NumProtocols = 1;
   config Int NumChannelsPerProtocol[];
   config Int MaxRxBufferSize = 256;
   config Int NumRxBuffers = 16;
   config Int DmaChannel = 0;
   config Int RxInterruptVector = 0;
   config Int TxInterruptVector = 0;
   config Int MiscInterruptVector = 0;

   Int DriverInit();
   Int DriverBind();
   Int DriverUnBind();
   Int DriverChannelCreate();
   Int DriverChannelClose();
   Int DriverChannelControl();
   Int DriverSubmit();
   Int DriverRxSwi();
   Int DriverRxInterrupt();
   Int DriverTxInterrupt();
   Int DriverMiscInterrupt();
   Int DriverDmaInterrupt();

   config ti.sysbios.io.DEV.Fxns DriverFunctions = {mdBindDev     : DriverBind,
                                                    mdUnBindDev   : DriverUnBind,
                                                    mdControlChan : DriverChannelControl,
                                                    mdCreateChan  : DriverChannelCreate,
                                                    mdDeleteChan  : DriverChannelClose,
                                                    mdSubmitChan  : DriverSubmit
                                                   };
   instance:

   internal:

      // The module state will contain all Driver data
      struct Module_State
      {
         Int DeviceID;
         Int HWInitialized;
         Int NumProtocols;
         Int ProtocolIDs[];
         Int NumOpenInputChannelsPerProtocol[];
         Int NumOpenOutputChannelsPerProtocol[];
         Channel_s Channels[];
      }

      // unsure if this is needed yet
      struct Instance_State
      {
      }
}

test.cfg snippet:

var driverMod = xdc.useModule('prog.drivers.Driver');

//Add an entry to the device table
DEV.tableSize = 3;

//set up Driver
var dev0Params = new DEV.Params();
dev0Params.devid = 0;
dev0Params.instance.name = "TEST1";
dev0Params.initFxn = driverMod.DriverInit;
dev0Params.deviceParams = null;
Program.global.mDevEth0 = DEV.create("/TEST1", driverMod.DriverFunctions, dev0Params);

The error I get is:

js: "./test.cfg", line 102: XDC runtime error: prog.drivers.driver/DriverFunctions: incompatible assignment to mdBindDev : xdc.services.intern.xsr.Extern@a00185::&prog_drivers_driver_DriverBind__E

Is what I am attempting to do possible? Or am I stuck doing some of this in straight C? I'd prefer to use some of the pre-compile time features / configuration that XDC provides.

It should be possible since the old IDriver interface in IPC used to do this somehow.

Thanks!

  • Can you tell me the versions of SYS/BIOS and XDCtools you are using? The error message reminds me of the bug that was fixed in XDCtools 3.25.00.48: https://bugs.eclipse.org/bugs/show_bug.cgi?id=397709.

  • I was using 3.24.03.33 when I originally got the error. I just downloaded and installed 3.25.00.48, and the build gave the same error. I am using SYS/BIOS 6.34.01.14.

  • The issue does appear to be similar to the bug referenced.

    I also tried to use $externModFxn, and $externFxn which only add an extra & in front of the full C function name.

    I also attempted to move the initialization into the module$use() function in driver.xs only to get the same error in a different location.

    Depending on where I move things, I get a similar error in the config file if I set the init funtion in the device parameters structure to driver.DriverInit, However when I add $externModFxn to the init line, the error goes away. I'm guessing that adding the $externModFxn is incorrect though.

  • I fixed the issue with the init function. That was a type mismatch between Int func() and Void func(). I'm still confused on why the assignment to a Fxn is erroring.

    Is the issue possibly in the DEV.create call?

    when I call out driver.DriverFunctions in the create call, is that passing the pointer to driver.DriverFunctions? because that is what dev.create wants.

  • Based on how the init function acts vs the FXN struct, I'm beginning to think that the issue is the generic Fxn vs the well defined init function. Maybe the best solution is to turn the IOM.h file into an IIomDriver interface module?

  • What would work in your case is
    mdBindDev: "&DriverBind",
    mdUnBindDev: "&DriverUnBind",
    etc.
    The reason why your initial approach did not work is type-related, as you already found out. It's possibly a bug in our code, but I need to run some more tests before I can decide if I should file a bug.

    Anyway, when you declare a function in the XDCspec file and assing it to a field of the type Fxn:
    Int DriverBind();
    and then
    mdBindDev: DriverBind
    the signature of mdBindDev, which is Fxn, and the singature of DriverBind, which is Int (*)(), do not match. They probably should because in C code, Fxn is defined as function that returns an Int and takes no parameters. However, there is no typedef at the config time that would treat those two as the same type. If you tried to move the assignment to your xs file, using $externModFxn("DriverBind") would be the right choice, as described here http://rtsc.eclipse.org/docs-tip/The_XDCscript_Language#.24externModFxn.3Csymbol_name.3E.29. The function DriverBind is already declared and there is no need to declare it again, which is the reason we have $externModFxn, to avoid duplicate function declarations.

  • I have tried externModFxn a couple of ways and I still have errors.

    With driver Functions as a config value:

    function module$use()
    {
       Driver = this;

       Driver.DriverFunctions.mdBindDev     = $externModFxn("DriverBind");
       Driver.DriverFunctions.mdUnBindDev   = $externModFxn("DriverUnBind");
       Driver.DriverFunctions.mdControlChan = $externModFxn("DriverChannelControl");
       Driver.DriverFunctions.mdCreateChan  = $externModFxn("DriverChannelCreate");
       Driver.DriverFunctions.mdDeleteChan  = $externModFxn("DriverChannelClose");
       Driver.DriverFunctions.mdSubmitChan  = $externModFxn("DriverSubmit");

    }

    yields this error:

    incompatible assignment to mdBindDev : xdc.services.intern.xsr.Extern@1a61172::&DriverBind

    When I include DriverFunctions in the Module_State structure externModFxn works, but then how do I pass it in to the DEV.create call?

    On the side I've started the process of porting the key features in IOM.h into an XDC interface module in the hopes that I can move forward.

  • Another related question:

    the function table which needs to be passed in to DEV.create is the pointer to the table. If I am creating the pointer table with an XDC module config value, how do I pass the address of that config value? Or if I place the table in the Module_State, how do I get a pointer to it there?

  • I tried the:

    mdBindDev: "&DriverBind",
    mdUnBindDev: "&DriverUnBind",


    and I get a new error, further along the compile path:

    package/cfg/driver_test_pm4g.c:3182:5: error: (near initialization for ‘prog_drivers_Driver_DriverFunctions__C.mdBindDev’)
    package/cfg/driver_test_pm4g.c:3183:5: error: initializer element is not constant

    I have tried many other combinations, down to the fully qualified function name with the __E, and there ends up being some type mismatch somewhere down the road.

    My attempts at creating an interface module runs into the same type mismatch issues, just down in the DEV.create call.


    The only thing left I can think of to fix this is to edit DEV's Fxns definition to match the real function signatures. Then I can use the $externPtr() in the DEV.create call to pass in the pointer.

  • I think you got to the bottom of the real problem, which is that it doesn't seem possible to declare a function in an XDC file that would match xdc_Fxn, which is what DEV_create requires. I don't think you want to change anything inside the SYS/BIOS API either. What you can do is just work around type checking altogether. Create your structure and function in a template file Driver.xdt, that gets expanded in the generated C config file.
    typedef Int (*prog_drivers_Driver_MyFxn)();

    typedef struct prog_drivers_Driver_DriverFxns {
        prog_drivers_Driver_MyFxn mdBindDev;
        prog_drivers_Driver_MyFxn mdUnBindDev;
        prog_drivers_Driver_MyFxn mdControlChan;
        prog_drivers_Driver_MyFxn mdCreateChan;
        prog_drivers_Driver_MyFxn mdDeleteChan;
        prog_drivers_Driver_MyFxn mdSubmitChan;
    } prog_drivers_Driver_DriverFxns;

    Int prog_drivers_Driver_DriverInit() {
        return 0;
    }

    Int prog_drivers_Driver_DriverBind() {
        return 0;
    }

    Int prog_drivers_Driver_DriverUnBind() {
        return 0;
    }

    Int prog_drivers_Driver_DriverChannelCreate() {
        return 0;
    }

    Int prog_drivers_Driver_DriverChannelClose() {
        return 0;
    }

    Int prog_drivers_Driver_DriverChannelControl() {
        return 0;
    }

    Int prog_drivers_Driver_DriverSubmit() {
        return 0;
    }

    prog_drivers_Driver_DriverFxns myStruct = {
        prog_drivers_Driver_DriverBind,
        prog_drivers_Driver_DriverUnBind,
        prog_drivers_Driver_DriverChannelControl,
        prog_drivers_Driver_DriverChannelCreate,
        prog_drivers_Driver_DriverChannelClose,
        prog_drivers_Driver_DriverSubmit
    };

    Add a declaration in your Driver.xdc that points to your template
    @Template("./Driver.xdt")
    module Driver
    {
    ...

    and remove all driver functions and the structure DriverFunctions from Driver.xdc. And in your config script do the following:
    var dev0Params = new DEV.Params();
    dev0Params.devid = 0;
    dev0Params.instance.name = "TEST1";
    dev0Params.initFxn = "&prog_driver_DriverInit";
    dev0Params.deviceParams = null;
    Program.global.mDevEth0 = DEV.create("/TEST1", "&prog_drivers_Driver_myStruct", dev0Params);

    I'll file a bug related to this problem.

    https://bugs.eclipse.org/bugs/show_bug.cgi?id=410376