This repository holds all the code that runs on our CubeSat's onboard computer (OBC).
adcs/- All code for the attitude determination and control system subsystem.
cdh/- All code for the command and data handling subsystem.
common/- All code that is shared between the subsystems (ex: logging)
comms/- All code for the communications subsystem.
drivers/- All device drivers and helper functions for modules (I2C, SCI, ADC, etc.)
eps/- All code for the EPS subsystem.
examples/- Example programs to help other developers.
hal/- The hardware abstraction layer generated by HALCoGen.
payload/- All code for the primary and secondary payload.
posix/- The Posix port for FreeRTOS which allows developers to test code on Linux.
This section will explain how to set up the repo, and how to build, flash, and debug the code.
The following software should be installed:
- GCC ARM Embedded Toolchain - Used to build the firmware
- HALCoGen (Only available on Windows machines) - Used to generate the HAL
- UniFlash - Used to flash the RM46
- Code Composer Studio - Used for debugging, but can also be used as a general IDE
Instructions on how to install these tools can be found on this Notion page.
This project is hosted on GitHub. You can clone this project directly using this command:
git clone git@github.com:UWOrbital/OBC-firmware.git
You can build the project using these commands at the top-level of the repo:
make clean # Delete any previous build files
make # Build the executable for the dev version of the firmware. The .out file should appear in the build directory.If you get a main() already defined error, remove the hal/source/sys_main.c file by running make clean.
To build the release version of the firmware, run the following:
make clean
make DEBUG=0 # You can also specify the BOARD_TYPETake a look at global_vars.mk to see what other variables can be passed in with the make command.
More information can be found on this Notion page.
Information about flashing the device and debugging can be found on this Notion page.
- Make sure you're added as a member to the UW Orbital organization on GitHub.
- Create a feature branch for whatever task you're working on.
- Our branch naming scheme is
<subteam>/<developer_name>/<feature_description>. Ignore the<developer_name>part if the branch has multiple developers. - Example:
cdh/daniel/implement-random-device-driver - Another example:
cdh/implement-random-device-driver
- Our branch naming scheme is
- Make a PR. Make sure to at least add the CDH leads as reviewers and ping the CDH pr channel on Discord. You may also want to add your subteam lead(s) as a reviewer if you're not on CDH.
- Pull requests should include information on, at minimum, the purpose of the PR, new changes made in the PR, tests performed to verify that the code works, and changes that can be made in future iterations of the feature. See this sample template for more. It’s good practice to have a PR template in a .github folder in every repository you create. GitHub will pull from this template every time a new PR is made.
- Make any requested changes and merge your branch onto main once the PR is approved.
Variable and function names should be descriptive enough to understand even without comments. Comments are needed to describe any complicated logic. You may use // or /* */ for single line comments.
Function comments should exist in both the .h and .c files optimally, but at minimum they should be available in the .h files. Comments should follow the format shown below:
/**
* @brief Adds two numbers together
*
* @param num1 - The first number to add.
* @param num2 - The second number to add.
* @return uint8_t - Returns the sum of of the two numbers.
*/
uint8_t add_numbers(uint8_t num1, uint8_t num2);- File comments are not required
- The symbol name should have the form
<PATH>_<FILE>_H_
For example, if the file is abc/xyz/foo.h, then the header guard should be
#ifndef ABC_XYZ_FOO_H_
#define ABC_XYZ_FOO_H_
...
#endifvariableNamesin camelCasefunctionNames()in camelCaseCONSTANT_NAMESin CAPITAL_SNAKE_CASEfile_namesin snake_casetype_defsin snake_case with _t suffix- Ex:
typedef struct { int a; int b; } struct_name_t
- Ex:
- 4 spaces per level of indentation
- Use spaces after opening brackets for conditionals and loops (e.g.
if ()andwhile ()), but not for function calls (i.e.my_func()). - Operators:
- No spaces around
*,/,%,! - One space on either side of
=,==,+,-,+=,-=, etc - One space after every comma
my_func(var1, var2, var3)
- No spaces around
- Import statments should be grouped in the following order:
- Local imports (e.g.
#include "cc1120_driver.h) - External library imports (e.g.
#include <semphr.h>) - Standard library imports (e.g.
#include <stdint.h>)
- Local imports (e.g.
- 160 character limit per line (not a hard limit, use common sense)
- Hanging indents should be aligned to delimeter:
myFunction(hasToo,
many, variables)- Avoid complex flow constructs, such as goto and recursion.
- All loops must have fixed bounds. This prevents runaway code.
- Avoid heap memory allocation.
- Use an average of two runtime assertions per function.
- Restrict the scope of data to the smallest possible.
- Check the return value of all non-void functions, or cast to void to indicate the return value is useless.
- Limit pointer use to a single dereference, and do not use function pointers.
- Compile with all possible warnings active; all warnings should then be addressed before release of the software.
This repository was developed by the members of UW Orbital, the University of Waterloo's CubeSat design team.