没有合适的资源?快使用搜索试试~ 我知道了~
uCOS-Ⅱ移植到ATmega128全过程
5星 · 超过95%的资源 需积分: 31 32 下载量 94 浏览量
2009-06-29
15:11:13
上传
评论
收藏 167KB DOC 举报
温馨提示
试读
15页
本文详细介绍了把μC/OS-Ⅱ移植到ATMEL公司的8位微控制器ATmega128上的全过程。所谓移植,就是使一个实时内核能在。某个微处理器或微控制器上运行。在移植之前,希望读者能熟悉所用微处理器和C编译器的特点。
资源推荐
资源详情
资源评论
本文详细介绍了把 移植到 公司的 位微控制器 上的全过程。所谓移
植,就是使一个实时内核能在。某个微处理器或微控制器上运行。在移植之前,希望读者能熟悉所
用微处理器和 编译器的特点。
的内核特点
之所以要先介绍 内核特点,是因为在 的移植过程中,仍需要用户用
语言和汇编语言编写一些与微处理器相关的代码。这里主要介绍 与 移植相
关的内核特点。如果读者已经对 比较了解了,那就不必阅读这一部分了。
微控制器 ()
的 包括一个算术逻辑单元(),一个状态寄存器(),一个通用工作
寄存器组和一个堆栈指针。状态寄存器()的最高位 是全局中断允许位。如果全局中断允许
位为零,则所有中断都被禁止。当系统响应一个中断后, 位将由硬件自动清“;当执行中断返回
()指令时, 位由硬件自动置“,从而允许系统再次响应下一个中断请求。 通用工作寄
存器组是由 个 位的通用工作寄存器组成。其中 ~ 这 个寄存器还可以两两合并为
个 位的间接地址寄存器。这些寄存器可以用来对数据存储空间进行间接寻址。这 个间接地址寄
存器的名称为: 寄存器、 寄存器、 寄存器。其中 寄存器还能用作对程序存储空间进行间接寻
址的寄存器。有些 ! 语言编译器还把 寄存器作为软件堆栈的堆栈指针,比如
!,"#$%&%"'!。
((((堆栈指针())是一个指示堆栈顶部地址的 位寄存器。在 ! 中,它被用作指向硬件堆
栈的堆栈指针。! 单片机上电复位后,) 指针的初始值为 *,由于 ! 单片机的堆栈是
向下生长的(从高地址向低地址生长),所以系统程序一开始必须对堆栈指针 ) 进行初始化,即将
) 的值设为数据存储空间的最高地址。! 编译器在链接 程序文件的时候,会自动在程序头
链入 &+,+-. 文件。&+,+-. 文件里面的程序将会去做初始化 ) 指针的工作。链入 &+,+-. 文件是
! 这个编译器的特点,在用其它编译器的时候,希望读者确认所使用的编译器是否带有自动
初始化 ) 的功能,若没有,应在用户程序中初始化 )。
数据存储空间(仅内部)
! 单片机的数据存储器是线形的,从低地址到高地址依次是 ) 寄存器区( 个通用寄存器),
寄存器区,数据存储区
((((! 编译器又将数据存储区划分为全局变量和字符串区,软件堆栈区和硬件堆栈区三个空间。
如下图:
((((((((((((((((((((((((((((((((((((((((((高地址
((((((((((((((((((((((((((((((((((((((硬件堆栈区
((((((((((((((((((((((((((((((((((((((软件堆栈区
(((((((((((((((((((((((((((((((((((全局变量和字符串区
((((((((((((((((((((((((((((((((((((( 寄存器区
((((((((((((((((((((((((((((((((((((() 寄存器区
(((((((((((((((((((((((((((((((((((((((((((低地址
((((! 编译器将堆栈分成了两个功能不同的堆栈来处理(这一点与 / 系列的单片机编译器
处理方式不同)。硬件堆栈用于储存子程序和中断服务子程序调用时的函数返回地址。这块数据区
域由堆栈指针 ) 进行寻址,数据的进栈和出栈有专门的汇编指令(.".,.-&0 等)支持,所以叫
做硬件堆栈区。软件堆栈用于传递参数,储存临时变量和局部变量。这块数据区域是用软件模拟堆
栈储存数据的方式进行数据存储,对该区域寻址的指针由用户自己定义,所以叫做软件堆栈区。
! 单片机的硬件堆栈的生长方向是向下的(从高地址向低地址生长),所以软件堆栈在定义的时
候,也采取相同的生长方向。
((((这里没有用 而采用 ! 单片机的提法是因为 属于 ! 系列单片机
中的一种,而所有的 ! 单片机的数据存储器组织方式都是一致的。在创建 的任务栈时,
需要了解所用微处理器数据存储空间尤其是堆栈空间的组织形式及相关的操作。读者应参阅所用微
处理器的资料和编译器的帮助文档,了解该部分知识。
1
的中断响应机制
(((( 有 1 个不同的中断源,每个中断源和系统复位在程序存储空间都有一个独立的中
断向量(中断入口地址)。每个中断源都有各自独立的中断允许控制位,当某个中断源的中断允许
控制位为“且全局中断允许位 也为“时,系统才响应该中断。
((((当系统响应一个中断请求后,会自动将全局中断允许位 清零,此时,后续中断响应被屏蔽。当
系统执行中断返回指令 时,会将全局中断允许位 置“,以允许响应下一个中断。若用户想
实现中断嵌套,必须在中断服务子程序中将全局中断允许位 置“。(这一点与 / 系列的单片
机不同)在中断向量表中,处于低地址的中断具有高的优先级。优先级高只是表明在多个中断同时
发生的时候,系统先响应优先级高的中断,并不含有高优先级的中断能打断低优先级的中断处理工
程的意思。这与 / 系列单片机的中断优先级概念不同。
((((由于 的任务切换实际上是模拟一次中断,因此需要知道 ) 的中断响应机制。中断发
生时2 按以下步骤顺序执行:
全局中断允许位 清零。
3将指向下一条指令的 ) 值压入堆栈,同时堆栈指针 ) 减 。
选择最高优先级的中断向量装入 ),程序从此地址继续执行中断处理。
4当执行中断处理时,中断源的中断允许控制位清零。
中断结束后,执行 指令,此时
全局中断允许位 置“。
3) 从堆栈推出,程序从被中断的地方继续执行。
特别要注意的是:! 单片机在响应中断及从中断返回时,并不会对状态寄存器 和通用寄存
器自动进行保存和恢复操作,因此,对状态寄存器 和通用寄存器的中断保护工作必须由用户
来完成。
1 的定时器中断
((( 有三个定时器:22;它们三者都有计数溢出中断功能2而且 和 还有匹
配比较中断,即定时器计数到设定的值时,产生中断并自动清零。若系统采用这种中断方式,其好
处是在中断服务程序 中不需要重新装载定时器的值。但本文出于通用性的考虑,仍采用定时器
计数溢出中断方式
的移植
移植条件
要实现 的移植,所用的处理器和编译器必须满足一定的条件:
56所用的 编译器能产生可重入代码。
可重入代码是指可以被一个以上的任务调用,而不必担心其数据会被破坏的代码。可重入代码任何
时候都可以被中断,一段时间以后又可以重新运行,而相应的数据不会丢失,不可重入代码则不行。
本文所使用 ,7+ 公司的 !!8 编译器能产生可重入代码。
() 用 语言就可以打开和关闭中断。
本文所使用的 !!8 编译器支持在 语言中内嵌汇编语句且提供专门开关中断的宏:
56和 56。这样,使得在 语言中开关中断非常方便。
() 处理器支持中断,并且能产生定时中断(通常在 至 9: 之间)本文使用的
,有 个定时器,能产生 所需的定时中断。
(1) 处理器支持能够容纳一定数量数据的硬件堆栈。本文使用的 有 1;,硬件
堆栈可以开辟在这 1; 中。
(/) 处理器有将堆栈指针和其它 ) 寄存器从内存中读出和存储到堆栈或内存中的指令。一般的
单片机都满足这个要求5如 )9、)) 指令6,且 还具有直接访问 寄存器的指令
(<、 等),它比 / 系列的单片机更容易实现上述要求。
移植的实现
的移植工作包括以下几个内容:
用 +=.#7 声明与编译器相关的 个数据类型5>)96
2
用?#@' 设置一个常量的值5>)96
?#@' 声明三个宏5>)96
用 语言编写六个简单的函数5>)>6
编写四个汇编语言函数5>)>6
根据这几项内容,本文逐步来完成。
<49 文件
((((<49是主头文件,在所有后缀名为 的文件的开始都包含 <49 文件。使用
<49 的好处是所有的 文件都只包含一个头文件,简洁,可读性强。缺点是 文件可能
会包含一些它并不需要的头文件,增加编译时间。我们是以增加编译时间为代价来换取程序的可移
植性的。用户可以改写 <49 文件,增加自己的头文件,但必须加在文件末尾。程序清单
(<49
#%'AB-#(C%"$0D(((((((((((((((( 的寄存器头文件
#%'AB-#(CA,"&0D(((((((((((((((((! 的宏
#%'AB-#(C&+#%"0D
#%'AB-#(C&+,%'0D
#%'AB-#(CA+=.0D
#%'AB-#(C&+#B%E0D((((((((((((((((一些 语言的标准库
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
F(((((((((((((((((头文件
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
#%'AB-#(GHI)",+%'I!I.",+%'>II"&>A.-0G
#%'AB-#(GHI)",+%'I!I)",+%'>I>I"&>A70G
#%'AB-#(GHI)",+%'I!I)",+%'>II-A"&>%%0G
要注意,的 个头文件的先后顺序是:"&>A.-0,"&>A70 最后是 -A"&>%%0。
>)9 文件
>)9 包括了用?#@' 定义的与处理器相关的常量、宏和类型定义。其中需要注意以下三点:
一是堆栈的生长方向。正如前面所述, 的堆栈生长方向是向下生长,即从高地址到低
地址,因此,>;>J9 要被定义为 。
二是进入临界代码段5A,%+%ABA"#&A+%"'6的方法。 提供了三种进入临界代码段的方法2
第一种方法是直接对中断允许位置 或清零,即进入临界代码段时,把中断允许位清零,退出临界
代码段时,把中断允许位置 ;第二种方法是进入临界代码段时,先将中断状态保存到堆栈中,然
后关闭中断。与之对应的是,退出临界代码段时,从堆栈中恢复前面保存的中断状态。第三种方法
是,由于某些编译提供了扩展功能,用户可以得到当前处理器状态字的值,并将其保存在 函数的
局部变量之中。这个变量可用于恢复状态寄存器 的值。由于 ! 不提供此项扩展功能,
所以本文暂不考虑用第三种方法进入临界代码段。第一种方法存在着一个小小的问题:如果在关闭
中断后调用 的功能函数,当函数返回后,中断可能会被打开。我们希望如果在调用
的功能函数前,中断是关着的,那么在函数返回后,中断仍然是关着的。方法 显然不满足要
求。本文使用 的第二种方法——先将中断状态保存到堆栈中,然后关闭中断。 三是任务
切换函数 >;>J56是个宏,具体的实现是在 +*K56(>)>)中
程序清单 >)9
?%7#7(>)>3
?#@'>)>
?B&
?#@'>)>(*+,'
?'#%7
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
F((((((((((((((((((((((((((((((((数据类型
3
剩余14页未读,继续阅读
资源评论
- jingke_szh2013-08-16感谢分享,就是编译器和我 的不一样
- 松松2013-08-02感谢分享,很有用 运行自己找了个板子试了一下.
- bingbinglifangbin2013-06-22感谢分享,很有用
zhl_tc
- 粉丝: 1
- 资源: 15
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 新能源汽车行人提醒装置AVAS流程图
- 海信电视刷机数据 LED32EC290N(0000)BOM1通用LED32K220(0000)BOM1生产用软件数据U盘升级文件
- 基于BS模式的冷链物流系统的设计与实现(论文+源码)-kaic.zip
- 红绿灯现实测试数据集,红绿灯识别检测
- unity自制模式(MVC与命令模式相结合)
- 基于tensorflow卷积神经网络实现图像风格的迁移源码(高分项目).zip
- 学习参考数据 1.参考书 2.ppt 3.源码
- 基于深度学习的Xilinx DDR3存储器接口解决方案,适合FPGA的初学者,也适合需要使用DDR进行FPGA设计的设计人员
- arduino ide 2.3.2 Windows
- 花旗杯基于深度学习的模型分析与特征提取
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功