Just a "thumbs up" from me if you do this (or find something that exists 
that'll do it) - it's a perfect fit for my current project :)

>-----Original Message-----
>From: Matthew Trescott <matthewtresc...@gmail.com>
>Sent: 17 March 2022 05:55
>To: dev@nuttx.apache.org
>Subject: Abstract "channels" driver model
>
>Hi everyone,
>
>I was thinking about how to implement the software for my project (control
>module for a Formula SAE car) and realized that the basic ADC driver model is
>a bit inconvenient and creates a lot of extra overhead in userspace threads
>when implementing advanced features. Some features I think would make
>sense in an abstract “channels” driver model that would benefit many controls
>applications:
>
>- Only wake up a thread when a value has changed "significantly."
>
>- Support channels generated from bilinear/bicubic interpolation using a table.
>
>- Share the same ADC values among multiple threads with different priorities,
>like a high-priority safing algorithm, a medium priority control algorithm, 
>and a
>low-priority CAN broadcast thread.
>
>- Share the same ADC values among threads with different needs—the three
>listed above only care about the latest value, while a datalogging thread that
>saves to flash memory would want to save data in chunks.
>
>- Implement software filters and allow binding to userspace control algorithms
>for Kalman filtering.
>
>- Allow different threads to subscribe to epoll events at different rates.
>
>- Allow data received via an offboard, runtime-configurable serial bus like CAN
>or UART to be assigned a meaningful name and seamlessly used for userspace
>control functions just like ADC measurements, with a userspace helper thread
>de-serializing the messages as they arrive.
>
>- Allow the application to wait for two or more channels to be consistent.
>
>- Avoid unnecessary copies and support ADC DMA transfers.
>
>~~~~~~~~
>The model I have in mind is something like this:
>
>- Channels are char-devices; e.g. /dev/channels/throttle-position-1
>
>- A userspace application that only cares about the latest measurement would
>do something like this to get a pointer that always points to the latest 
>channel
>value and avoid the overhead of read():
>
>    uint32_t *throttle_position_1;
>    int tps1_fd;
>    tps1_fd = open("/dev/channels/throttle-position-1");
>    ioctl(tps1_fd, CHANIOC_SUBSCRIBE, (unsigned long)&throttle_position_1);
>    ioctl(tps1_fd, CHANIOC_SET_FILTER, ...);
>    poll(...);
>    // Do some calculations with *throttle_position_1
>    // Drive some output
>
>- A periodic userspace task that works with bulk data would read() from the
>ring buffer, or get a pointer to the ring buffer with an ioctl (not sure which
>would be better)
>
>- New data is copied to the ring buffer in the low- or high-priority work 
>queue.
>
>- Boardctl or board-init logic is responsible for setting up special ADC 
>triggering
>(e.g. from a PWM module) and telling the ADC backend driver to register itself
>as a channel. DMA can be set up so that ADC measurements are directly
>copied to the "latest value" location if no filtering or conversion is needed.
>
>- Software-generated channels are created with a syscall; the userspace
>thread can write to the resulting char device and the data will be stored in 
>the
>ring buffer and wake up any threads waiting on the software-defined
>channel.
>
>~~~~
>
>Looking for prior art, I noticed that there are the Common Sensor Register
>Interace and Sensor Cluster Driver Interface (drivers/sensors/README.txt).
>However, these don't cover ADCs or address the overhead of having a
>multiple-input control thread needing to use both epoll() and read(). Nor do
>they support filtering or multiple userspace threads accessing the same
>sensor in a convenient way.
>
>However, something like this might already exist, just not in mainline NuttX. 
>If
>you know of such a thing or have feedback on this idea, please let me know.
>Otherwise, I'll move ahead with working on it.
>
>Best regards,
>Matt

Reply via email to