/ ENV_SETUP.md
ENV_SETUP.md
1 # Bristlemouth Firmware Environment Setup Instructions 2 3 ## Developer Guide (in progress) 4 If you already have your development environment set up, check out the [DEVELOPER.md](DEVELOPER.md) file for some quick start guides, etc... 5 6 If you're developing on the Bristlemouth Development Kit, see the [BMDK_README.md](./src/apps/bm_devkit/BMDK_README.md) 7 8 After you're finished setting everything up for the command line, if you want to build using VS Code, check out 9 [`docs/vscode-setup.md`](docs/vscode-setup.md). 10 11 ## Initial setup 12 ### Install conda 13 14 [Conda](https://docs.conda.io/en/latest/) is used to manage dependencies (compiler, openocd, cmake, python) so that everyone has the same version of all the tools (without affecting the rest of your system). 15 16 (If you're running on a Raspberry Pi with Ubuntu 64-bit, you'll need to use [miniforge](https://github.com/conda-forge/miniforge) instad of miniconda.) 17 18 (If you're on a Mac, you may need to first install the Xcode command-line tools. One way to do this is to run `xcode-select --install` in a Terminal window.) 19 20 If you don't have conda installed, follow these steps by choosing the proper line for your platform: 21 22 ``` 23 $ cd /tmp 24 # Download for Mac (Apple Silicon / M1 / M1 Pro / M2 / etc.): 25 $ curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh 26 # or, download for Mac (Intel): 27 $ curl -O https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh 28 # or, download for Linux: 29 $ wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 30 # install it 31 $ bash Miniconda3-latest-*.sh 32 ``` 33 34 - Scroll through the instructions using your space bar and accept the license terms. 35 - Tell the installer that, yes, you do want to initialize miniconda, by pressing ENTER and then entering `yes` 36 37 **NOTE:** You'll have to relaunch your terminal for conda to start working. 38 39 You'll notice that the new terminal will be inside the conda (base) environment, if you don't want this to happen automatically, just run `conda config --set auto_activation_base false` once and relaunch. 40 41 ### Extra Linux Setup 42 43 For now, we have to use gcc that comes with Linux to build the tests 44 45 `sudo apt install gcc g++` 46 47 If you plan on flashing/debugging with linux, you'll also need the following 48 `sudo apt install libncurses5 libncurses5-dev python2.7 python2.7-dev` 49 50 Don't forget to copy the [udev rules](tools/udev) so the STLink will work! 51 52 ### Set up environment 53 54 This will create a conda environment and download/install all the dependencies. 55 You will have to activate this specific environment whenever you're working inside this repo. 56 57 ``` 58 $ conda create -n bristlemouth 59 $ conda activate bristlemouth 60 $ conda env update -f environment.yml 61 ``` 62 63 Once you're done, you can always deactivate the environment with: 64 ``` 65 $ conda deactivate 66 ``` 67 68 Whenever you pull new project changes (specifically those that update environment.yml), you should run `conda env update -f environment.yml` again. 69 70 ### Set up Pre-commit 71 72 This is an optional step that will install helpful Pre-commit checks to make your code safer and more "beautiful". Make sure to have your conda env updated and active before running this command. 73 74 ``` 75 pre-commit install 76 ``` 77 You can also run the checks whenever you want by running: 78 ``` 79 pre-commit run 80 ``` 81 82 Note that if pre-commit modifies your code, you will need to `git add` the files before you commit them. 83 If you'd like to force a commit through, use the `git commit --no-verify` flag. 84 85 ### Set up environment variables 86 The environment variables needed for the project are listed in `.env.example`. 87 If you want to make use of [Memfault](#memfault) analysis you'll need to gather your credentials and put them in a `.env` file 88 that is copied from the `.env.example`. 89 90 ### Pull submodules 91 Bristlemouth uses several submodules to include third party libraries, etc. 92 These files might not have been downloaded when cloning/pulling. If that's the case, run `git submodule update --init` to download them. 93 94 A couple things to note about submodules: 95 - The submodule folders do not update SHAs automatically. If we need updated scripts, run `git submodule update --remote path/to/submodule` 96 97 98 ## Building/Flashing - Command-line 99 100 **🛑 NOTE:** If you came here from the *Bristlemouth Dev Kit Guide*, you do not need to complete the following sections. You can now return to the document that brought you here. 101 102 ### Configure CMake 103 104 This follows a pretty standard cmake process. First you create a directory for this particular build/configuration. You can either create a top level directory for each build (/cmake-build-debug, /cmake-build-bridge) or one top level directory with individual build subdirectories (/cmake-build/bristlemouth, /cmake-build/bridge). The `cmake-build` prefix is in the .gitignore, so however you structure the different folders they should still begin with that. 105 106 ``` 107 # Sub-directory example 108 $ mkdir -p cmake-build/bridge 109 $ cd cmake-build/bridge 110 ``` 111 112 Then you run cmake and tell it where the toolchain file is located, which BSP(board support package) to use, as well as which application. Pay attention to the `../` relative paths in the args - depending on how your cmake build directories are set up, you might have to replace them with `../..`. 113 114 115 ``` 116 # If you have individual top-level build directores for each app 117 $ cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-none-eabi-gcc.cmake -DBSP=bridge_v1_0 -DAPP=bridge -DCMAKE_BUILD_TYPE=Debug 118 119 # If you have one top-level build dir with different sub-dirs for each app 120 $ cmake ../.. -DCMAKE_TOOLCHAIN_FILE=../../cmake/arm-none-eabi-gcc.cmake -DBSP=bridge_v1_0 -DAPP=bridge -DCMAKE_BUILD_TYPE=Debug 121 ``` 122 123 You can optionally set the build type to release (it defaults to Debug) by appending `-DCMAKE_BUILD_TYPE=Release` to the command. 124 125 ### Building the Project 126 127 Once inside the build directory you can just run: 128 129 ``` 130 make 131 ``` 132 133 or 134 135 ``` 136 $ cmake --build . 137 ``` 138 139 If you want to enable parallel builds, add `-j` to either of those commands. 140 141 ### Bootloader 142 Before flashing your application, you **MUST** first build/flash the bootloader. This only needs to happen once per device. 143 144 To configure: 145 146 ``` 147 $ mkdir -p cmake-build/bootloader 148 $ cd cmake-build/bootloader 149 $ cmake ../.. -DCMAKE_TOOLCHAIN_FILE=../../cmake/arm-none-eabi-gcc.cmake -DBSP=bootloader -DAPP=bootloader -DCMAKE_BUILD_TYPE=Release 150 ``` 151 152 To build and flash the bootloader: 153 154 If you have an STLink SWD or SWD over USB-C debugger (flashing the bootloader on the first Flash over DFU USB not currently supported): 155 ``` 156 make -j flash 157 ``` 158 159 ### Flashing/Debugging 160 To flash using openOCD/STLink (more debugger support to be added later), you can just run: 161 162 **NOTE: You will need to flash the bootloader before you can use any application. This only has to be done once** 163 164 ``` 165 $ make flash 166 ``` 167 168 To run the GDB debugger, you can use: 169 170 ``` 171 $ make debug 172 ``` 173 174 #### USB dfu-util 175 176 You can also take advantage of the built-in usb bootloader in the STM32U575 to flash the device. You'll need to have [dfu-util](http://dfu-util.sourceforge.net/) installed. On MacOS just `brew install dfu-util`, on Ubuntu just `apt-get install dfu-util` (I do hope to add it to the conda environment, but it's not a high priority right now.) 177 178 If over USB (Note - this is currently broken on DevMote + Bristlefin cc @Victor): 179 First need to put system into bootloader mode, by sending the bootloader command over serial. 180 - connect to the serial device ending in `1`, not `3`: 181  182 - send `bootloader` command, and you'll get booted out. 183 - Then can DFU flash from build dir with: 184 ``` 185 make -j dfu_flash 186 ``` 187 - Note: this is what a fail looks like: 188  189 - This is what success looks like: 190  191 192 Once the device is in DFU mode, you can run `dfu-util -l` to see if the device is detected. To flash it with the latest firmware, just run `make dfu_flash`! 193 194 `make dfu_flash` can be used with both the bootloader and main applications. 195 196 197 #### Flashing with a specific STLink device 198 If you have more than one STLink debugger connected to your computer, you must tell the flashing script which one to use. The way to do this is as follows: 199 200 ```STLINK_SERIAL=004D00423438510B34313939 make flash``` 201 202 To get the serial number on MacOS, you'll have to go to system information and look in the USB device tree for the STLink device. There should be a Serial Number field for each one. 203 204 In Linux, use `udevadm info /dev/ttyACM2 | grep ID_SERIAL_SHORT` or `lsusb -v -d 0483:374b | grep iSerial` (on the appropriate device) 205 206 ## Unit Tests 207 208 We're using [GoogleTest](https://github.com/google/googletest) to run the unit tests. At the moment, the tests are compiled and run natively on the host machine. The goal, eventually, is to compile them with the ARM compiler and run them on an emulator such as [Renode](https://renode.io/). 209 210 **Note:** Linux and MacOS aren't using the exact same compiler to run the tests. They're both clang, but MacOS uses the builtin one and Linux the one from the Conda envrionment. It's not a huge issue so I'm not going to spend the time to debug that right now. 211 212 ### Configure CMake 213 214 This follows a pretty standard cmake process. First you create a directory for this particular build/configuration. 215 216 ``` 217 $ mkdir test-build 218 $ cd test-build 219 ``` 220 221 Then you run cmake 222 223 ``` 224 $ cmake -DCMAKE_BUILD_TYPE=Test ../ 225 ``` 226 227 ### Building the tests 228 229 Once inside the build directory you can just run: 230 231 ``` 232 $ cmake --build . 233 ``` 234 235 236 ### Running the tests 237 To run the tests, use the command (make sure you already built the tests before running!): 238 239 ``` 240 $ ctest 241 ``` 242 243 To see fancy colored output with test details, run: 244 ``` 245 $ export GTEST_COLOR=1; ctest -V 246 ``` 247 248 ## micropython 249 250 In order to build with micropython support, you must pass the `-DUSE_MICROPYTHON=1` cmake flag. 251 252 ### Building mpy-cross on macOS arm64 253 There's currently a bug with building the micropython cross-compiler `mpy-cross` on arm64 MacOS (it works fine while using Rosetta). There are missing include files while trying to build `mpy-cross`. Thankfully, there's a workaround. 254 255 We can compile mpy-cross separately by providing the correct CPATH for the c/c++ include libraries. (We can't do this for the entire project, since it will break the microcontroller firmware cross-compilation) 256 ``` 257 cd src/third_party/micropython/mpy-cross 258 export CPATH="`xcrun --show-sdk-path`/usr/include" 259 make 260 mkdir -p `git rev-parse --show-toplevel`/tools/bin 261 cp build/mpy-cross `git rev-parse --show-toplevel`/tools/bin 262 ``` 263 264 Once mpy-cross is compiled and saved in tools/bin, we can point the build process to it so it doesn't try to re-build it. 265 ``` 266 export MICROPY_MPYCROSS=`git rev-parse --show-toplevel`//tools/bin/mpy-cross 267 make -j 268 ``` 269 270 271 ## Memfault 272 If you're using [Memfault](https://memfault.com/) for crash analysis, this section covers some useful workflows. 273 274 ### Uploading .elf to Memfault 275 276 After building the project, run `make memfault_upload`. Make sure your .env file is set up ahead of time! 277 278 ### Uploading memfault coredump over GDB 279 If you're in GDB and a crash occurs, this is how you capture a coredump to upload to memfault (make sure you already ran `make memfault_upload`!) : 280 281 In GDB: 282 `source ../../../src/third_party/memfault-firmware-sdk/scripts/memfault_gdb.py` 283 284 then 285 286 `memfault login your@email <your memfault API key goes here> -o <your organization> -p <your project>` 287 288 if you're developing in the Sofar organization: 289 `memfault login your@email <your memfault API key goes here> -o sofar-ocean -p bristlemouth` 290 291 finally 292 293 `memfault coredump`