FW16 Vehicle Simulation
This simulation will be similar to our past project, MPXE.
It will log GPIO states, I2C transactions, SPI transactions, and CAN data. This includes mocking our LTC6811 ICs, current sense IC, and motor current/voltage.
Current Repo as of 15/12/2024 (Local testing on Aryan’s Github): https://github.com/Akashem06/Embedded_Simulation_Framework
DESIGN CHOICES:
The server and client interface will be done in C++ using TCP/IP sockets to maintain communication.
Everything will be modular to support scalable development. I have made it so the simulation framework can easily be ported to other chip families with varying GPIOs, I2C interfaces, etc.
Log data into a single JSON file, containing each project's info. (Could be transitioned to multiple JSON files per project, as a single file can become very large).
Currently, the C++ terminal is the user interface, but this can easily be transitioned to a more user-friendly GUI.
The mock drivers supported by the simulation are in the following list:
GPIO
I2C
SPI
CAN
Flash
CRC
ADC
LTC6811
MAX17261
Wavesculptor motor controller
Gpio Manager
Server Instance
Supports command generation for receiving all pin state/mode/alt functions.
Supports command generation for receiving single pin state/mode/alt function.
Supports processing/updating the JSON file after receiving a message from the client
Utilizes heap memory to dynamically allocate vectors to deserialize data. This allows for future expansion if needed!
Uses the heap to dynamically load/save the GPIO Json data. This way, if we are not updating JSON data, it is not stored in the background.
Client Instance
Support interacting with the C-drivers
Support packaging single pin state/mode/alt function.
Support packaging all pin state/mode/alt functions.
I2C Manager
To be completed
SPI Manager
To be completed
CAN Manager
To be completed
ADC Manager
To be completed
The client name can be passed in when running the program as an argument (using argc argv).
This prompts the question: Will we use a Python script to initiate the simulation, perhaps via SCons?
Depending on future GUI development, we could integrate some JSON parsing application to manage to start the simulation. To be determined.
We must synchronize the start of all programs. This could be done using a global barrier semaphore across all processes. This would require shmem. Another alternative is using a global START message sent to all clients. To be determined.
Application thread/scheduling for periodic data scraping
To be completed
The idea is to create a data scraping task that schedules when we fetch GPIO data, set ADC readings, update BMS data etc.
This can be done by generating multiple threads that sleep for x amount of time
This can be done by following suite with master tasks, and defining 3 frequencies at which data can be collected
This can be done by using the time library to allow data collection at certain times.
DESIGN IMPROVEMENTS/THOUGHTS
We could use UDP rather than TCP since everything will be running locally. This reduces message overhead. This would modify the base server/client classes. Everything is built on top of these base classes.
We could run the client projects on an external server like the Bay PC. This could be integrated into the CI/CD where the simulation can be used to verify the vehicle is functioning as expected (no faults/unexpected readings).
We could transition message structures to Protobufs to standardize everything.
Better synchronization/input buffering
I was dealing with some issues when rapidly sending bytes from the client->server (Separate messages, so each byte would trigger the callback, and it would not complete fast enough to handle the next byte).
One solution is to have an array store the received data so it can be buffered using a read/write pointer.
Another solution is to use a mutex/spinlock that blocks reading the socket until data is done processing? I will play around with this in the final development stages.
Aryan might have added too much abstraction; maybe we can remove some layers? Specifically between Datagram classes → Managers → Terminal interfaces? I think the abstraction makes the code pretty readable.