2022-01-31 Design Decisions:
Discussion:
Two modes: both share an init function which sets up memory and specifies kind
Periodic: Data is sent/received from the shared mem by the peripheral task at a regular interval
The values are filled on the tx/rx structs on initialization
Tx executed on regular intervals
Rx executed on regular intervals, with any information needed provided (ie for exchange)
To access data, task can call read_data which blocks if it is being used
Manual Request:
A separate “request” call is made, and fills the struct with the relevant data. This is non-blocking such that multiple peripherals can be requested concurrently
A read_data call is made at a later point in the software (after all requests are made). This is the same as above, and is blocking
The peripheral task blocks on the request call being made. It then handles the request the same way as it would with periodic, using the data in the struct
Once it completes, it allows the “read data” call to access the data and then blocks again until another request is made
Decisions:
FreeRTOS
Static Memory allocation for all APIs - Yes
Task Structure (Control Task groupings vs QP)
Control task design to start
Control Task design:
FSM model
Event queue associated with each
Critical should be able to return to prev state, keep track of how data is handled
Each fsm-task has an event queue
Need to add methods to raise events in correct queue
Read, process, post
Project runs through a cycle, blocks for predetermined interval after work is complete
Calls read data, executes functionality, txes any require data
Peripherals all run in separate tasks, so can execute concurrently
Reads of peripheral data happen regardless of whether new data has arrived
ISR stores data in shared memory, read task responsible for copying to fsm task
Event subscription model - use FreeRTOS queues
Enforced scheduling
Guaranteed messages going to and from different boards, see how many cycles board has gone through
Implicitly enforced, build around CAN cycles
Maybe have variable tick times??
Peripherals:
Shared Memory model
Keep hardware layer as thin as possible
Object Oriented approach
Option 1: We have a mutex for SPI and I2C, when a task wants an exchange it acquires a lock and does its thing. It may get interrupted by a high-priority task. (could be useful for simplicity with a priority complex risk)
FreeRTOS could handle this!
Option 2: Have an SPI task and I2C task with separate queues for each one. The blob of data can have a pointer to a mutex and a var address (essentially writing back data to memory) which could be synchronous. We can put this in a wrapper to make it alike to a synchronous I2C call. Can also do asynchronous tasks with extra caution.
-
Interrupt Design:
Gpio_it library → set event group flags, figure out how to deal with priorities
CAN Redesign:
Codegen:
CAN
Testability:
No more Mocking
Less #defines → for improved GDaBility
Enforce READMEs with penalty of death
Custom FreeRTOSConfig.h → Just custom
Tick time
CAN needs a broadcast module:
Notify subscribers when a thing happens
Single publisher multiple subscribers
Mainly for CAN rx
Validation: the DRI (person responsible) for a project should be the one validating it, so they keep validation in mind, as much as possible. (Will be more possible with COVID.)
We should have a model of how validation and unit testing should work. Makes peer review easier, so we can do more of that.
E.g.: FSM-like structure. Given, when, then.
Definition of done includes a validation plan and a smoke test plan.
Tickets:
FreeRTOS FSM task Library
GPIO_it Library
Use event_groups
Priorities of interrupts
Broadcast module
Check changes with new chip
Moving forward:
Figure out peripherals
How to handle critical events/interrupts