New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
driver/sensor: add unified management for sensor #2039
Conversation
Interesting. How do you envision this being used? |
Signed-off-by: dongjiuzhu <dongjiuzhu1@xiaomi.com>
@Donny9 are you thinking of this kind of being like the Linux IIO subsystem? What about triggering and devices that have multiple channels? |
|
Yes, this model is particularly similar to the linux iio system, whose upper and linux iio subsystems are functionally similar. Upper half layer of this model implements sensor_register api, circular buffer management, batch mode setting and expose push_event to lower half layer. |
Wtgahrs2 integrates multiple sensor: accel, gyro, mag, baro and gps. Signed-off-by: dongjiuzhu <dongjiuzhu1@xiaomi.com>
Change-Id: I0521098d6157c59d4e0d463e43a2d202797577b6 Signed-off-by: dongjiuzhu <dongjiuzhu1@xiaomi.com>
@Donny9 I would be very supportive of an approach like this. I had the same feeling trying to use the sensor subsystem and had asked about building something like this out a couple years ago. I probably have 10 or 15 of the sensors that are currently supported, especially the i2c ones, so I could probably contribute some of the lower half drivers over time and certainly do some testing. |
we can simulate the motion algorithm in sim platform with wtgahrs2 by serial interface "/dev/ttyUSBX" on ubuntu host. This driver of wtgahrs2 follow this model of i submitted. This is spec. it includes accelermeter, gyroscope, magnetic, baromenter, gps. |
I have written sensorhub software on linux and ceva/qcom dsp before, and i found that they are particularly good compared with the nuttx sensor driver. so i looked at rtt, linux, android hal, AliOS,zephy,mynewt_core. You can try porting a device on this model. https://github.com/alibaba/AliOS-Things/blob/master/include/service/udata/udata.h |
I also like the idea of unifying interfaces and reducing the need to repeat it across each sensor. But I worry if this is really a general sensor solution. Mainly since this introduces an intermediate buffering which may not be desired (due to space and added processing, in contrast to simply have the lower half write into the buffer passed by the caller). Maybe this buffer could optionally be disabled somehow. |
This is sensortest for this model. The url is apache/nuttx-apps#434 |
Seems like we could add an interface to register a buffer with the driver? IIO has this internal interface: |
The buffer is originally designed to solve the problem that the upper application fails to read sensor data timely due to jamming, and it will bring some protection. We suggest that the length of this buffer should be 2-3 sensor events for a sensor with a high sampling rate. If the buffer is low sampling rate, it can be set to 1 sensor event. The events generated in this sensor model are all active and not read by the read function, because the read function is sometimes slow, which can cause performance problems for application . |
@v01d what if the buffer itself could be reinitialized via ioctl? Then it would still be controlled by the application, but the buffer would reside in kernel space where is probably should be anyway? We would basically just call One of the other advantages is applications can query the kernel for a sensor value like instantaneous temperature without having to set up the sensor. |
Yes, we've thought about this way before. But I think it would be better to give the circular buffer pointer to the application via the read function? |
I generally think that makes sense I guess the question is if we make the buffer dynamic or not. I am inclined to allow the application to resize the buffer if the ref count on it is 0. |
@v01d and @btashton, there is one problem to let user control the buffer size: to support the hardware FIFO which is very popular on the new accel/gyro sensor model, sensor upper layer will extend the buffer temporarily to accumulate the bulk data and shrink the size once the userspace read out the data. Compare with IIO, the major difference is that:
The limitation for item 2 is to reduce the driver implementation complexity. |
I understand why the FIFO is important, but I think this still can work:
|
Yes, it could be added very easily with the current implementation. To simplify the design, we have two concept about the buffer size:
The first two items let user decide how much the jitter or latency should be used, the last item avoid the driver writer involve the complex buffer management. |
|
Regarding either driver or application buffer control, I think it is more important to let the application control it since the lower driver does not necessarily know how the user intends to access it. Also, how can you deal with ICs having different sensors inside? Sometimes these are different I2C devices in the same chip and sometimes they are the same device but with separate register sets (for example, temperature + pressure). While you could separate it into two drivers, sometimes this is not a good idea since it is better to be aware that they share a bus or that the sensor cannot actually give data from both independently. |
Where is this wtgahrs.c file? It does not seem to be part of this PR. Maybe I'm missing something. Regarding the sensor model itself, it is difficult for me to evaluate how well it maps to existing sensors. I think there's a risk of this being too restrictive and it is something that you will only find out when you try to look at various drivers and see if they all can work the same way or their behaviour would change. That said, we could merge this and consider it a feature that needs more evaluation before fully embracing it (and porting all drivers to it). I wouldn't want to have two sets of drivers: those that work with this interface and a lot of others that do not. Maybe as you say, it is a matter of slowly evolving this into something that considers all scenarios. Regarding the buffer, there are two points here. First, I think that for some drivers it is better to have the option of having no extra buffer at all. The posix read() will supply a buffer where the driver can directly write into. I don't think it makes sense for all cases to have an intermediate buffer. In that case, I would expect the intermediate buffer be skipped. Second, consider adding support for dropping old values when the queue is full. This came up recently with the ADC driver: most times you care more about last N values than first N values until buffer is full. |
Yes, Your concerns are understandable, but it is almost impossible for me to transplant all the existing sensors to this model at present. We can only recommend us to use the sensor model, and then gradually add new functions to improve it and replace the previous disordered model. On the two points thar you mentioned, the first one needs to add by read function directly read register content to save intermediate buffer, i will finish it as soon as possible; the seconds one for intermediate buffer, it's been taken into account in the design, we will overwire old sensor event when intermediate buffer is fulls. Finally, you can see wthahrs2.c in this commits, url:15c5ab7. Thanks for your advice. |
Thanks @Donny9 Regarding direct read, I'm not sure if we're talking about the same thing. I wasn't suggesting that you should be able to read I2C registers directly. I was suggesting that the lower part should be able to write into the pointer that read() receives directly. The push_event() interface means that this would not be possible. The only way would be that the upper part be able to request data from the lower part (something like read_sensor(), which would receive a pointer where to read into). This could be a blocking operation, compatible with blocking read. I think it would be good to consider such simple case as an option. It could also be done via signaling (the lower part could invoke a upper half method to signal that new data is available). |
I'm tempted to merge this with the understanding that this driver is experimental and we are not locking in the interfaces until the next release. If we did that I would expect that we work to make sure we resolve some of these questions. I think it is important that we consider the cost of turning this in terms of ram and flash for smaller platforms (which also may be lower power) which I think is part of what @v01d is getting at as well. Also there is the "Common Sensor Register Interface" that I think was intended to solve this same problem. I dont think it makes a lot of sense to be supporting three different classes of sensor drivers, so hopefully we can get down to one or two. |
Here, it's the plan for the new patch:
On the other hand, the current implelmentation(buffer + push_event) will activate If read_sensor is NULL. So the driver writer can select one approach which is more suitable for his case, but the userspace always use the same method to access the sensor regardless wether the buffer exist or not. |
I don't think that addresses the issue. Its not if the the lower half driver implements a buffer it is if the user can provide the buffer to be used. Perhaps we could allow the user application to register an actual FIFO? Right now I can have a temperature sensor and simply say I want to read 10 samples starting now. I do that by issuing a read of 10 bytes to the driver and providing it the buffer. This is nice and thin. Now for an IMU this is likely terrible. I want to be sampling data and processing it at the same time, this is where this interface here really shines. The question is how do we also support that give me 10 temperature samples to this buffer starting now case. |
So @btashton you want the userspace provide a buffer/FIFO to driver and avoid the memory copy?
|
I think we should be careful with that assumption, I could see wanting to bring ADC under this at some point in the future. The interfaces we currently have there are not ideal either.
I would rather let @v01d respond, I'm probably speaking too much for him on this. But I think the point is we are moving the buffer from the application to the kernel and by doing that causing this extra copy to happen as well as complicating things like flushing the sensor buffer. IIO has the one-shot via sysfs so I suppose that kind of read would be similar to what exists today, I guess the question is can the driver buffer be optional in that case? ADI and ST both have been involved in the IIO efforts in Linux so there certainly is buy-in for this kind of abstraction from companies who really care. I have only used it in the context of some of the ADI RF frontends. |
Base on the converation, I would suggest that we first merge this PR and then:
And then announce the new sensor driver model in the next official release. |
That sounds reasonable to me. I'll let@v01d sign off. I can do some sensor porting this weekend. |
Ok, I agree with your approach. I just merged. |
@Donny9 I am going to kick my sensor work until later in the week. I want to add support for the Linux i2c char device (https://www.kernel.org/doc/Documentation/i2c/dev-interface) to the simulator. That way I can plug in a FTDI 232H USB adaptor and hook up i2c/spi sensors directly to it and do all the work inside the simulator. Adafruit has a nice little adaptor (https://www.adafruit.com/product/2264) that has the Stemma QT connector on the end which is what most of the sensor dev boards I have use. |
Summary
Add unified management for sensor.
The driver model supports 24 kinds of sensor and provide a simple sensor driver model.
It's devided into two layers: upper half and lower half.
Upper half layer provides sensor character device registration, circualr buffer managerment, batch mode setting, etc.
Lower half layer mainly deals with sensor register and do sensor operation sets: activate, set_interval, batch.
Impact
It can make sensor driver more simple, management more convenient and more standard.
Testing
daily test