Setting up Firmware Development Software - df8oe/UHSDR GitHub Wiki
Building and installing the firmware is quite easy. However, please read and follow the instructions outlined below before asking. If you feel that the instructions can be improved, extended, shortened: Feel free to do so and share your knowledge with all of us. Log into your GitHub account and start improving this document. Thank you!
If you want to contribute your improvements, read the guidelines for contributing to learn how to do this.
If you want to be seriously involved in firmware development, the use of a cheap real-time debugger such as the ST-Link is a real time-saver. Unfortunately, Rev 0.5 of the UI Board removes the previously available connections from the P8 header to the Debug interface and repurpose the pins. For that reason it is going to be very difficult to connect the debugger to the CPU. While it is not impossible to wire it up, TRY TO AVOID UI Board Rev. 0.5 if you plan to use the debugging capabilities at any later time. MCHF Rev 0.6 readds the headers AND adds the GND pin. Nice!
Normal use of the mcHF Rev 0.5 will not suffer from the missing Debug interface.
As this UHSDR firmware now supports 3 different processor types (STM32F4, STM32F7 and STM32H7) running on different hardware configurations (OVI40 UI board, MCHF UI board) with potentially different RF hardware, and can build both a bootloader and the firmware from the source, you will have to follow certain instructions to get the right build done.
See instructions in the Running a Build section below.
The project uses gcc for compilation. Other compilers have not been tested and are not supported by the build environment. Feel free to add support for other compilers.
We do not recommend to use compilers older than 8.1 because this is the one we are using right now for official builds so builds may fail with older compilers. To our knowledge, currently gcc versions 4.9 to 8.1 are being used with success. Older gcc releases had issues during linking, suse of older releases is not and will not be supported.
Minimum version for tools (applies to all operating systems):
Tool | Minium Version Required | Comment |
---|---|---|
GNU make | GNU Make 4.0 | we use function file, available with 4.0 or newer |
GCC | 4.9 | We recommend to use newest stable GCC |
On many newer distributions you can use the compiler environment provided as packages with the distribution. If it is a gcc 4.9 or newer, you should be fine. To get the newest compiler, you can look at the GNU Arm Embedded Toolchain. However, for now we recommend to stick with the recommended configurations first. Feel free to add more instructions to this wiki.
If you happen to run a Raspberry Pi or similar ARM based linux machines, you could use the provided compiler, but this is not tested.
Use apt install gcc-arm-linux-gnueabihf
to get the newest available compiler release including all tools required to build the firmware.
Use of standard compiler and tools packages included works for Ubuntu 15.04 and newer. Use apt-get install gcc-arm-linux-gnueabihf
to get the newest available compiler release including all tools required to build the firmware.
Install openocd
if you plan to run hardware assisted debugging.
Use the instructions given below for Debian Jessie, installing the backport works perfectly to get gcc 4.9.
sudo add-apt-repository "deb http://ftp.debian.org/debian jessie-backports main"
sudo apt-get update
sudo apt-get install -t jessie-backports -y --force-yes gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib openocd
On Windows you can follow two approaches. You may go for a IDE based environment or use a command line build approach. For command line builds, you will have to use a Unix emulation (MinGW) or Bash on Ubuntu on Windows (WSL available on Windows 10). For IDE builds you will have to use the GCC Compiler for ARM.
See here for a strictly Windows 7/8/10 x64 build environment.
The GNU Arm Embedded Toolchain provides installers for Windows and more. Ubuntu users can still use the "old" GCC ARM Embedded Project PPA to get GCC packages.
Important Information: Do not use the 2018 Q4 GCC on Windows. It has an issue when linking. Remain on 2018 Q2 until a newer release is available or this information is removed. Linux and MacOS are not affected and can use the newest compiler.
Download the most recent installer and run it, leaving all settings to the defaults.
MinGW provides a Unix emulation, we simply install all the nice Unix tools and can run a Makefile build.
- Install MinGW
- Install gcc-arm (but preferrably you should use the Windows GCC downloaded from the website above)
- Install git
- Optional but recommended: git-shell etc.
After that it performs the same way as on Linux.
Since Windows 10 "Anniversary Update", Bash on Ubuntu on Windows provides developers with a familiar Bash shell and Linux environment in which you can run most Linux command-line tools, directly on Windows, UNMODIFIED, without needing an entire Linux virtual machine. This is very similar to MinGW with the advantage of a full access to the Ubuntu and Debian software library.
First, install Bash on Ubuntu on Windows with the help of the Installation Guide. You will get Ubuntu 14.04 (trusty) on Windows 10 Anniversary Update (version 1607) or Ubuntu 16.04 (xenial) on Windows 10 Creator Update(version 1703).
Next, install the development tools:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential
sudo apt-get install python-minimal
On Creator Update, install the cross compiler:
sudo apt-get install gcc-arm-none-eabi
On Anniversary Update, install the cross compiler as on Debian Jessie above.
Finally, get the source files and compile:
cd
git clone https://github.com/df8oe/UHSDR.git
cd UHSDR/mchf-eclipse
make all
In order to install a build environment on Mac OS, you should first install Homebrew:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Afterwards, you can install the cross compiler and GNU sed:
brew cask install gcc-arm-embedded
brew install gnu-sed
Following the complete instructions on the GNU MCU Eclipse pages for installing will give you a nice working setup including nice debugging capabilities. It might seem like a lot of instructions and you have to jump between pages, but this is well-spent effort, especially on Windows.
Do not forget to install the packs for the STM32F4 processor (or STM32F7 if you are using F7 based hardware). Detailed instructions for this step may appear here in future.
Important Hint for Eclipse Upgrades
If you upgrade your Eclipse installation during upgrade you will get a box which points to a new/different workspace folder. It is mandatory to choose a new workspace like it is proposed! Later you have to import UHSDR project again and all will work fine. If you use workspace which was created by a former Eclipse version you will run into trouble.
See the instructions in the mchf-embitz project folder of the repository
CoIDE is a all-in-one IDE for ARM processors on Windows. It is simpler to use than Eclipse but also less extensible.
The GitHub project contains a working CoIDE 1.7.x project. Download CoIDE 1.7.8. In addition you will need only a GCC ARM Tool Chain. Follow the instructions given above to install one.
DO NOT USE CoIDE 2.0 or newer. Build fails on these. There are no plans to migrate the CoIDE project to 2.0, however, if you made a successful migration, let us know and we may be able to integrate that. Otherwise, stick to CoIDE 1.7.8.
Please note: mcHF UI Board 0.5 does not provide the debug port on its P8 connector (although it has P8, it is bascially useless, check the schematic). mcHF UI Board 0.4 and 0.6 provide the signals on P8.
- Get yourself a ST-LINK V2 compatible USB stick. These sell for 8-15USD/EUR/GBP on Amazon
- Update to newest stick to newest ST LINK V2 firmware. This solves some issues.
- Solder a 4 or 5 pin strip 90 degrees to connector P8 (Rev 0.4: 4 Pin, Rev. 0.6 5 Pin)
- Rev 0.4 only: Solder another pin from a pin strip to a place where you can get a ground connection (or clip a wire to the casing of one of the USB sockets)
- Connect SWDIO and SWDCLK to the respective pins on P8: Rev 0.4: Pin 4 -> SWDCLK, Pin 3 -> SWDIO, Rev 0.6: Pin 5 SWDCLK, Pin 4: SWDIO, Pin 1 GND. Rev. 0.4 only: Connect ground pin from stick to mcHF.
- To connect the original ST-LINK/V2 you have to connect pin 1 from 20 pin header from ST-LINK to UI_3V_MCU on UI board. E.g. you can use one of P6 pins. If you use a "clone" ST-LINK/V2 stick, you do not have to connect 3.3V
- One of the verified configurations in ST-LINK Utility - Mode: Hot Plug, Reset Mode: Hardware Reset, Frequency: 1,8MHz
- Use a SHORT cable to connect ST-LINK and mcHF. Less than 10cm is recommended. All sort of sporadic errors happen with longer cables. You have been warned.
There are many other hardware interfaces on the market for debugging ARM processors. If you buy one of these and get to work, just document it here. In other words: Not yet supported.
No, not for compiling and debugging. But for contributing, getting up-to-date source code easily, collaborating, .... That's way we recommend strongly to have both.
Depending on what you are intending to do, there are three different approachs how to get the software and stay in sync with development progress. See the subsections below. Then, depending on your build environment see instructions in next section, which will tell you how to "install" the sources for a build.
- Download the zipped source code from the active-devel branch ins this repository: (https://github.com/df8oe/UHSDR/archive/active-devel.zip)
- Unzipp
- Go the next section telling you what to do to prepare the source for use with your build environment.
- Install your favorite git environment, being it the simple command line client or the most sophisticated Git environment.
- The Git Repository URL is (https://github.com/df8oe/UHSDR.git). If you use the git command line client:
git clone https://github.com/df8oe/UHSDR.git
puts the repository on your disk and links it with the main repository.
- Later, if you want to get the newest state, run
git pull
. This will even keep handle changes you did. But be aware, sometimes the automatic merge of your changes with the newest state from Github will fail, and git will ask for your support. - Go the next section telling you what to do to prepare the source for use with your build environment.
In a nutshell, you will need your own GitHub account and a fork of this repository in your own GitHub account area.
Please follow the instructions given in the guidelines for contributing in order to setup the git connections to GitHub correctly and understand the way of working we use in this project.
Although not strictly technically necessary, please follow the naming conventions for the remote GitHub repositories! It makes discussion about git/github so much easier, if we all use same names for the remotes!
Nothing to do, just go into the directory "mchf-eclipse" with your command line and run the build according to instructions.
You need to make the UHSDR project configuration known to Eclipse. This action is called "Import an Existing Project". Please, do not import the source code into an existing Eclipse project (there is an option for that, but this is the wrong way). Here we go:
- Start Eclipse
- "File"->"Import"->"General"->"Existing project"
- "Archived"
- Navigate to the ZIP and select it
- mchf-eclipse Project should be listed and selected in the previously empty list box
- "Finish"
- Project will appear in Eclipse workspace view.
For advanced users/use cases: There are other ways to get the project into the Eclipse workspace but for sake of simplicity we don't document or support them here to keep instructions complexity low.
See the instructions in the mchf-embitz project folder of the repository
From the same source we can build the firmware or the bootloader. With C compiler defines we control what hardware and software features are supported in a build. There are also C compiler defines to configure the processor. In addition to that some paths have to set according to the processor and firmware vs. bootloader build type.
The Makefile and/or the IDE configurations hide most of this from you.
Your main choices are (used in all build systems):
What | Makefile Variable/Define | Valid choices | Default | Comment |
---|---|---|---|---|
Processor Type | BUILDFOR |
'F4' | 'F4', 'F7', 'H7', 'F4-512KB' | 'F4-512KB' for building for F4 with 512kB flash with reduced functionality |
UI Board + RF_BOARD | CONFIGFLAGS |
"-DUI_BRD_MCHF" or "-DUI_BRD_OVI40" plus "-DRF_BRD_MCHF" and/or "-DRF_BRD_OVI40" | "-DUI_BRD_MCHF -DUI_BRD_OVI40" | ui boards are mutually exclusive, rf boards any combination possible |
TRX Display Name | TRX_NAME |
"MCHF", "OVI40', "OVI40H7" | "MCHF" | any string if not too long works |
TRX ID | TRX_ID |
"mchf", "i40h7', "ovi40" | "mchf" | string with at most 5 characters, used for naming the binaries fw-... / bl-... |
To put this together, an example for a make call to build a OVI40 UI firmware using the H7 processor with support for the MCHF RF board:
make BUILDFOR="H7" TRX_ID="i40h7" TRX_NAME="OVI40H7" CONFIGFLAGS="-DUI_BRD_OVI40 -DRF_BRD_MCHF -DRF_BRD_OVI40" all
In the IDEs such as Eclipse the different build configuration set these values for you. See below for details. Not all the settings are done in the IDE case in the same way as in the Makefile technically, so you will not find for instance the BUILDFOR variable being used in Eclipse. Nevertheless the table above gives you the general idea of what is possible (and is exactly what we use in Makefiles).
In addiion to the settings above, the make process uses a few more settings specific to the Makefile build process and have no direct counterpart in the IDE cases:
What | Makefile Variable/Target | Valid choices | Default | Comment |
---|---|---|---|---|
Build Target | make all |
'all', 'firmware' or 'bootloader' | none | mutually exlusive, 'all' builds firmware and also the documentation |
Separate Build | ROOTLOC |
path to the mchf-eclipse directory | "." (current dir) | this can be used to build in a different directory located outside the original source tree |
Compiler location | OPT_GCC_ARM |
path to top level directory of package | none | must point to top level directory of arm gcc compiler package, not the /bin directory! |
To put this together, an example for a make call to build a OVI40 UI firmware using the H7 processor with support for the MCHF RF board assuming the sourc located in /opt/src/UHSDR/mchf-eclipse
and the build in /opt/build/ovi40_h7_build
, the compiler is in /opt/gcc
:
make -f "/opt/src/UHSDR/mchf-eclipse/Makefile" ROOTLOC="/opt/src/UHSDR/mchf-eclipse" OPT_GCC_ARM="/opt/gcc" BUILDFOR="H7" TRX_ID="i40h7" TRX_NAME="OVI40H7" CONFIGFLAGS="-DUI_BRD_OVI40 -DRF_BRD_MCHF -DRF_BRD_OVI40" all
cd mchf-eclipse
make all
will produce, if successful, the file firmware mchf.bin
in this directory. make clean
will remove all generated files.
cd mchf-eclipse
make bootloader
will compile the bootloader code.
If it fails, make sure that all the required tools are in the execution path.
First see MinGW install information above. Then run it just like on Linux.
make clean
make all
The build process on Mac OS is similar to Linux or Windows, you just need to set the correct prefix:
export OPT_GCC_ARM=/usr/local
make clean
make all
- Import project first, see instructions above.
- Make sure to be in the "C/C++" perspective. This is visible in the window title bar (you will see "C/C++" as part of the window title. If not, "Window"->"Perspective"->"Open Perspective"->"C/C++" oder ... "Other"->"C/C++" will get you there.
- Select "DebugLibMCHF" build configuration using "Project"->"Build Configurations"->"Set Active"->"DebugLibMCHF"
- Run "Project->Build". Build uses make just like a command line build.
- Select "DebugMCHF" build configuration using "Project"->"Build Configurations"->"Set Active"->"DebugLibMCHF"
- Run "Project->Build". Build uses make just like a command line build.
- Resulting firmware file (mchf-eclipse.bin) is in directory "DebugMCHF".
Now you can change the code and run "Project->Build".
The bootloader can be build by selecting "DebugBoootloaderMCHF" and can be found in "DebugBootloaderMCHF".
See the instructions in the mchf-embitz project folder of the repository
- Start IDE, open project using file
firmware.coproj
. - Run "Project->Build Project".
- Resulting firmware file is placed by default in firmware_target/Debug
There are different ways how to get the newly built binary on the mcHF. While the first two alternatives work, the third choice which uses a USB dongle, is the quickest way to do it and the only one which gives you also full debugging support in real-time.
See wiki page for firmware updates
See wiki page for firmware updates
-
Connect stick to PC, use either direct connection or good cables/hubs. Bad USB extension cables caused problems during flashing.
-
Now put your finger on the Power button and do not release it. Flashing will stop the internal "power hold" mechanism and switch off the TRX before the new firmware has been loaded. If this happens, your UHSDR TRX may be temporarily "bricked". To fix this you may need to either restart the flashing process (this time with power button hold all the time). Or if this doesn't work, you may have to reflash the bootloader using the Jumper P6 method described elsewhere in this wiki. You have been warned!
-
CoIDE:
- Just press the "Flash" button. This will start first the flashing and then start the mcHF.
-
Eclipse:
- Make sure you have the right run configuration selected.
- Just press the "Run" button. This will start first the flashing then start the mcHF.
-
Command Line:
- Start openocd with
openocd -f support/MCHF.cfg -c "init" -c "reset halt"
. Depending on the UHSDR TRX you may have to usesupport/ovi40.cfg
etc. This should produce some output and mention the successful connection to the target MCU. Attention: You need to keep the Power button pressed, otherwise the TRX will switch off. - Change in the directory where your UHSDR fimrware .elf is located (e.g. fw-mchf.elf).
- Start gdb with
arm-none-eabi-gdb
in a separate terminal window. Once the gdb session starts, entertarget remote localhost:3333 file fw-mchf.elf load monitor reset halt cont
- This flashes the binary and starts it. BTW: Hitting CTRL-C will stop the firmware and gdb tells you where it was.
- Start openocd with
The easiest way to debug the UHSDR Software is to run the transceiver connected to a PC via ST LINK V2 USB Adapter and Eclipse installed as described before. This offers starting and stopping the processor, reading the memory, variables, setting breakpoints easily in the code editor and so on. You can even use special calls (trace_printf/trace_write) which will insert debug output in the code. The output is shown on the PC (data is sent via the debug interface, no extra connection required).
Similar functionality is available on the command line, with gdb and openocd.
In a nutshell, if you can flash the firmware using Eclipse or gdb/openocd, you can also run debug using the same interface.
By default the debug output via semihosting is disabled. Two reasons for that: It takes resources and even more importantly, if enabled, it produces binaries which do not work without the ST LINK debugger active! Only activate this in your local builds.
In order to have semihosting working, you need to add two defines to your build system:
- OS_USE_TRACE_SEMIHOSTING_STDOUT
- TRACE
In Eclipse, you can select the Build Configuration "DebugSemihosting", which has these defines set.
We added support for profiling the UHSDR software (sort of). It helps you to count how often something happens and/or how long something takes at the granularity of single CPU clock cycle, which is 5,9nS (yes, nanoseconds).
You have to include "profiling.h" in the source file of interest, define a new profiling event in ProfiledEventNames (or reuse an existing one, if it is not in use, check carefully).
Profiling will be disabled by default. If "PROFILE_EVENTS" is defined, it is active.
Call profileEvent(EventName). This will increment the counter of the event in the eventProfile datastructure. Access the data there via "eventProfile[EventName].count". You may use the trace print functionality to print out the counter or you simply use the debugger to inspect the value in memory.
This is a little more complex.
- First start the cycle timer with "profileTimeEventInit()" .This resets the timer and makes it run.
- At any time call profileTimedEventStart(EventName) to have the start being recorded. At the end of the event call profileTimedEventStop(EventName)
The duration of a single event should not be longer then 2^32 / clock frequency, i.e. ~25s @168 Mhz for a single event. Total duration recorded should not be more than 2^64 cycles which is quite a lot, i.e. there is no limit on that for the average person in this universe.
Due to the approach multiple events can be recorded simultaneously correctly but outer events include the overhead of the calculation of the duration of the inner ones. Only the innermost events are more or less accurate. In many cases this deficit is neglectable since the measurement has very low overhead.
The recorded data is the time in cycles of the all active periods of that event. There is also a counter, so that it is possible to calculate the average event duration: "eventProfile[].duration/eventProfile[EventName].count"
If you were able to flash the firmware using the commandline (see above) you can simply debug using any generic gdb tutorial (set breakpoints, step over instructions, etc.).
You don't need to restart gdb if you recompiled your binary, just start with the instructions for flash at file <path_to_firmware_elf_file>
and all following commands given above. Breakpoints remain set in this case.
It is recommended to set a break to at the main function. (break main
). This will stop after cont
at main. At this point you can stop pressing your finger on the Power button. Now continue with another cont
.
Hit the "Debug" toolbar button (look like a bug) and Eclipse will switch to debug mode, compile, flash, and start the firmware and then stop at the first instruction in the main() function. At this point you can stop pressing your finger on the Power button. You have to press "Play/Continue" toolbar button in order to run the firmware. Press "Pause" at any time to pause the firmware execution.