歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

移植uCOS-II到Cortex-M3平台

本文的目的是希望讀者能夠通過本文的內容掌握移植uCOS-II 的規范方法。如果只是需要移植文件,可以直接去Micriμm的官網上下載。

移植uCOS-II,主要的移植工作是編寫如下三個文件:

OS_CPU.H

OS_CPU_C.C

OS_CPU_A.ASM

下面就按照這三個文件的順序來介紹。本文以STM32F107+RealView Compiler 開發環境為例。如果使用的其他的開發環境,個別代碼可能需要做些小修改。

 

OS_CPU.H

 

OS_CPU.H 的第一部分是定義了一個宏OS_CPU_EXT。這一部分暫時可以先不去管。

#ifdef OS_CPU_GLOBALS

#define OS_CPU_EXT

#else

#define OS_CPU_EXT extern

#endif

接下來是一系列的類型定義。這一部分的移植需參考RealView Compiler Reference Guide的如下章節:

RealView Compiler Reference Guide->C and C++ Implementation Details->Basic data types

從這裡可以得到如下信息。

Type

Size in bits

Natural alignment in bytes

char

8

1 (byte-aligned)

short

16

2 (halfword-aligned)

int

32

4 (word-aligned)

long

32

4 (word-aligned)

long long

64

8 (doubleword-aligned)

float

32

4 (word-aligned)

double

64

8 (doubleword-aligned)

long double

64

8 (doubleword-aligned)

All pointers

32

4 (word-aligned)

_Bool

8

1 (byte-aligned)

根據上面的信息,形成下面的代碼:

typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int INT32S;
typedef float FP32;
typedef double FP64;
typedef unsigned int OS_STK;
typedef unsigned int OS_CPU_SR;

上面代碼中OS_STK 表示堆棧出棧、入棧的基本數據長度。我們知道Cortex-M3 的所有堆棧操作都是以字為單位的,所以這裡為 unsigned int 型。OS_CPU_SR 對應的是程序狀態寄存器PSRs,自然也是unsigned int 型。

然後是關於臨界區的處理,一般來說我們都喜歡使用第三種方法來實現臨界區,這裡也不例外。這裡多說幾句,第一種直接開關中斷的實現臨界區的方法很少采用,因為這種方法可能將原本關閉了的中斷意外的打開。第二種方法是最高效的實現方法,但是這種方法調整了堆棧指針,對於需要利用堆棧指針間接尋址局部變量的系統並不適用。(x86通常采用第二種方法,因為它有單獨的寄存器來做局部變量的尋址)第三種方法最保險,雖然效率比第二種方法略低一點。

#define OS_CRITICAL_METHOD 3
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}

#if OS_CRITICAL_METHOD == 3
OS_CPU_SR OS_CPU_SR_Save(void);
void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif

這兩個函數可以用匯編(OS_CPU_A.ASM)來編寫:

    EXPORT  OS_CPU_SR_Save   
  EXPORT  OS_CPU_SR_Restore
OS_CPU_SR_Save
    MRS    R0, PRIMASK ; Set prio int mask to mask all (except faults)
    CPSID  I
    BX      LR

OS_CPU_SR_Restore
    MSR    PRIMASK, R0
  BX      LR

也可以通過C代碼(OS_CPU_C.C)中插入匯編的方式來實現:

__asm OS_CPU_SR OS_CPU_SR_Save(void)
{
    MRS    R0, PRIMASK ; Set prio int mask to mask all (except faults)
    CPSID  I
    BX      LR
}
__asm void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr)
{
    MSR    PRIMASK, R0
    BX      LR
}

上面的代碼利用的RealView Compiler 的特殊功能(Embedded assembler),如需進一步的信息,可以參考RealView Compiler Reference Guide中Using the Inline and Embedded Assemblers這一章的內容。

然後是堆棧增長方向,ARM Cortex-M3 的堆棧是倒生的:

#define OS_STK_GROWTH 1

任務切換,OSCtxSw()在OS_CPU_A.ASM中定義:

#define OS_TASK_SW() OSCtxSw()

最後是一些函數原型聲明:

void OSCtxSw(void);
void OSIntCtxSw(void);
void OSStartHighRdy(void);
void OS_CPU_PendSVHandler(void);
void OS_CPU_SysTickHandler(void);

Copyright © Linux教程網 All Rights Reserved