allwpilib
allwpilib copied to clipboard
Allow sim device creation to be disabled
The use case for this is to allow the use and creation of simulation extensions that interact with real hardware. When using the simulation HAL, hardware objects will use SimDevice to control various values, like motor speeds. However, some teams may want to write a simulation extension that interacts with real IO, like SPI, CAN, or I2C. Instead of having to use the callbacks for each device they want to use, and possibly reimplementing the data processing for each device (read: parsing SPI/CAN/I2C packets) they can use HAL_DisableSimDeviceCreation to allow the devices to use their non-simulation SPI/CAN/I2C code, and simply implement the IO layer.
Basically, if I want to implement a simulation extension that uses simulation callbacks and something like Linux's open to allow communication with a SPI bus, I want the devices to use their non-sim SPI code so I don't have to parse SPI packets and use individiual device callbacks.
Does this actually do what you think it does? I'd like to see a concrete example, I don't think the API actually works this way unless you're implementing your own custom HAL.
Specifically:
Basically, if I want to implement a simulation extension that connects to an SPI bus, I want the devices to use their non-sim SPI code so I don't have to parse SPI packets and use individiual device callbacks.
If you aren't using a custom HAL, I don't think it will actually connect to any SPI bus unless you're linked to a HAL that allows that (and the simulation HAL doesn't).
It won't connect to a physical bus, but you can write a plugin that does so for most of the low-level bus calls, as the HALSIM layer does have mock hooks for most of them (but not all, e.g. auto-SPI is not shimmable). My worry with this though is having multiple plugins conflict (especially e.g. vendors trying to hook CAN layer calls will almost certainly step on each other). We would need to implement better bus sim hooks to really make this clean.
Would vendors implement the bus sim hooks, or would we? I have a SocketCAN extension, and I was kind of thinking about PRing that here.
If you aren't using a custom HAL, I don't think it will actually connect to any SPI bus unless you're linked to a HAL that allows that (and the simulation HAL doesn't).
I worded that badly. When I said connect, I meant using the simulation callbacks, like calling open to access a SPI port on Linux, and adding a registering a callback for writing SPI packets that uses write to send data over SPI.
I worded that badly. When I said connect, I meant using the simulation callbacks, like calling open to access a SPI port on Linux, and adding a registering a callback for writing SPI packets that uses write to send data over SPI.
Edit: I now realize what you're saying. I'm not sure this is the right approach for this, though.
Maybe not, but nearly every device, both in WPILib and in vendordeps, have a condition where if a valid sim device is created (HAL_CreateSimDevice doesn't return 0), it won't use real hardware, even if it's provided through HALSIM plugins and simulation callbacks. Doing another way would require a HUGE refactor. This is simpler and it works. I've tested this impl on a Raspberry Pi with a CAN bus and have sucessfully spun CAN motors.
This is implemented as a global disable. I think it would be more useful as a (set of) prefix disable(s) so it can be selectively applied to just specific devices.
This is implemented as a global disable. I think it would be more useful as a (set of) prefix disable(s) so it can be selectively applied to just specific devices.
As Raymond Chen would say, don't use global state to manage a local problem
How would vendordeps be handled? I'm using this to force REVLib to use its real code path for CANSparkMaxes. Also, what would level would the disables be on? Device-level? IO-level? IO-level (SPI, CAN, I2C) seems reasonable.
The only thing that makes sense is the name of the device. We don’t know what a SimDevice is mocking, only the name of it.