CSHARK Recruitment task - Reading sensor data using freeRTOS
The project is intended to be build on Linux machine ( preferably Ubuntu 24.04 LTS )
I use the NUCLEO-G431RB board from ST as a host MCU platform. The sensor I'm about to read ain't real (Couldn't find anything interesting at home). I simply emulate it on the serial port on PC with basic python script. The sensor gets single byte data request from MCU 0xAA, and responds with host PC CPU temperature ( float ) followed by the 8-bit CRC. Underlying uart interface is configured in simples blocking mode.
Firmware functionality as described in requirements: Two FreeRTOS tasks. One for reading and one for processing the data. Data exchanged between tasks through the rtos queue. Data post processing is a simple "moving average" mechanism.
- Custom CMake-based build system that handles cross-compilation and native unit test build as well
- Negligible usage of CubeMX generated code
- Using original freeRTOS repository ( not the one provided with Cube package or generated by MX )
- RTOS, MCU package and unit test frameworks are a submodules in this repository
- Cpputest framework for unit testing
- Development under MS Visual Studio Code with extensive usage of CMake tools extensions for the IDE configuration
I'm not going to list all prerequisites here... Assuming that arm-none-eabi-gcc, CMake, Make, Binutils etc. are installed...
( only once ) Fetch Submodules ( CppuTest, Cube G4, freeRTOS-kernel )
git submodule update --init --recursive --depth=1
- Configure Cmake
cmake -B ./build_firmware -DCMAKE_BUILD_TYPE:STRING=Debug -DTARGET_PLATFORM:STRING=EMBEDDED -DCMAKE_TOOLCHAIN_FILE:FILEPATH=cmake/gcc-arm-none-eabi.cmake .
- Build
cmake --build ./build_firmware
- Flash target
STM32_Programmer_CLI -c port=swd -D ./build/Debug-EMBEDDED/cshark_test.elf -rst
- Configure Cmake
cmake -B ./build_unit_tests -DCMAKE_BUILD_TYPE:STRING=Debug -DTARGET_PLATFORM:STRING=UNIT_TESTS .
- Build
cmake --build ./build_unit_tests
- Run unit test executables
./build/Debug-UNIT_TESTS/test_runners/test_sensor_test_suite -v -b
- All data processing methods should be covered by unit tests to ensure their proper operation.
- All interfaces ( or other dependencies ) should use a dependency injection pattern and should be mocked when used in unit tests ( example provided )
- Integration tests for processes cooperation should be provided
- Manual testing of device functionality
- Regression prevention should be covered by the automatic tests building and running in CI pipeline
- Separate module for CRC calculation and use of G4 CRC peripheral for faster calculation
- Improved uart class to make use of interrupts and/or DMA and a better error handling and race condition prevention.
- (as above) make use of RTOS mutexes to prevent collisions when accessing physical interfaces from multiple threads
- Create bootloader and implement runtime firmware upgrade ability ( preferably secureBoot concept )
- Analyze the risc of error occurrence in the business logic code and provide a robust handling
- Checking the code against standards / formatting (clang-format, cppcheck, etc...)
- Building the production code (cross compilation before tests as there is no sense to run unit tests if the target code does not build well)
- Building the testing code
- Running tests
- Post processing ( binary files encryption, generating crypto keys, etc...)
- Storing artifacts and build log files
- Deployment binary artifacts to production server / device where multiple devices could be flashed