Arm Mbed OS is a popular open source project that accelerates the development of devices for the Internet of Things (IoT). If you have created your unique processor device, then the first task will be to port some operating system (OS) to it.
Here is a step-by-step instruction on how to launch
Arm Mbed OS on a motherboard with a
NXP Kinetis microcontroller family.
Arm Mbed OS project
is owned by ARM and is intended only for the ARM architecture. Contrary to popular belief,
Mbed is not written entirely in C ++, is not sharpened exclusively for
Cortex-M and is not that new. Its origins lie in the distant 90s when
Keil created
RTX , the real-time operating system (RTOS) for I8051. Subsequently, the
RTX was Keil transferred to ARM7 and ARM9, and then Cortex appeared.
')
ARM acquired
Keil and RTOS was named
CMSIS-RTOS . It was still entirely written in
C. Finally, with the arrival of the
IoT and Arduino boom,
Mbed appeared.
Arduino's changes caused a
C ++ shell and a simplified API with a familiar set of dozens of pins, a UART and a LED, and IoT filled the project with
TCP / IP, Bluetooth Low Energy, 6LoWPAN, Thread stacks ... But
RTX5 still sits in the depth of the source code
Mbed OS .
The
Keil brand continues to exist and in the Keil development tools distribution kit, you can find CMSIS-RTOS with a large selection of middleware and porting examples for a larger range of microcontroller families than
Mbed offers. However, it is a closed commercial project.
Specialized fee
for which the porting is made here for an example and its scheme does not matter much. More importantly the microcontroller that is installed on it. This is the
MKE18F512VLL16 of the Kinetis family from NXP. Its main parameters are:
Kernel - ARM Cortex-M4F 32-Bit
Maximum core frequency - 168MHz
Flash 512KB (512K x 8)
RAM 64 KB
100-LQFP (14x14)
Microcontroller content

This microcontroller is not in the list of supported ARM Mbed OS. It can be explained by the fact that it is
relatively new .
The microcontroller is interesting with a good set of peripherals at a fairly
modest price and high core frequency. The
FlexIO module allows you to create
non-standard interfaces that are not available on conventional microcontrollers.

Step 1. Downloading NXP Tools
- We configure our version of MCUXpresso Software Development Kit (SDK) for the MKE18F512xxx16 family online at www.nxp.com
- When you need to specify the Toolchain / IDE, select the IAR IDE . Further work will be considered in IAR IDE .
- Select all available Software Components .
- Download the resulting MCUXpresso Config Tools, Windows 64bit package from the site.
This will be a 30 megabyte archive MKE18F512xxx16.zip with the following contents:

- - Download also MCUXpresso Config Tools v4.1 for Windows . With it, we configure the microcontroller clocking subsystem.
Step 2. Getting the application project without RTOS
- Launch MCUXpresso Config Tools v4.1 for Windows

- As a template, choose one of the simplest demo examples - led_blinky.

- We configure the clocking scheme and give the command to generate the clocking initialization sources. Initialization sources are updated directly in the project directories.

- We copy the received project with source codes under IDE IAR in the directory. In the project, select the J-Link debugger, the debug channel through the SWD interface. We modify the write commands to the LED port, compile and upload to the board.
Step 3. Configuring and converting the Mbed project
- We go to the site of the project Mbed in the platform section - os.mbed.com/platforms .
There we are looking for a board with a microcontroller as close as possible to the one we have chosen. - Choose a board FRDM-K66F - os.mbed.com/platforms/FRDM-K66F . The choice is not random, with a similar microcontroller have experience .
- On the page with the board presentation we decide to choose a demo - mbed-os-example-blinky - os.mbed.com/teams/mbed-os-examples/code/mbed-os-example-blinky/?platform=FRDM-K66F
This is the simplest example and will be the easiest to adapt for another board. - Register and go to the on-line section of the compiler - os.mbed.com/compiler
- First we select the platform - FRDM-K66F , and then we import the demo we have chosen - mbed-os-example-blinky . In the Programs panel, this demo will be named mbed_blinky .

- We compile this example for verification, and then export it.
We export in a format intended for
IDE IAR 


Now we have the source for the
Mbed working project for
IAR . However, the resulting project is inconvenient to work.
All files in the project were collected in one group and mixed. It is impossible to search and identify which file belongs to which function package. The project involved the
sources of almost all the middleware project
Mbed , although most of them we do not need now.

Step 4. Convert the IAR project to normal form
- With the help of specially written utilities in Python, we perform several conversion operations.
First, we delete from the directories of the demonstration project all sources that are not included in the project. The list of sources is obtained from the file
mbed-os-example-blinky.ewp . The utility is called
Clear_from_unused_files_and_dirs.py . It also removes the empty directories formed after deleting files.
Secondly, using the
Convert_ewp_file.py utility
, we reconfigure the project file
mbed-os-example-blinky.ewp so that the groups in it correspond to the project directories. We get the project with a more understandable structure, where you can remove or add packages. Here we can rename the project. To do this, edit the tag
<configuration> <name>mbed-os-example-blinky</name>
in the file
mbed-os-example-blinky.ewp . Change the name of the file
mbed-os-example-blinky.ewp (in this case,
Test_proj.ewp ), fix the tag
<path>$WS_DIR$/mbed-os-example-blinky.ewp</path>
in the
mbed-os-example-blinky.eww file (in this case on
Test_proj.ewp ) and change the name of the
mbed-os-example-blinky.eww file to the one we chose (in this case,
Test_proj.eww )

