Home » Archived » DSDP - Real-Time Software Components (RTSC) » IPeripheral and driver development(How to use metaonly peripheral info in target driver)
|
Re: IPeripheral and driver development [message #1725818 is a reply to message #1725688] |
Mon, 07 March 2016 21:37   |
Sasha Slijepcevic 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   |
Chris H 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   |
Sasha Slijepcevic 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   |
Chris H 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   |
Sasha Slijepcevic 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 #1727541 is a reply to message #1725688] |
Wed, 23 March 2016 15:41  |
James Lockwood 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;
|
|
|
Goto Forum:
Current Time: Mon Oct 02 22:38:11 GMT 2023
Powered by FUDForum. Page generated in 0.01650 seconds
|