新闻中心

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



关键词:

评论


相关推荐

技术专区

关闭