1# README Codec2 STM32 Unit Test 2Don Reid 2018/2019 3 4This is the unittest system for the stm32 implementation of 5codec2/FreeDV which runs on Linux systems. It requires a STM32F4xx 6processor development board connected to/having a ST-LINK, e.g. a 7STM32F4 Discovery board. 8 9## Quickstart 10 11Requirements: 12* python3/numpy 13* arm-none-eabi-gdb install and in your path (see codec2/stm32/README.md) 14* STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 (see codec2/stm32/README.md) 15* build openocd from source and have it in your path (see below) 16 17Build codec2 for x86 Linux and run the ctests. This generates several artifacts required for the stm32 tests: 18 19``` 20$ cd ~/codec2 21$ mkdir build_linux && cd build_linux && cmake .. && make && ctest 22``` 23 24Now build for the stm32, and run the stm32 ctests: 25``` 26$ cd ~/codec2/stm32 && mkdir build_stm32 && cd build_stm32 27$ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/STM32_Toolchain.cmake -DPERIPHLIBDIR=~/Downloads/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 .. 28$ make 29$ sudo apt install python3-numpy libncurses5 30$ ctest -V 31``` 32 33You should see tests executing (and passing). They are slow to execute 34(30 to 180 seconds each), due to the speed of the semihosting system. 35 36## If a Test fails 37 38Explore the files in ```codec2/stm32/unittest/test_run/name_of_test``` 39 40When each test runs, a directory is created, and several log files generated. 41 42## Running the stm32 Unit Tests 43 441. Tests can be run using the ctest utility (part of cmake) 45 ``` 46 $ cd ~/codec2/stm32/build_stm32 47 $ ctest 48 ``` 49 You can pass -V to see more output: 50 ``` 51 $ ctest -V 52 ``` 53 You can pass -R <pattern> to run test matching <pattern>. Please note, 54 that some test have dependencies and will have to run other tests before 55 being executed 56 ``` 57 $ ctest -R ofdm 58 ``` 59 To list the available ctests: 60 ``` 61 $ ctest -N 62 ``` 631. To run a single test. This test exercises the entire 700D receive side, 64 and measures CPU load and memory: 65 ``` 66 $ cd ~/codec2/stm32/unittest 67 $ ./scripts/run_stm32_tst tst_ofdm_api_demod 700D_AWGN_codec 68 ``` 69 In general: 70 ``` 71 $ ./scripts/run_stm32_test <name_of_test> <test_option> 72 ``` 73 741. To run a test set (example): 75 ``` 76 $ cd ~/codec2/stm32/unittest 77 $ ./scripts/run_all_ldpc_tests 78 ``` 79 In general: (codec2, ofdm, ldpc): 80 ``` 81 $ ./scripts/run_all_<set_name>_tests 82 ``` 83 84## When tests fail 85 861. If a test fails, explore the files in the ```test_run``` directory for that test. 871. Try building with ALLOC_DEBUG can be helpful with heap issues: 88 ``` 89 $ CFLAGS=-DEBUG_ALLOC cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/STM32_Toolchain.cmake \ 90 -DPERIPHLIBDIR=~/Downloads/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 .. 91 ``` 92 93## Sequence of a Test 94 95Consider the example: 96``` 97build_stm32$ ctest -R tst_ldpc_dec_noise 98``` 99 1001. The test is kicked off based on `src/CMakeLists.txt`, which calls `scipts/run_stm32_tst` 1011. `run_stm32_tst` calls the test setup script, e.g. `tst_ldpc_dec_setup`. Typically, this will run a host version to generate a reference. 1021. `run_stm32_tst` runs the stm32 executable on the Discovery, e.g. `tst_ldpc_dec`, the source is in `src/tst_ldpc_dec.c` 1031. The steup and check scripts can handle many sub cases, e.g. `ideal` and `noise`. 1041. `run_stm32_tst` calls the test check script, e.g. `tst_ldpc_dec_check` which typically compares the host generated reference to the output from the stm32. 1051. As the test runs, various files are generated in `test_run/tst_ldpc_dec_noise` 1061. When debugging it's useful to run the ctest with the verbose option: 107 ``` 108 $ ctest -V -R tst_ldpc_dec_noise 109 ``` 110 Set the `-x` at the top of the scripts to trace execution: 111 ``` 112 #!/bin/bash -x 113 # 114 # tst_ldpc_enc_check 115 116 ``` 117 118## Directory Structure 119 120 | Path | Description | 121 | --- | --- | 122 | `scripts` | Scripts for unittest system 123 | `src` | stm32 C sources 124 | `\src\CMakeLists.txt` | ctests are defined here 125 | `lib/python`| Python library files 126 | `lib/octave`| Octave library files 127 | `test_run` | Files created by each test as it runs 128 129 130## Running the tests remotely 131 132If the stm32 hardware is connected on a different pc with linux, the tests can be run remotely. 133Test will run slower, roughly 3 times. 134 1351. You have to build OpenOCD on the remote machine with the STM32 board. It must be built from 136 (https://github.com/db4ple/openocd.git). 1371. You don't need OpenOCD installed on your build pc. 1381. You have to be able to run ssh with public key authentication using ssh-agent so that 139 you can ssh into the remote machine without entering a password. 1401. You have to call ctest with the proper UT_SSH_PARAMS settings, e.g. 141``` 142UT_SSH_PARAMS="-p 22 -q remoteuser@remotemachine" ctest -V 143``` 144 145## Debug and Semihosting 146 147These tests required a connection from the arm-none-eabi-gdb debugger 148to the stm32 hardware. For this we use a recent version of 149OpenOCD. Running tests with the stm32 hardware connected to a remote 150machine via ssh is possible. This works only with a patched (fixed) 151OpenOCD, see below. 152 153## OpenOCD 154 155We recommend OpenOCD instead of stlink. 156 157Most linux distributions use old packages for openocd, so you should 158build it from the git source. If your test runs fail with error 159messages regarding SYS_FLEN not support (see openocd_stderr.log in the 160test_run directories), your openocd is too old. Make sure to have the 161right openocd first in the PATH if you have multiple openocd 162installed! 163 164It is strongly recommended to build OpenOCD from sources, see below. 165 166## Building OpenOCD 167 168OpenOCD needs to be built from the source. 169 170If you want to use openocd remotely via SSH, you have to use currently the patched 171source from (https://github.com/db4ple/openocd.git) instead of the official repository. 172 1731. 174 The executable is placed in /usr/local/bin ! Make sure to have no 175 other openocd installed (check output of `which openocd` to be 176 /usr/local/bin) 177 178 ```Bash 179 sudo apt install libusb-1.0-0-dev libtool pkg-config autoconf automake texinfo 180 git clone https://git.code.sf.net/p/openocd/code openocd-code 181 cd openocd-code 182 ./bootstrap 183 ./configure 184 sudo make install 185 which openocd 186 187 sudo cp contrib/60-openocd.rules /etc/udev/rules.d/ 188 sudo udevadm control --reload-rules 189 {un plug/plug-in stm32 Discovery} 190 ``` 191 1922. Plug in a stm32 development board and test: 193 194``` 195 $ openocd -f board/stm32f4discovery.cfg 196 197 Open On-Chip Debugger 0.10.0+dev-00796-ga4ac5615 (2019-04-12-21:58) 198 Licensed under GNU GPL v2 199 For bug reports, read 200 http://openocd.org/doc/doxygen/bugs.html 201 Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD 202 adapter speed: 2000 kHz 203 adapter_nsrst_delay: 100 204 none separate 205 srst_only separate srst_nogate srst_open_drain connect_deassert_srst 206 Info : Listening on port 6666 for tcl connections 207 Info : Listening on port 4444 for telnet connections 208 Info : clock speed 2000 kHz 209 Info : STLINK V2J33S0 (API v2) VID:PID 0483:3748 210 Info : Target voltage: 2.871855 211 Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints 212 Info : Listening on port 3333 for gdb connections 213``` 214 215## st-util (deprecated) 216 217Most distributions don't have stutil included. Easiest way is to build it from 218the github sources. 219 220The source can be downloaded from: 221 222 (https://github.com/texane/stlink) 223 224After compiling it can be installed anywhere, as long as it is in the PATH. The program is in 225`build/Release/src/gdbserver/st-util`. 226 227The newlib stdio functions (open, fread, fwrite, flush, fclose, etc.) send 228some requests that this tool does not recognize and those messages will appear 229in the output of st-util. They can be ignored. 230 2311. Build from github 232 233```Bash 234 git clone https://github.com/texane/stlink 235 cd stlink 236 make 237 sudo cp ./etc/udev/rules.d/49-stlinkv2.rules /etc/udev/rules.d/ 238 sudo udevadm control --reload-rules 239``` 2403. Add the st-util util to your $PATH, if not installed in the default location ( /usr/local/bin ) 241 2424. Plug in a stm32 development board and test: 243 244``` 245 $ st-util 246 247 st-util 1.4.0-47-gae717b9 248 2018-12-29T06:52:16 INFO usb.c: -- exit_dfu_mode 249 2018-12-29T06:52:16 INFO common.c: Loading device parameters.... 250 2018-12-29T06:52:16 INFO common.c: Device connected is: F4 device, id 0x10016413 251 2018-12-29T06:52:16 INFO common.c: SRAM size: 0x30000 bytes (192 KiB), Flash: 0x100000 bytes (1024 KiB) in pages of 16384 bytes 252 2018-12-29T06:52:16 INFO gdb-server.c: Chip ID is 00000413, Core ID is 2ba01477.G 253 2018-12-29T06:52:16 INFO gdb-server.c: Listening at *:4242... 254``` 255 256 257 258 259# vi:set ts=3 et sts=3: 260