没有合适的资源?快使用搜索试试~ 我知道了~
首页uCOS-II在ATmega128上的移植
资源详情
资源评论
资源推荐

在 上的移植
本文详细介绍了把 移植到 公司的 位微控制器 上的全过
程。所谓移植,就是使一个实时内核能在某个微处理器或微控制器上运行。在移植之前,
希望读者能熟悉所用微处理器和 编译器的特点。
的内核特点
之所以要先介绍 内核特点,是因为在 的移植过程中,仍需要
用户用 语言和汇编语言编写一些与微处理器相关的代码。这里主要介绍 与
移植相关的内核特点。如果读者已经对 比较了解了,那就不必阅
读这一部分了。
微控制器 ()
的 包括一个算术逻辑单元(),一个状态寄存器(),一
个通用工作寄存器组和一个堆栈指针。状态 寄存器()的最高位 是全局中断允许
位。如果全局中断允许位为零,则所有中断都被禁止。当系统响应一个中断后, 位将由硬
件自动清“;当执行中断返回()指令时, 位由硬件自动置“,从而允许系统再
次响应下一个中断请求。
通用工作寄存器组是由 个 位的通用工作寄存器组成。其中 ~ 这 个寄
存器还可以两两合并为 个 位的间接地址寄存器。这些寄存器可以用来对数据存储空
间进行间接寻址。这 个间接地址寄存器的名称为: 寄存器、! 寄存器、" 寄存器。其
中 " 寄存器还能用作对程序存储空间进行间接寻址的寄存器。有些 # 语言编译器还
把 ! 寄存器作为软件堆栈的 堆栈指针,比如 #,$%&'('$)#。
堆栈指针(*)是一个指示堆栈顶部地址的 位寄存器。在 # 中,它被用作
指向硬件堆栈的堆栈指针。# 单片机上电复位后,* 指针的初始值为 +,由于
# 单片机的堆栈是向下生长的(从高地址向低地址生长),所以系统程序 一开始必须
对堆栈指针 * 进行初始化,即将 * 的值设为数据存储空间的最高地址。# 编译器
在链接 程序文件的时候,会自动在程序头链入 (,-,. 文件。(,-,. 文件里面的程序
将会去做初始化 * 指针的工作。链入 (,-,. 文件是 # 这个编译器的特点,在用
其它编译器的时候,希望读者确认所使用的编译器是否带有自动初始化 * 的功能,若没
有,应在用户程序中初始化 *。

数据存储空间(仅内部)
# 单片机的数据存储器是线形的,从低地址到高地址依次是 * 寄存器区( 个通用
寄存器), 寄存器区,数据存储区。
# 编译器又将数据存储区划分为全局变量和字符串区,软件堆栈区和硬件堆栈区
三个空间。如下图:
高地址
硬件堆栈区
软件堆栈区
全局变量和字符串区
寄存器区
* 寄存器区
低地址
# 编译器将堆栈分成了两个功能不同的堆栈来处理(这一点与 / 系列的单片
机编译器处理方式不同)。硬件堆栈用于储存子程序和中断服务子程序调用时的函数返回
地址。这块数据区域由堆栈指针 * 进行寻址,数据的进栈和出栈有专门的汇编指令
(.$.,.(0 等)支持,所以叫做硬件堆栈区。软件堆栈用于传递参数,储存临时变量和
局部变量。这块数据区域是用软件模拟堆栈储存数据的方式进行数据存储,对该区域寻址
的指针由用户自己定义,所以叫做软件堆栈区。
# 单片机的硬件堆栈的生长方向是向下的(从高地址向低地址生长),所以软件堆
栈在定义的时候,也采取相同的生长方向。
这里没有用 而采用 # 单片机的提法是因为 属于 # 系
列单片机中的一种,而所有的 # 单片机的数据存储器组织方式都是一致的。在创建
的任务栈时,需要了解所用微处理器数据存储空间尤其是堆栈空间的组织形式及
相关的操作。读者应参阅所用微处理器的资料和编译器的帮助文档,了解该部分知
识。
的中断响应机制
有 1 个不同的中断源,每个中断源和系统复位在程序存储空间都有一个
独立的中断向量(中断入口地址)
。每个中断源都有各自独立的中断允许控制位,当某个中断源的中断允许控制位为“且全
局中断允许位 也为“时,系统才响应该中断。

当系统响应一个中断请求后,会自动将全局中断允许位 清零,此时,后续中断响应被
屏蔽。当系统执行中断返回指令 时,会将全局中断允许位 置“,以允许响应下一
个中断。若用户想实现中断嵌套,必须在中断服务子程序中将全局中断允许位 置“。
(这一点与 / 系列的单片机不同) 在中断向量表中,处于低地址的中断具有高的优先
级。优先级高只是表明在多个中断同时发生的时候,系统先响应优先级高的中断,并不含
有高优先级的中断能打断低优先级的中断处理工程的意思。这与 / 系列单片机的中断
优先级概念不同。
由于 的任务切换实际上是模拟一次中断,因此需要知道 * 的中断响应机制。
中断发生时2 按以下步骤顺序执行:
全局中断允许位 清零。
3将指向下一条指令的 * 值压入堆栈,同时堆栈指针 * 减 。
选择最高优先级的中断向量装入 *,程序从此地址继续执行中断处理。
4当执行中断处理时,中断源的中断允许控制位清零。
中断结束后,执行 指令,此时
全局中断允许位 置“。
3* 从堆栈推出,程序从被中断的地方继续执行。
特别要注意的是:# 单片机在响应中断及从中断返回时,并不会对状态寄存器 和
通用寄存器自动进行保存和恢复操作,因此,对状态寄存器 和通用寄存器的中断保
护工作必须由用户来完成。
1 的定时器中断
有三个定时器:22;它们三者都有计数溢出中断功能2而且 和
还有匹配比较中断,即定时器计数到设定的值时,产生中断并自动清零。若系统采用这
种中断方式,其好处是在中断服务程序 中不需要重新装载定时器的值。但本文出于通
用性的考虑,仍采用定时器计数溢出中断方式
的移植
移植条件
要实现 的移植,所用的处理器和编译器必须满足一定的条件:
56所用的 编译器能产生可重入代码。
可重入代码是指可以被一个以上的任务调用,而不必担心其数据会被破坏的代码。可重入

代码任何时候都可以被中断,一段时间以后又可以重新运行,而相应的数据不会丢失,不
可重入代码则不行。本文所使用 -7, 公司的 ##8
() 用 语言就可以打开和关闭中断。
本文所使用的 ##8 编译器支持在 语言中内嵌汇编语句且提供专门开关中断的
宏:56和 56。这样,使得在 语言中开关中断非常方便。
() 处理器支持中断,并且能产生定时中断(通常在 至 9: 之间)本文使用的
,有 个定时器,能产生 所需的定时中断。
(1) 处理器支持能够容纳一定数量数据的硬件堆栈。本文使用的 有 1;
,硬件堆栈可以开辟在这 1; 中。
(/) 处理器有将堆栈指针和其它 * 寄存器从内存中读出和存储到堆栈或内存中的指令。
一般的单片机都满足这个要求5如 *9、** 指令6,且 还具有直接访问
寄存器的指令(<、 等),它比 / 系列的单片机更容易实现上述要求。
移植的实现
的移植工作包括以下几个内容:
用 ,=.%7 声明与编译器相关的 个数据类型5>*96
用?%@) 设置一个常量的值5>*96
?%@) 声明三个宏5>*96
用 语言编写六个简单的函数5>*>6
编写四个汇编语言函数5>*>6
根据这几项内容,本文逐步来完成。
<49 文件
<49
是主头文件,在所有后缀名为 的文件的开始都包含 <49 文件。使用
<49 的好处是所有的 文件都只包含一个头文件,简洁,可读性强。缺点是
文件可能会包含一些它并不需要的头文件,增加编译时间。我们是以增加编译时间为代价
来换取程序的可移植性的。用户可以改写 <49 文件,增加自己的头文件,但必须
加在文件末尾。
程序清单 <49
?')AB%C'$&0D 的寄存器头文件
剩余16页未读,继续阅读










安全验证
文档复制为VIP权益,开通VIP直接复制

评论1