Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » DSDP - Real-Time Software Components (RTSC) » IPeripheral and driver development(How to use metaonly peripheral info in target driver)
IPeripheral and driver development [message #1725688] Sun, 06 March 2016 20:43 Go to next message
Chris H is currently offline Chris HFriend
Messages: 11
Registered: September 2014
Junior Member
I am currently creating generic peripheral drivers (UART, SPI, I2C, etc.) similar to TI-RTOS drivers but implemented using a proxy/delegate scheme like is done for the SYS/BIOS HAL. I would like to keep the device specific register address and structure information out of the driver itself and instead reference this information through a device specific peripheral module. I've seen https://wiki.eclipse.org/DSDP/RTSC_-_xdc.platform.ICpuDataSheet which looks promising. After looking through existing implementations of IPeripheral from TI I'm left confused since all modules inheriting IPeripheral are metaonly.

How can I spec registers and enumeration in IPeripheral modules and use them in the target code? My initial thought is this is not possible. Looking at the ti.sysbios.family.arm.lm4.Timer implementation and I see ti_catalog_arm_peripherals_timers_TimerRegsM4 all over the code. This structure is defined in a header file that is not generated by RTSC but is "contained" in the ti.catalog.arm.peripherals.timers package. Looking at MSP430 implementation is even more confusing since all the registers are defined in the modules but don't appear to be used anywhere. Have I missed the point of IPeripheral?
Re: IPeripheral and driver development [message #1725818 is a reply to message #1725688] Mon, 07 March 2016 21:37 Go to previous messageGo to next message
Sasha Slijepcevic is currently offline Sasha SlijepcevicFriend
Messages: 115
Registered: July 2009
Senior Member
Chris,
IPeripheral interface was created to be a configuration-time representation for device peripherals, and it was initially used only in Grace (http://processors.wiki.ti.com/index.php/Grace_Quick_Start_Guide). That's where you would find references to the registers and their fields defined in IPeripheral modules that you were looking for in the SYS/BIOS code. Using IPeripheral interface, devices declare available peripherals and then any module at the config time could generate appropriate runtime code based on the types of these peripherals. The generated code would directly write into the registers declared by an IPeripheral rather than invoking any API exposed by that IPeripheral. In fact, none of the modules that implement that interface have the runtime presence.
For example, SYS/BIOS code in ti/sysbios/family/msp430/Timer.xs only uses ITimer interface to find out which timers are on device, and then the values for direct writes to registers are generated.
I don't think that's the usage you intend for your drivers, so your drivers wouldn't gain much by inheriting from IPeripheral.

Now, I haven't spent much time thinking of what would be a good way to implement peripherals using a proxy/delegate scheme. I would definitely start from the existing ITimer interface in ti.sysbios.interfaces and its implementation in ti.sysbios.hal, and then work from there. If you do that, you'll probably have more specific questions, so please feel free to continue this thread.
Re: IPeripheral and driver development [message #1726008 is a reply to message #1725818] Wed, 09 March 2016 02:03 Go to previous messageGo to next message
Chris H is currently offline Chris HFriend
Messages: 11
Registered: September 2014
Junior Member
Here is a sketch of the proxy/delegate UART I'm currently using:

IUART.xdc
@DirectCall
@InstanceInitError
@InstanceFinalize
interface IUART
{
    // Config enums, etc...
    typedef Void (*CallbackFxn)(Ptr, Int);
instance:
    Int read(Void * buffer, SizeT size);
    Int write(Void * const buffer, SizeT size);
    // Config params...
}

Generic UART.xdc "used" in the target code
module UART inherits IUART
{
internal:
    /*! target/device-specific UART implementation. */
    proxy UARTProxy inherits IUART;
    struct Instance_State
    {
        UARTProxy.Handle pinst;
    }
}

The device specific UART.xdc driver inherits IUART:
@ModuleStartup
module UART inherits drivers.IUART
{
internal:
    struct Instance_State
    {
        Int portNum;
        Int32 baseAddr;
        // ...
    }
}

In this example the baseAddr of the port registers could be assigned at config time based on an IPeripheral module. I could just put all the register info in the spec file, but this would lead to duplication and fragmentation of register info and macros. The device catalog feels like the right package to hold this info and hence my question about IPeripheral. I can see how using IPeripheral for generated code would make sense for large families of similar processors like the MSP430. I could add the @TargetHeader attribute to an IPeripheral module but that doesn't give my any of the benefits of RTSC spec and seems hackish. So where would be a good place to store all the register structures and macros for a given processor?

[Updated on: Wed, 09 March 2016 02:13]

Report message to a moderator

Re: IPeripheral and driver development [message #1726257 is a reply to message #1726008] Thu, 10 March 2016 18:50 Go to previous messageGo to next message
Sasha Slijepcevic is currently offline Sasha SlijepcevicFriend
Messages: 115
Registered: July 2009
Senior Member
But, why do you want to expose registers in XDCspec files? In IPeripheral, the purpose is for other modules to generate C code with direct register reads and writes so the registers and their bits must be known at the config time. It seems that you are creating a generic API for accessing UART, similar to what TI-RTOS does, and the registers are not exposed in the generic header files for peripherals. Are you planning to let users directly configure initial values of some registers at the config time? That would be a good reason to expose registers, but that doesn't fit with the overall architecture where you have generic drivers, and that's what users access.
If you are using registers only internally in device-specific runtime code, then you have a couple of options. You could create internal config parameters that would get its values from an IPeripheral and then you would have these values accessible at runtime, without a need to hardcode these values in your XDCspec file. You could also do what TI-RTOS does, and get the register addresses from the appropriate driverlib products, from the header files and then XDCspec files are not even involved and they don't need to be. If there is no driverlib, and no IPeripherals for your device, then you can have these values hardcoded in your C sources, and there is no duplication.
Re: IPeripheral and driver development [message #1726453 is a reply to message #1726257] Mon, 14 March 2016 04:07 Go to previous messageGo to next message
Chris H is currently offline Chris HFriend
Messages: 11
Registered: September 2014
Junior Member
Sasha,

The registers would only be used by the driver code itself and not accessible to the user config. The idea is to have a consistent location to put device specific information. In general, a given driver may not be appropriate in all applications. For example, enabling an MMU may require a completely different driver. Knowing that drivers are not "one size fit all" it would be nice to provide a common peripheral module that could be reused by multiple drivers. The current IPeripheral interface can only accomplish this for template generated drivers. Even Grace doesn't generate the drivers themselves only the initialization routines.

Take for example ti.catalog.msp430.peripherals.adc.ADC10. If we ignore the config/instance parameters and assume this module was not metaonly, then this would allow anyone developing an ADC10 driver for the MSP430 to use this module and have all the register structures and enumerations available to them. At that point they could choose to generate a driver with a template as Grace does, hand-code the driver, etc. As you can see I care about more than the register values and addresses (I'm using standard RTSC solutions for that). I don't have a way with IPeripheral to, for example, write ADC10CTL0.SREF = SREF_3 without redefining these structures/enums in my own module or handcrafted header file.

If we drop the metaonly then wouldn't the existing IPeripheral modules generate header files that nobody would care about? Would there be any other implications or downsides to this? Perhaps we need an IPeripheral2 if IPeripheral can't support hand-coded drivers?

Most likely I'll create my header-only peripheral modules in the appropriate catalog package and not inherit from IPeripheral for now. It would be nice if we could support template generated and hand-coded drivers with a single interface module.

Thank you,
Chris
Re: IPeripheral and driver development [message #1726598 is a reply to message #1726453] Mon, 14 March 2016 23:40 Go to previous messageGo to next message
Sasha Slijepcevic is currently offline Sasha SlijepcevicFriend
Messages: 115
Registered: July 2009
Senior Member
Chris,
I understand now why you wanted to extend IPeripheral, and make it a runtime. The main concern with changing IPeripheral to a runtime interface would be compatibility with modules built with earlier versions of XDCtools. I would expect that going from metaonly to runtime is much less disruptive than the other way around, but I would have to check that first. It shouldn't be too much work and here is the enhancement request that I filed, and you can add your email to track progress - https://bugs.eclipse.org/bugs/show_bug.cgi?id=489605. Unfortunately, I can't promise any immediate XDCtools release with that change, so you are probably better off to start with your own hierarchy.

The biggest obstacle for me to spend much time on that problem is that the TI-RTOS team turned to various driverlib products to acquire register addresses and enums. That makes it unlikely that we will have RTSC packages that cover all the device families that SYS/BIOS and TI-RTOS support, and there are always new families and devices added to these products. Therefore, much less attention is paid to IPeripheral modules, except that they must not break anything.
Re: IPeripheral and driver development [message #1726600 is a reply to message #1726598] Tue, 15 March 2016 00:52 Go to previous messageGo to next message
Chris H is currently offline Chris HFriend
Messages: 11
Registered: September 2014
Junior Member
Sasha,

I'll try out the change on my end and report back if there are any issues. I'm currently using SYS/BIOS on an AM335x so I won't get any coverage of the supported platforms, but I can at least rebuild them as a first check. If there are any regression tests available that don't require a target let me know and I can try to run them.

Thanks,
Chris
Re: IPeripheral and driver development [message #1726614 is a reply to message #1726600] Tue, 15 March 2016 06:29 Go to previous messageGo to next message
James Lockwood is currently offline James LockwoodFriend
Messages: 43
Registered: July 2009
Member
Chris,

Having gone through this before, I would suggest you not use a proxy. Just inherit from an interface (like IUart) and call IUart_read( handle_IUart, ...). The reason for this is because you will be limited with the proxy to only ONE type of Uart driver. If you have an external Uart peripheral because you needed more Uarts than the chip itself had, you can just call IUart_<function_name> and IUart will follow the handle's vtable and call the appropriate driver-specific function.

We encountered this because we had to use I2C Gpio expander chips for more I/O, and also because we needed two Flash drivers / one for onboard (updating firmware), one for Spi NOR flash.

Good luck on your endeavors.



Re: IPeripheral and driver development [message #1727125 is a reply to message #1726614] Sat, 19 March 2016 16:43 Go to previous messageGo to next message
Chris H is currently offline Chris HFriend
Messages: 11
Registered: September 2014
Junior Member
Hi James,

That's a very good point. I've run into the need for what would be instance proxies before but haven't figured out how to implement them. If I understand your suggestion correctly, I would create instances of my UART module(s) which inherit from IUART, but call the IUART functions in the application code. I would also need to upcast the handles to IUART_Handle for the calls to work correctly. Then in my case all i need to do is remove the intermediate UART proxy module, clean up the call in the code and everything will just work.

Thanks for the tip!

Chris
Re: IPeripheral and driver development [message #1727541 is a reply to message #1725688] Wed, 23 March 2016 15:41 Go to previous message
James Lockwood is currently offline James LockwoodFriend
Messages: 43
Registered: July 2009
Member
Chris,

You don't even need to upcast anything.

Say for example, you have a command console module that uses a UART to send/receive. You want your command console to operate with any device, and not worry about which specific driver actually gets linked in, making the command console module useable for any device.

In your command console's .xdc file you would import the IUart, and then in your Module_State (or Instance_State if you really needed multiple consoles), you declare a variable as:

struct Module_State {
    ...whatever vars you need to declare...
    IUart.Handle handle_IUart;
};


you would, of course also have a config variable such as

config IUart.Handle handle_IUart = null;

When using it in your command console code, simply use something like:
#include <package/name/containing/interfaces/IUart>
....
numberOfCharsReceived = IUart_read( module->handle_IUart, &buffer, ....);


In your configuration script, you don't need to do anything special either. It would look something like:

Uart = xdc.useModule('someSpecific.chip.drivers.Uart');
CommandConsole_UartParams = new Uart.Params();
CommandConsole_UartParams.baudRate = 19200;
.....
CommandConsole_Uart = Uart.create(CommandConsole_UartParams);

CommandConsole = xdc.useModule('my.package.with.CommandConsole');
CommandConsole.handle_IUart = CommandConsole_Uart;

Previous Topic:Standalone Eclipse with ROV and GDB
Next Topic:Source location
Goto Forum:
  


Current Time: Thu Apr 18 07:08:53 GMT 2024

Powered by FUDForum. Page generated in 0.02371 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top