Well, I'm back to the task of getting some firmware running on a Kinetis KEA-series MCU - the automotive subfamily. Because sometimes the application calls for something more than just industrial spec.
I'd already noted that the support available under KDS is annoyingly different, and that KSDK support isn't there (and isn't planned for any time soon).
Well, now I have a little blinky-lights program running on the eval board using MQXLite, and it's time to bring in some real functions (like talking to the CPLD via I2C). And: the device-driver conventions are quite different. So I'll be needing to make a bunch of changes to, e.g., the I2C memory driver that was sitting around, already working on a different Kinetis part via KSDK and FreeRTOS.
Oh, well: another device-driver interface to figure out and hide behind my abstraction layer.
Update: Oh, great. This family of device drivers doesn't appear to be actually documented, aside from comments in the source files, and... oh. There's a missing function, SelectSlaveDevice, mentioned in the comments but nowhere to be found. Looks like, yes, it's necessary to go to the "Methods" tab for the device driver and enable that one. Between that little discovery and what I'm digging up from support fora, perhaps I'll be able to get this turkey communicating in the next few hours.
Update 2: OK, found the documentation. It's in Processor Expert's "Help on Component" thingy, accessible via right-click. Even includes a "Typical usage" example of sorts. Thing is, the scheme this device-driver model uses for initialization and whatnot is not friendly to device abstraction on buses. Oh, well: looks like I can't use static configuration for one-or-more memory-like peripherals, or maybe a level of indirection is required.
Update 3: Bad software architect! No pizza! Turns out the xxx_Init functions return a magical pointer, which is supposed to be passed to the subsequent I/O functions. If automatic initialization is turned on, the init code calls the xxx_Init functions and simply discards the returned values, rather than, say, saving them in global variables that follow some naming convention (e.g., xxx_Data) or just storing it in a static variable for future use (since xxx_Init and xxx_TweakBits live in module XXX.c and are specific to device xxx). So, for those device drivers that actually rely on the value, automatic initialization is right out, and each Init function must be called, once, from the application's initialization code and the returned value kept somewhere safe and passed to all the TweakBits functions.
Update 4: So now I'm trying to work at the LDD (Logical Device Driver) level, and having to implement my own blocking I/O operations. MQX Lite provides semaphores: good. But...
So I set an event handler to post to a defined semaphore on I/O completion (per device, and maybe per general operation type). But that means I'd bloody well better wait on completion after each operation that's expected to generate a completion event, because there's no method provided to reset a semaphore without waiting on it, and I really don't want to end up in a situation where I'm one completion event ahead and failing to wait on completion of the current operation.
Or I could just set VALUE to zero when I'm about to launch an operation and I'm not sure the semaphore is clean.
Comments