This is for design testing only. Not for hardware tests.
3 Types of testing
hardware tests (only on hardware)
design tests (only on simulation)
smoke tests (both?)
Due to the inclusion of FreeRTOS, tasks and functions must be designed in a way for ease of testability. Testing is super important especially in a real vehicle and it’s much more important that a vehicle is debug-able and understandable instead of optimal.
Newest VSCode has great use of the debugger:
Should use with JSON
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "/home/vagrant/shared/fwxv/build/x86/bin/projects/leds", "args": [], "stopAtEntry": false, "cwd": "/home/vagrant/shared/fwxv", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] } ] }
Inter Task communication
So there are different way tasks can communicate with each other, thus different ways for the tests to snoop data. The different ways in FreeRTOS are as follows
Global Variables
Queues
Messages
Stream Buffers
Function overloading
Global Variables
Global variables are defined on the top of the .c
file and are usually static
. This means that the variable is confined within the file its defined in. Since this is for design testing, we will predominately use these to snoop the internal data.
Queues
FreeRTOS queues is a FIFO that can hold a specific number of elements of a fixed size. This is usually used within a project. Tests should not access queues directly as that can create more issues.
Messages
Message buffers are variable length messages that can be sent from an ISR to a task or from task to task. Currently not really using it, but if we did, it would be complicated to test. Thus will not be accessing message buffers directly in tests.
Stream Buffers
Stream buffers are similar to messages except that it sends a stream of bytes one at a time. Since this is dynamically allocated we will not use this, but again should not be used directly in tests.
Function Overloading
Function overloading is a great way to change a function behaviour. Using this, its possible to change inputs and change firmware behaviour in the middle of a run. We can use function overloading to get the data that should be returned to a function, or change the output accordingly. This is what was predominately used in MSXIV and we could use it again, however, not strictly necessary.
Summary:
So in order to separate project functionality vs project testing, it’s important to keep them as far as part as possible. We want to keep projects as “black box” as possible in order to validate inputs and outputs. So as long as functions are black box, it’s possible and useful to do function overloading. However, something like overloading an entire task is not useful since we’re not testing anything useful.
Thus, it’s important to minimize the effect that tests have on the actual project to make sure that what is being tests is project functionality only.
Design of Testing Architecture (Steering)
So the design of the testing architecture will be similar to the CAN architecture. See CAN Documentation for more details.
Essentially since this is design testing and simulation only, don’t need to worry about the memory usage. So we will defined output and input global variables to evaluate “black box” testing.
I will be using the “steering” project from firmware_xiv
for how describing the new architecture.
Steering main():
So steering starts off with initializing all its module, then start processing the event.
Steering has 3 main functionalities:
Processing digital inputs
Processing analog inputs
Processing CAN data
Processing Digital Inputs
This is in steering_digital_input.c
and essentially it sets GPIO
interrupts to raise an event if an interrupt occurs.
Processing analog inputs
This is in steering_control_stalk.c
and essentially it calls an ADC
read periodically. Every ADC
read, it’ll run the callback and check the value parameters. It will raise an event if the ADC
read value satisfies the conditions.
Processing CAN data
This is in steering_can.c
and just sends CAN messages based on the event that’s read.
Steering Summary:
Thus there are 3 main functionality of steering
which will roughly translate to their own TASKS.