Updating Component to Mbed OS
Getting Started
This guide is to assist you in the process of updating an existing component library/program on https://os.mbed.com/components/ from older versions of Mbed to Mbed OS.
Pre-requisites
- Mbed platform
- Mbed CLI
Identifying old versions of Mbed
We will use a temperature and humidity sensor as an example - https://os.mbed.com/components/Grove-TempHumi-Sensor/
First, navigate to the Hello World repository for the component.
Next, view the files in the Hello World repository. The presence of mbed.bld
will signify an old version of Mbed.
A component that uses and has been tested with Mbed OS will have an mbed-os.lib
file.
Some repositories may have both mbed.bld
and mbed-rtos.lib
. Mbed-RTOS is the precursor to Mbed OS, which combines the older mbed library with mbed RTOS. So, Mbed OS can replace BOTH mbed.bld
and mbed-rtos.lib
.
Migrating to Mbed OS
There are two possibilities when trying to migrate a component to Mbed OS:
- Replacing the old Mbed library with Mbed OS "just works," as the APIs used in the library have seen no changes. In this instance, you're done.
- Replacing the old Mbed library with Mbed OS produces some compilation errors. For one of two reasons:
- The API calls in the library are out of date, and will need to be migrated to Mbed OS API syntax
- The Hello World application uses target specific code and will need to be migrated to use code for the target we are compiling for
The general outline for updating to Mbed OS is as follows:
mbed import [URL of Hello World]
cd [Project Name]
mbed remove mbed
mbed remove mbed-rtos
mbed add mbed-os
To determine the success of migration run:
mbed compile -m [MCU] -t [toolchain]
Example Component #1 - Just Works
- Component: Grove - Buzzer
- Hello World repo: Seeed_Grove_Buzzer
So, in our command prompt we run:
mbed import https://os.mbed.com/teams/Seeed/code/Seeed_Grove_Buzzer/
cd Seeed_Grove_Buzzer
mbed remove mbed
mbed remove mbed-rtos
mbed add mbed-os
mbed compile -m ublox_evk_odin_w2 -t gcc_arm
We see that it successfully compiles, so there are no changes necessary to the Grove-Buzzer library.
Example Component #2 - Application Fails to Compile
- Component: SRF08-Ultrasonic-Range-Finder
- Hello World repo: SRF08HelloWorld
So, in our command prompt we run:
mbed import https://os.mbed.com/users/melse/code/SRF08HelloWorld/
cd SRF08HelloWorld
mbed remove mbed
mbed remove mbed-rtos
mbed add mbed-os
mbed compile -m k64f -t gcc_arm
Compilation Errors
After we have cloned the repository to our computer and deployed the latest version of Mbed OS, we need to check what compilation errors already exist.
Here is the output produced from mbed compile
:
Building project SRF08HelloWorld (K64F, GCC_ARM) Scan: . Scan: env Scan: mbed Scan: FEATURE_LWIP Scan: FEATURE_STORAGE Compile [ 0.3%]: AnalogIn.cpp Compile [ 0.6%]: BusIn.cpp Compile [ 0.8%]: main.cpp [Error] main.cpp@4,13: 'p9' was not declared in this scope [Error] main.cpp@4,17: 'p10' was not declared in this scope [ERROR] .\main.cpp:4:13: error: 'p9' was not declared in this scope SRF08 srf08(p9, p10, 0xE0); // Define SDA, SCL pin and I2C address ^~ .\main.cpp:4:17: error: 'p10' was not declared in this scope SRF08 srf08(p9, p10, 0xE0); // Define SDA, SCL pin and I2C address ^~~ [mbed] ERROR: "c:\python27\python.exe" returned error code 1. [mbed] ERROR: Command "c:\python27\python.exe -u C:\Repos\SRF08HelloWorld\mbed-os\tools\make.py -t gcc_arm -m k64f --source . --build .\BUILD\k64f\gcc_arm" in "C:\Repos\SRF08HelloWorld"
So, this is a target specific error. The pins used in the Hello World application do not exist on the target we compiled for, K64F. So, let's replace the SDA/SCL pins with something on the K64F. We will use the K64F platform page to find the correct pins. Here, I see that D14/D15 will work. So, main.cpp
now looks like this:
#include "mbed.h" #include "SRF08.h" SRF08 srf08(D14, D15, 0xE0); // Define SDA, SCL pin and I2C address int main() { while (1) { printf("Measured range : %.2f cm\n",srf08.read()); wait(0.1); } }
Now, it successfully compiles.
Example Component #3 - Library Fails to Compile
- Component: CN0357 - Toxic gas measurement
- Hello World repo: CN0357-helloworld
So, in our command prompt we run:
mbed import http://mbed.org/teams/AnalogDevices/code/CN0357-helloworld/
cd CN0357-helloworld
mbed remove mbed
mbed remove mbed-rtos
mbed add mbed-os
mbed compile -m k64f -t gcc_arm
Compilation Errors
After we have cloned the repository to our computer and deployed the latest version of Mbed OS, we need to check what compilation errors already exist.
Here is the output produced from mbed compile
:
Building project CN0357-helloworld (K64F, GCC_ARM) Scan: . Scan: mbed Scan: env Scan: FEATURE_LWIP Scan: FEATURE_STORAGE Compile [ 0.3%]: AD5270.cpp [Error] AD5270.h@91,25: 'SPI_CS' was not declared in this scope [Error] AD5270.h@91,80: 'SPI_MOSI' was not declared in this scope [Error] AD5270.h@91,105: 'SPI_MISO' was not declared in this scope [Error] AD5270.h@91,129: 'SPI_SCK' was not declared in this scope [ERROR] In file included from ./CN0357/AD5270/AD5270.cpp:50:0: ./CN0357/AD5270/AD5270.h:91:25: error: 'SPI_CS' was not declared in this scope AD5270(PinName CS = SPI_CS, float max_resistance = 20000.0, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~ ./CN0357/AD5270/AD5270.h:91:80: error: 'SPI_MOSI' was not declared in this scope AD5270(PinName CS = SPI_CS, float max_resistance = 20000.0, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ ./CN0357/AD5270/AD5270.h:91:105: error: 'SPI_MISO' was not declared in this scope AD5270(PinName CS = SPI_CS, float max_resistance = 20000.0, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ In file included from ./CN0357/AD5270/AD5270.cpp:50:0: ./CN0357/AD5270/AD5270.h:91:129: error: 'SPI_SCK' was not declared in this scope AD5270(PinName CS = SPI_CS, float max_resistance = 20000.0, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~ [mbed] ERROR: "/usr/local/opt/python/bin/python2.7" returned error code 1. [mbed] ERROR: Command "/usr/local/opt/python/bin/python2.7 -u /Users/jenplu01/Repos/CN0357-helloworld/mbed-os/tools/make.py -t gcc_arm -m k64f --source . --build ./BUILD/k64f/gcc_arm" in "/Users/jenplu01/Repos/CN0357-helloworld" ---
The errors relating to "was not declared in this scope" are library specific errors. We need to go into the ./CN0357/AD5270/AD5270.h
header file and remove the constructor's default arguments. Line 91 of the AD5270.h header file should now look like this:
Line 91 of AD5270.h
AD5270(PinName CS, float max_resistance, PinName MOSI, PinName MISO, PinName SCK);
Run mbed compile
again:
Building project CN0357-helloworld (K64F, GCC_ARM) Scan: . Scan: mbed Scan: env Scan: FEATURE_LWIP Scan: FEATURE_STORAGE Compile [ 2.5%]: main.cpp [Error] AD7790.h@114,51: 'SPI_CS' was not declared in this scope [Error] AD7790.h@114,74: 'SPI_MOSI' was not declared in this scope [Error] AD7790.h@114,99: 'SPI_MISO' was not declared in this scope [Error] AD7790.h@114,123: 'SPI_SCK' was not declared in this scope [Error] CN0357.h@77,73: 'SPI_MOSI' was not declared in this scope [Error] CN0357.h@77,98: 'SPI_MISO' was not declared in this scope [Error] CN0357.h@77,122: 'SPI_SCK' was not declared in this scope [Error] main.cpp@111,12: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 3, which is not yet defined [Error] main.cpp@111,0: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 4, which is not yet defined [Error] main.cpp@111,0: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 5, which is not yet defined [ERROR] In file included from ./CN0357/CN0357.h:52:0, from ./main.cpp:48: ./CN0357/AD7790/AD7790.h:114:51: error: 'SPI_CS' was not declared in this scope AD7790( float reference_voltage, PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~ ./CN0357/AD7790/AD7790.h:114:74: error: 'SPI_MOSI' was not declared in this scope AD7790( float reference_voltage, PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ ./CN0357/AD7790/AD7790.h:114:99: error: 'SPI_MISO' was not declared in this scope AD7790( float reference_voltage, PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ ./CN0357/AD7790/AD7790.h:114:123: error: 'SPI_SCK' was not declared in this scope AD7790( float reference_voltage, PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~ In file included from ./main.cpp:48:0: ./CN0357/CN0357.h:77:73: error: 'SPI_MOSI' was not declared in this scope CN0357(PinName CSAD7790 = D8, PinName CSAD5270 = D6, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ ./CN0357/CN0357.h:77:98: error: 'SPI_MISO' was not declared in this scope CN0357(PinName CSAD7790 = D8, PinName CSAD5270 = D6, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~~ ./CN0357/CN0357.h:77:122: error: 'SPI_SCK' was not declared in this scope CN0357(PinName CSAD7790 = D8, PinName CSAD5270 = D6, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK); ^~~~~~~ ./main.cpp: In function 'int main()': ./main.cpp:111:12: error: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 3, which is not yet defined CN0357 cn0357; ^~~~~~ ./main.cpp:111:12: error: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 4, which is not yet defined ./main.cpp:111:12: error: call to 'CN0357::CN0357(PinName, PinName, PinName, PinName, PinName)' uses the default argument for parameter 5, which is not yet defined [mbed] ERROR: "/usr/local/opt/python/bin/python2.7" returned error code 1. [mbed] ERROR: Command "/usr/local/opt/python/bin/python2.7 -u /Users/jenplu01/Repos/temp/CN0357-helloworld/mbed-os/tools/make.py -t gcc_arm -m k64f --source . --build ./BUILD/k64f/gcc_arm" in "/Users/jenplu01/Repos/temp/CN0357-helloworld" ---
Notice that the ./CN0357/AD7790/AD7790.h
and ./CN0357/CN0357.h
header files also have similar "was not declared in this scope" errors. We will need to remove the constructor's default arguments again in both files.
Line 114 of the AD7790.h header file should now look like this:
Line 114 of AD7790.h
AD7790( float reference_voltage, PinName CS, PinName MOSI, PinName MISO, PinName SCK);
Line 77 of the CN0357.h header file should now look like this:
Line 77 of CN0357.h
CN0357(PinName CSAD7790, PinName CSAD5270, PinName MOSI, PinName MISO, PinName SCK);
Run mbed compile
once again and we now have the following errors:
Building project CN0357-helloworld (K64F, GCC_ARM) Scan: . Scan: mbed Scan: env Scan: FEATURE_LWIP Scan: FEATURE_STORAGE Compile [ 5.1%]: Ticker.cpp Compile [ 5.4%]: Timeout.cpp Compile [ 5.6%]: main.cpp [Error] main.cpp@111,12: no matching function for call to 'CN0357::CN0357()' [ERROR] ./main.cpp: In function 'int main()': ./main.cpp:111:12: error: no matching function for call to 'CN0357::CN0357()' CN0357 cn0357; ^~~~~~ In file included from ./main.cpp:48:0: ./CN0357/CN0357.h:77:5: note: candidate: CN0357::CN0357(PinName, PinName, PinName, PinName, PinName) CN0357(PinName CSAD7790, PinName CSAD5270, PinName MOSI, PinName MISO, PinName SCK); ^~~~~~ ./CN0357/CN0357.h:77:5: note: candidate expects 5 arguments, 0 provided ./CN0357/CN0357.h:58:7: note: candidate: CN0357::CN0357(const CN0357&) class CN0357 ^~~~~~ ./CN0357/CN0357.h:58:7: note: candidate expects 1 argument, 0 provided [mbed] ERROR: "/usr/local/opt/python/bin/python2.7" returned error code 1. [mbed] ERROR: Command "/usr/local/opt/python/bin/python2.7 -u /Users/jenplu01/Repos/temp/CN0357-helloworld/mbed-os/tools/make.py -t gcc_arm -m k64f --source . --build ./BUILD/k64f/gcc_arm" in "/Users/jenplu01/Repos/temp/CN0357-helloworld" ---
These errors are now due to the CN0357 variable in main.cpp
no longer having sufficient arguments. Go into main.cpp
and modify the initialization of the CN0357 cn0357;
variable on line 111 to include the K64F's pin names. Line 111 should now look like this:
Line 111 of main.cpp
CN0357 cn0357(D8, D6, D11, D12, D13); // CSAD7790, CSAD5270, MOSI, MISO, SCK
Now, the program successfully compiles.
Please log in to post comments.