As a result, has a project structure


- We study the source code to determine those of them that depend on the characteristics of the microcontroller. For this, it is more convenient to use more specialized editors, such as SlickEdit or
Eclipse . The editor should also report macros declared in the
IDE settings. To do this, create an additional header file
Extra_options.h and copy the contents of the
Extra Options from
IDE IAR there .

Step 5. Editing the Mbed project
We are ready to edit the project. Let's start by analyzing the macros in the
Extra_options.h file. This is done in the editor with the appropriate capabilities, you can do in the IAR environment.
- Remove unused macros so that they do not distract attention with further analysis. We sort the rest. About half of the macros were unused.
- In
Extra Options, enter the new macro -
TARGET_MKE18F . It defines the starting address of the stack in the
mbed_rtx.h file. The stack grows in the direction of decreasing addresses. In
Mbed, it is customary to start the stack from the top of the available RAM. For MKE18F we set this limit to
0x20008000UL- Find the directory
TARGET_K66F . There are stored files depending on the type of microcontroller. There are quite a lot of them - 136 files. Create next to the directory
TARGET_K66F your own name
TARGET_MKE18F .
- From the directory of the demonstration project
SDK led_blinky \ CMSIS, copy to the directory
Mbed -
os \ targets \ TARGET_Freescale \ TARGET_MCUXpresso_MCUS \ TARGET_MKE18F \ device files:
• fsl_device_registers.h. (Macro CPU_MK66FN2M0VMD18 in Extra Options is replaced by CPU_MKE18F512VLL16)
• MKE18F16.h
• MKE18F16_features.h
• system_MKE18F16.h
• system_MKE18F16.c
- Delete files
• MK66F18.h
• MK66F18_features.h
• system_MK66F18.c
• system_MK66F18.h
- In the
TOOLCHAIN_IAR directory,
we replace the contents with the
startup_MKE18F16.s and
MKE18F512xxx16_flash.icf files .
- In the
IDE IAR project, also for the linker, specify the path to the new file
MKE18F512xxx16_flash.icf- The contents of the
Mbed-os \ targets \ TARGET_Freescale \ TARGET_MCUXpresso_MCUS \ TARGET_MKE18F \ drivers directory are erased and populated with the
devices \ MKE18F16 \ drivers directory
in the MKE18F512xxx16 family SDK- Replace the
\ mbed-os \ targets \ TARGET_Freescale \ TARGET_MCUXpresso_MCUS \ fsl_common.c file with the same one from the
devices \ MKE18F16 \ drivers directory located in the
MKE18F512xxx16 SDK . In the
Mbed-os \ targets \ TARGET_Freescale \ TARGET_MCUXpresso_MCUS \ TARGET_MKE18F \ drivers directory, delete the same file.
- From the
mbed-os \ targets \ TARGET_Freescale \ TARGET_MCUXpresso_MCUS \ TARGET_MKE18F \ drivers directory we delete files in the name of which FreeRTOS is present.
- From the
\ mbed-os \ features \ netsocket \ emac-drivers directory we delete all the files associated with the K6 microcontroller EMAC peripherals, because the new microcontroller does not have EMAC.
- Again we use the utility
Convert_ewp_file.py- Compile and get 267 errors. They are all in files that are in the
TARGET_MCUXpresso_MCUS directory and are mostly named with the suffix
api . Each file must be dealt with separately. A total of 12 files appear with errors.
Step 6. Editing Mbed Files
Fsl_clock_config.c file
This is the most important file at this stage. It is the initialization of clocking all subsystems of the chip. The RTOS initialization function
mbed_sdk_init calls the
BOARD_BootClockRUN function from this file. Replace the
fsl_clock_config.c file
with the verified file from the
led_blinky project. There it is called
clock_config.c (renamed after copying to
fsl_clock_config.h and correct
#include in it where necessary), and the call to the
BOARD_BootClockRUN function in the RTOS files is replaced with
BOARD_BootClockHSRUN , because we want to start the chip at the maximum frequency of
168 MHz .
- We consider the remaining files. Immediately raise doubts about their need. Indeed, many of them are simple wrappers for peripheral functions with a simplified interface. Most likely, they are made for an audience of novice programmers, for whom it is important that the API is similar to Arduino-based systems. We may neglect these files as not carrying the payload, although we will not be accepted into the Mbed community for this.
Files to remove:
API
• analogin_api.c
• analogout_api.c
• dma_api.c
• i2c_api.c
• pwmout_api.c
• spi_api.c
• dma_api_hal.h
Drivers
• AnalogIn.cpp
• I2C.cpp
• I2CSlave.cpp
• SPI.cpp
• SPISlave.cpp
• AnalogIn.h
• AnalogOut.h
• I2C.h
• I2CSlave.h
• PwmOut.h
• SPI.h
• SPISlave.h
HAL
• analogin_api.h
• analogout_api.h
• i2c_api.h
• pwmout_api.h
• spi_api.h
- Edit the file mbed.h to comment out the connection of the files that we deleted. Also edit object.h .
- Edit the mbed_die function called when the system crashes . By default, it flashes an LED. Remove blinking, we do not have such an LED.
- We are clearing PinNames.h and PeripheralNames.h files from pin announcements and structures associated with api files deleted before this
- We delete unnecessary arrays in the PeripheralPins.c file, after that it remains only to edit the pin map for UARTs in it.
- We slightly change the directory structure and the location of files in the targets subdirectory to reduce the randomness of naming and file fragmentation.
List of remaining files requiring correction:
• serial_api.c
• trng_api.c
• flash_api.c
• sleep.c
• us_ticker.c
These files cannot simply be deleted, as important RTOS services depend on them. The main problem is that the
MKE18F512xxx16 family uses a different peripheral name than the
MK66FN2M0VMD18 , although the periphery for the main API has almost remained the same.
File serial_api.c
In it, we mainly change the names of functions and enumerations inherited from the K66 chip. This file defines low-level functions for debugging RTOS output via UART.
Us_ticker.c file
important because it determines the mechanism for obtaining the exact time in ticks for RTOS (in our example, the value of the tick is 1 μs). This API is used in the RTOS delay functions and in the event queue services with a specified activation time on the time scale. To organize a continuous time counter, the associated channels 0 and 1 of the PIT module are used. Channel 0 has a period of 1 μs, channel 1 ends the cycle in 429 seconds (0xFFFFFFFF is loaded into it, the channel counter is decremented). To queue events, channels 2 and 3 of the PIT module with interrupts from channel 3 are used. Thus it turns out that Mbed occupied the entire PIT module and cannot be used for anything else.
Trng_api.c file
realizes hardware random number generation. In the chip
MKE18F512xxx16 there is no such generator, so we put plugs from the standard C function
rand . A good random number generator is needed for SSL and TLS data encryption protocols. So far we are not planning to use such on our board.
Sleep.c file
implements the function of entering and exiting sleep mode. This affects the work of the accelerator to work with Flash memory. It is necessary to correct the names of the functions that allow and prohibit the flash memory cache.
File flash_api.c
implements functions for programming internal flash memory. Here we came across the fact that
there can be two sections of Flash memory in chips of the
MKE18F512xxx16 family. Chose to work with section 0.
- Correct macros with internal chip frequency values in the
system_MKE18F16.h file
Linker file MKE18F512xxx16_flash.icf.
It should have a declaration of the symbol
__VECTOR_RAM . This is the address from which the interrupt vector table will be placed in RAM. In
Mbed OS, the interrupt vector table is always copied from Flash to RAM since it can be programmatically modified by the system during operation.
Kurez
Rested against the fact that the vector
SVC_Handler is a stub and fixated on itself. And the initialization of
Mbed OS causes exactly this vector. Somewhere missing the moment of setting the correct vector. It turns out they forgot to connect to IAR assembler files with the extension with a capital letter
S. And there the most important file with a context switch is
irq_cm4f.S . Thank you Python. Fix the
Convert_ewp_file.py utility and run it again. Recompile the project.
How to revive a dead chip
When initializing GPIO ports, it is possible to randomly incorrectly initialize I / O lines for the debugger and quartz. In this case, the chip stops debugging and even the SWD adapter J-Link stops programming. In our case, the problem can be solved simply. We short-circuit one output of the outer quartz to the ground, remove power, and serve again. Our program will not reach the wrong initialization GPIO because stuck waiting for the inclusion of quartz. At this time, SWD programming by the adapter becomes available again.
The problem of wrong time delay function wait
Measuring the blinking period of the LED, the slowdown in the execution of the
wait function was found to be longer than expected exactly twice. To check the correctness of the internal frequency settings, we initialize the output to the external output of the internal PLL clock divided by 8. We see the frequency 21 MHz. All right
During initialization of the frequency of ticks
RTX, the parameters of which are set in the
RTX_Config.h file, the
SystemCoreClock variable is
used , and it, in turn, is assigned in the
BOARD_BootClockHSRUN function during system initialization and is equal to 168000000. Everything is also correct here.
Checked in the
TimeLine window of the
IAR debugger the interrupt rate of the system tick, it is equal to 1 KHz, also correct.
It turned out to be incorrectly initialized module
PIT . He stopped counting when
RTX went into SLEEP mode. And
RTX enters this mode at every tick if there are no active tasks. Thus, the timer stopped, but its values were used in the
wait function to provide the most accurate delay. But we inherited this error from the official port of Mbed for K66!
On the third day, the porting of
ARM Mbed OS was successfully completed and the LED flashes.
github.com/Indemsys/Mbed_led_blinky_MKE18F