📜 ⬆️ ⬇️

Porting Arm Mbed OS to a dedicated controller



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



Step 2. Getting the application project without RTOS




Step 3. Configuring and converting the Mbed project



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


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

Source: https://habr.com/ru/post/262839/


All Articles