This paper introduces the method of porting the C/OS real-time operating system to the Coldfire processor MCF52235, providing a real-time operating system platform for the software development of the MCF5223x series microcontrollers. First, the characteristics and kernel structure of C/OS are analyzed. Combined with the structural characteristics of MCF52235 and the software and hardware development tools used, the porting conditions and implementation methods are studied in depth, and the files that need to be modified, the codes written, and the issues that need to be paid attention to in the system porting are elaborated in detail. Then, using the Coder 6.4 integrated development environment and evaluation board, the correctness of the porting code is verified by establishing two application tasks, indicating that porting uC/OS on MCF52235 is successful and feasible. The porting process and method introduced here can be used as a typical example of porting C/OS in other microcontrollers.
uC/OS is a multi-tasking real-time operating system. The kernel source code is open, concise, customizable, and the execution time is deterministic. It is highly portable and very suitable for the development of some small and medium-sized embedded systems. uC/OS can be ported to embedded systems of different types and sizes from 8 to 64 bits, and can run on most 8-bit, 16-bit, 32-bit, and even 64-bit microprocessors and DSPs [1].
MCF52235 is an embedded microcontroller of Freescale's Coolfire series 32-bit MCU solution, using the V2 version
RISC core. MCF52235 has 32 KB SRAM and 256 KB FLASH, and integrates standard Coldfire peripherals, including three SCIs suitable for medium and long distance communication, an I2C and a Q SPI for communication between the system and peripherals. At a core frequency of 60 Hz, the processing power of MCF52235 is 56 MIPS, with a high performance-price ratio [24]. MCF52235 is sufficient for porting C/OS.
RAM and FLASH, and has faster processing speed and lower cost, so for the development of embedded application systems, embedded C/OS
To realize the porting of C/OS to MCF52235, two aspects of work need to be done: one is to redefine the size and function of the kernel; the other is to write hardware-related code for the kernel. The file structure of C/OS is shown in Figure 1. It can be seen that C/OS has nothing to do with the CPU type. The C code file COS.C includes many files, which are the kernel of C/OS and many functional functions. The first three files are real-time kernel, task management and clock beats. These three files must be used. The following 6 functional functions are used for communication between tasks, and only some of them may be used in the application.
The unused ones can be excluded to avoid generating useless codes during compilation. This part of the code is irrelevant to the CPU type. When porting, these files should not be changed. The configuration file OS_CFG.H needs to be made according to the application requirements. Its main function is to determine the system function provided by C/OS.
This file needs to be modified during porting to determine which parts of the program are used and which are not. There are three main code files related to the CPU type: OS_CPU.H, OS_CPU_A.ASM and OS_CPU_C.C. The files define the data types used for a specific CPU to define related macros. OS_CPU_A.ASM is hardware-related code written in assembly language, and OS_CPU_C.C is hardware-related code written in C language. Since the porting uses a C cross-compilation tool, assembly statements can be inserted into the C code. These two files can be merged into one file during porting [5].
The timing interrupt that generates the clock beat comes from inside the microcontroller, but not from inside the V2 core. The timing interrupt can be generated by the real-time clock.
You can also use the on-chip peripheral module timer unit to generate timer interrupts. This part of the code is obviously hardware-related and needs to be written by yourself during porting [6].
2 Transplantation process
The so-called transplantation is to enable a real-time kernel to run on a certain microprocessor or microcontroller. In order to facilitate transplantation, most of the C/OS code is written in C language, but some processor-related codes still need to be written in C and assembly language. This is because C/OSII can only use assembly language to read and write processor registers. The transplantation process mainly includes preparation before transplantation, writing BSP (board support package) and modifying and writing processor-related codes. The relationship between C/OS core code, CPU-related interface program, BSP and user application is shown in Figure 2.
2.1 Preparation before transplantation
Go to the official website of C/OS and download the C/OS source code. Open Codew arrior 6.4 to create the project file of MCF52235, and then add the C/OS source code file to the project [8]. There are several places that need to be modified:
(1) In the downloaded source code, change os_cfg_r.h to os_cfg.h; change os_dbg_r.c to os_dbg.c.
(2) Since this may cause duplicate definition errors, the files that are repeatedly included in the source code need to be commented out.
(3) It is necessary to compile in INT ERNAL_FLASH mode, not in RAM mode, otherwise an overflow error will occur.
2.2 Writing BSP
The board support package (BSP) is a software layer between the underlying hardware and the operating system, responsible for the initial hardware and software after the system is started.
Initialize and encapsulate the underlying hardware so that the operating system no longer faces specific hardware [9]. Two BSP files are created here: BSP.ASM and BSP.C. Among them, BSP.ASM contains the interrupt interface program written in assembly language. BSP.C contains the hardware and software initialization program and the interrupt service program that generates the clock beat.
2.3 Modification and writing of processor-related code
There are three processor-related files, namely OS_CPU . H, OS_CPU _ A. ASM and OS _ CPU _ C. C, that need to be modified. Since MCF52235 has an eMAC module, it is also necessary to write the OS_CPU _I. ASM file to be used during task switching and interruption and interrupt return.
Save and restore related registers.
2.3.1 Porting of OS_CPU.H
OS_CPU.H contains some macro definitions and data type definitions related to the processor and compiler.
The short type is 16 bits, and the int type is 32 bits. The stack of MCF52235 is 32 bits wide, so OS_STK is defined as
32 bits, all task stacks must be declared using the OS_ST K data type. The data type is defined as follows:
ty pedef unsigned char BOOLEAN;
ty pedef unsigned char INT 8U;
type pedef signed char INT8S;
ty pedef unsigned sho rt INT16U;
ty pedef signed shor t INT16S;
type pedef unsigned int INT32U;
type pedef signed int INT32S;
typedef float FP32;
typedef double FP64;
typedef unsigned int OS_STK;
typedef unsigned short OS_CPU_SR;
(1) Critical section processing. Like all real-time kernels, interrupts must be disabled when entering the critical section of the code and enabled when completing it.
OS defines two macros to disable and enable interrupts: OS_ENT ER_CRITICAL() and OS_EXIT _CRITICAL(). C/ OS defines three methods to disable and enable interrupts, and the third method is selected in most cases.
# define OS_CRITICAL_METH OD # 3
# define OS_ENTER_CRITICAL( ) { cpu_sr = OS _CPU_
SR_Save( ) ; } // Disable interrupt
# def ineOS _ EXIT _ CRITICAL( ) { OS _ CPU _ SR_ Resto re
( cpu_sr ); } // Enable interrupt
(2) Task layer context switch. When C/OS calls OS_TASK_SW(), the task layer context switch occurs.
The context switch is different for different processors, so an assembly function needs to be executed. In this case, the TRA P instruction is used to generate
The advantage of using the TRAP instruction is that it can make it look like an interrupt. Here we use #14 TRAP because in most cases
In this case, #15 TRAP is reserved by the debugger and monitor. #14 TRAP is located at VBR+ 0x00B8, and then jumps to the corresponding address.
Place the address of OSCtx Sw() at this vector. This function is declared in OS_CPU_A.ASM. VBR stands for Vector Base Register,
Contains the base address of the exception vector table, initialized to 0x00000000 at program start, but can be changed at runtime.
# define OS_TASK_SW( ) asm( T RAP # 14; )
(3) Stack growth direction. The stack growth direction of MCF52235 is from high address to low address, so OS_ST K_GROWTH is set to
is 1.
#define OS_STK_GROWTH 1
2.3.2 OS_CPU_C.C porting
OS_CPU_C.C contains 10 relatively simple C language functions. Generally speaking, C/OS only needs OSTaskStkInit(). Other functions are used to allow users to expand the operating system functions in their own programs. If you need to use these functions, you need to set OS_CPU_HOOKS_EN to 1 in OS_CFG.H. Stack initialization: OSTaskStkInit() Although it is written in C language,
This function is used to initialize the task stack, which is created by the task function OSTask.
Create() or extend the task function OSTaskCreateExit(). The essence of task stack initialization is to simulate an interruption, so that the stack looks like an interruption has just occurred. The task stack stores the starting address of the task code and the values of some CPU registers. Once the conditions are met, the task can be executed. The structure of the initialized task stack is shown in Figure 3.
2.3.3 OS_CPU_A. ASM porting
This file contains 5 fairly simple assembly functions, since it is not generally possible to save and restore registers in C.
( 1) OS_CPU_SR_Save()
This function implements OS_CRITICAL_MET HOD # 3 by saving the interrupt mask register and then disabling interrupts. When the function returns, D0 contains the contents of the status register, which contains the current interrupt disable state. This return value is saved by the calling function to the variable
cpu_sr.
( 2) OS_CPU_SR_Restore()
This function is used to restore the interrupt mask to the state before calling OS_ENTER_CRITICAL().
If interrupts are disabled before ENTER_CRITICAL(), then after OS_EXIT_CRITICAL(), interrupts are disabled.
( 3) OSStartHighRdy()
This function is called by OSStart() to run the highest priority task. OSStart() sets OSTCBHighRdy to point to the OS_T CB of the highest priority task. Upon return from OSTaskSwHoo k(), OSRunning is set to OS_T RUE, which indicates that the RT OS is now
will be executed. Restore the stack pointer from the OS_T CB of the highest priority task, and then fetch the CPU registers from the task stack. Finally execute
A RET instruction, which pops SR and PC from the stack, and the current task code begins to execute.
( 4) OSCtx Sw( )
A task-level task switch occurs when a task is no longer running, such as when a task calls a function that is delayed by 10 clock ticks.
At this time, C/OS needs to find the next most important task to run. The function of OSCtx Sw () is to save the CPU registers and stack of the task to be suspended, and restore the CPU registers and stack of the task to be run. Task-level context switching is shown in Figure 4.
( 5) OSIntCtxSw( )
When the interrupt service routine is completed, the OSIntExit() function is called to determine if there is a more important task that needs to be executed than the interrupted task. In this case, OSIntExit() determines which task to run and then calls OSIntCtxSw(). In this case, the interrupt service routine has saved the CPU registers of the interrupted task, and all that needs to be done is to restore the CPU registers of the new task.
2.3.4 OS_CPU_I. Writing ASM
If the enhanced multiply-accumulate unit (eMAC) module is used, the eMAC registers should be saved and restored on context switches and interrupts.
Saving and restoring the eMAC registers are implemented using two macros [10]. The code is as follows:
. macro OS_EM AC_SAVE
MOVE. L MACSR, D7
CLR.L D0
MOVE. L D0, M ACSR
MOVE. L ACC0, D0
MOVE. L ACC1, D1
MOVE. L ACC2, D2
MOVE. L ACC3, D3
MOVE. L ACCEXT01, D4
MOVE. L ACCEXT23, D5
MOVE. L MASK, D6
LEA 32( A7) , A7
MOVEM. L D0D7, ( A7)
.endm
. macro OS_EM AC_REST ORE
MOVEM. L ( A7 ) , D0D7
MOVE. L # 0, MACSR
MOVE. L D0, ACC0
MOVE. L D1, ACC1
MOVE. L D2, ACC2
MOVE. L D3, ACC3
MOVE. L D4, ACCEXT01
MOVE. L D5, ACCEXT23
MOVE. L D6, MASK
MOVE. L D7, MACSR
LEA 32( A7) , A7
.endm
2.4 Generation of clock beats
Finally, we need to write an interrupt service program that uses the on-chip timer to generate clock beats. C/OS requires the microcontroller to provide a simple clock for tasks such as delay. Here, the programmable interrupt timer is used to generate clock beat interrupts. Calling OSTimeTick() in the timer interrupt service program generates the clock beat required by the system. The interrupt handler after the interrupt is generated in C/OS is as follows:
_BSP_TickISR:
MOVE. W # 0x2700, SR
LEA 60( A7) , A7
[page]
MOVEM. L D0D7/ A0 A6, ( A7)
OS_EMAC_SAVE
MOVEQ. L # 0, D0
MOVE.B (_OSIntNesting), D0
ADDQ. L # 1, D0
MOVE.B D0, (_OSI ntNesting)
CMPI.L#1,D0
BNE_BSP_TickISR_1
MOVE. L ( _OSTCBCur ) , A1
MOVE. L A7, ( A1)
_BSP_TickISR_1:
JSR _BSP_TickISR_Handler
JSR _OSInt Exit
OS_EMAC_RESTORE
MOVEM. L ( A7 ), D0D7/ A0A6
LEA 60( A7) , A7
RTE
3 Task Creation and Testing of Migration Code
After the source program is transplanted, users can try to create their own projects. Writing task codes is basically the same as before in the front-end and back-end systems.
The purpose is to write each task into a file independently, and finally schedule it uniformly by the main program. In order to test whether the transplantation is successful, two tasks are created using STaskCreateExt (). One task makes the LED on the board flash once a second, and the other task uses the on-chip A/D to sample the acceleration sensor signal on the board and display the current acceleration value on the digital tube. Finally, OSStart() is called to start multi-task scheduling.
3.1 Define the stack size for each task
OS_STK
TaskStartStk[ T ASKSTART ST K_SIZE] ;
OS_STK ADT askStk[ T ASKSTK_SIZE] ;
Then initialize the system in the main() function:
OSInit( ) ;
3.2 Create a task
OST askCreateEx t( TaskStart, ( void * ) 0, ( OS _ ST K * )
& T askStar tSt k[ T ASKSTARTST K_SIZE1] , T ASK _START _
PRIO, TASK_START_PRIO, ( OS_ST K* ) & T askStart St k[ 0] ,
TASK_ST ART_ST K_SIZE, ( vo id * ) 0, OS_TASK_OPT _ST K_
CH K| OS_TASK_OPT_STK_CLR) ;
OSTaskCreateExt ( ADT ask, ( vo id * ) 0, ( OS _ STK * )
& ADTaskStk[TASKST K_SIZE1], ADTASK_PRIO, ADT ASK
_ PRIO, ( OS _ ST K * ) & ADTaskStk [ 0] , TASK _ ST K _SIZE,
( vo id * ) 0, OS_TASK_OPT_STK_CHK) ;
3.3 System startup
OSStart( ) ;
3.4 Test Results
After the test code is compiled and downloaded to the experimental board, the information displayed on the experimental board indicates that the two tasks are running alternately, indicating that the shift
The implantation was successful, as shown in Figure 5.
Previous article:Using Allegro to implement high-speed circuit layout design for embedded systems
Next article:Design of MCF5307 embedded system driver based on hardware hiding idea
Recommended ReadingLatest update time:2024-11-16 14:30
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Share CC2541 Bluetooth clock settings
- Analysis of the structure and working principle of single chip microcomputer serial communication
- Basic functions of linear charger
- A place that I don't understand
- Problems with sensor acquisition circuits
- What are the RF challenges of small cells for 5G networks?
- Basic Features of DSP TMS320C6000
- Let's take a look at this power switching circuit.
- What is the reason for the Flash Timeout error message when downloading the program on STM32F4?
- EEWORLD University ---- FreeRTOS on stm32 ST