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