久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-Ⅱ在ATmega128上的移植Step by Step

μC/OS-Ⅱ在ATmega128上的移植Step by Step

作者: 時間:2016-10-08 來源:網絡 收藏

(2) 用C語言就可以打開和關閉中斷。

本文所使用的ICCAVR V6.29編譯器支持在C語言中內嵌匯編語句且提供專門開關中斷的宏:CLI()和SEI()。這樣,使得在C語言中開關中斷非常方便。

(3) 處理器支持中斷,并且能產生定時中斷(通常在10至100Hz之間)本文使用的ATmega128,有3個定時器,能產生μC/OS-Ⅱ所需的定時中斷。

(4) 處理器支持能夠容納一定數量數據的硬件堆棧。本文使用的ATmega128有4K RAM,硬件堆棧可以開辟在這4K RAM中。

(5) 處理器有將堆棧指針和其它CPU寄存器從內存中讀出和存儲到堆棧或內存中的指令。一般的單片機都滿足這個要求(如PUSH、POP指令),且ATmega128還具有直接訪問I/O寄存器的指令(IN、OUT等),它比8051系列的單片機更容易實現上述要求。

2.2移植的實現

μC/OS-Ⅱ的移植工作包括以下幾個內容:

用typedef聲明與編譯器相關的10個數據類型(OS_CPU.H)

用#define設置一個常量的值(OS_CPU.H)

#define聲明三個宏(OS_CPU.H)

用C語言編寫六個簡單的函數(OS_CPU_C.C)

編寫四個匯編語言函數(OS_CPU_A.S)

根據這幾項內容,本文逐步來完成。

2.2.1 INCLUDES.H文件

是主頭文件,在所有后綴名為.C的文件的開始都包含INCLUDES.H文件。使用INCLUDES.H的好處是所有的.C文件都只包含一個頭文件,簡潔,可讀性強。缺點是.C文件可能會包含一些它并不需要的頭文件,增加編譯時間。我們是以增加編譯時間為代價來換取程序的可移植性的。用戶可以改寫INCLUDES.H文件,增加自己的頭文件,但必須加在文件末尾。

程序清單L2.2.1 INCLUDES.H.

#include // ATmega128的寄存器頭文件

#include // ICCAVR的宏

#include

#include

#include

#include //一些C語言的標準庫

/*

***************************************************************************

* μC/OS-Ⅱ 頭文件

***************************************************************************

*/

#include G:PortingICCAVRporting12_8ATmega128os_cpu.h

#include G:PortingICCAVRPorting12_8EX1_mega128os_cfg.h

#include G:PortingICCAVRPorting12_8SOURCEucos_ii.h

要注意,μC/OS-Ⅱ 的3個頭文件的先后順序是:os_cpu.h,os_cfg.h最后是ucos_ii.h。

2.2.2 OS_CPU.H文件

OS_CPU.H包括了用#define定義的與處理器相關的常量、宏和類型定義。其中需要注意以下三點:

一是堆棧的生長方向。正如前面所述,ATmega128的堆棧生長方向是向下生長,即從高地址到低地址,因此,OS_STK_GROWTH要被定義為1。

二是進入臨界代碼段(critical code section)的方法。μC/OS-II提供了三種進入臨界代碼段的方法,第一種方法是直接對中斷允許位置1或清零,即進入臨界代碼段時,把中斷允許位清零,退出臨界代碼段時,把中斷允許位置1;第二種方法是進入臨界代碼段時,先將中斷狀態保存到堆棧中,然后關閉中斷。與之對應的是,退出臨界代碼段時,從堆棧中恢復前面保存的中斷狀態。第三種方法是,由于某些編譯提供了擴展功能,用戶可以得到當前處理器狀態字的值,并將其保存在C函的局部變量之中。這個變量可用于恢復狀態寄存器SREG的值。由于ICCAVR不提供此項擴展功能,所以本文暫不考慮用第 三種方法進入臨界代碼段。第一種方法存在著一個小小的問題:如果在關閉中斷后調用μC/OS-II的功能函數,當函數返 回后,中斷可能會被打開。我們希望如果在調用μC/OS-II的功能函數前,中斷是關著的,那么在函數返回后,中斷仍然是關著的。方法1顯然不滿足要求。本文使用μC/OS-II的第二種方法——先將中斷狀態保存到堆棧中,然后關閉中斷。

三是任務切換函數OS_TASK_SW( )是個宏,具體的實現是在OSCtxSw( )(OS_CPU_A.S)中程序清單L 2.2.2 OS_CPU.H.

#ifdef OS_CPU_GLOBALS

#define OS_CPU_EXT

#else

#define OS_CPU_EXT extern

#endif

/*

**************************************************************************

* 數據類型

* (與編譯器相關的內容)

*************************************************************************

*/

typedef unsigned char BOOLEAN;

typedef unsigned char INT8U; // 無符號8位數

typedef signed char INT8S; // 帶符號8位數

typedef unsigned int INT16U; // 無符號16位數

typedef signed int INT16S; // 帶符號16位數

typedef unsigned long INT32U; // 無符號32位數

typedef signed long INT32S; // 帶符號32位數

typedef float FP32; // 單精度浮點數

typedef unsigned char OS_STK; // 堆棧入口寬度為8位

typedef unsigned char OS_CPU_SR; // 定義狀態寄存器為8位

/*

*************************************************************************

*

*方法 #1: 用簡單指令開關中斷。

* 注意,用方法1關閉中斷,從調用函數返回后中斷會重新打開!

* 方法 #2: 關中斷前保存中斷被關閉的狀態.

*

*************************************************************************

*/

#define OS_CRITICAL_METHOD 2

#if OS_CRITICAL_METHOD == 1

#define OS_ENTER_CRITICAL() _CLI() // 關閉中斷

#define OS_EXIT_CRITICAL() _SEI() // 打開中斷

#endif

#if OS_CRITICAL_METHOD == 2

#define OS_ENTER_CRITICAL() asm(st -y,r16n in r16,0x3Fn clin push r16n

ld r16,y+); // 關閉中斷

#define OS_EXIT_CRITICAL() asm(st -y,r16n pop r16n out 0x3F,r16n ld



關鍵詞:

評論


相關推薦

技術專區

關閉