基于STM32的嵌入式操作系统程序设计及实现本科毕业论文
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本科毕业论文(设计)
论文题目:基于STM32的嵌入式操作系统程序设计及实现
姓名:学号:班级:年级:专业:学院:指导教师:完成时间:
作者声明
本毕业论文(设计)是在导师的指导下由本人独立撰写完成的,没有剽窃、抄袭、造假等违反道德、学术规范和其他侵权行为。
对本论文(设计)的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。
因本毕业论文(设计)引起的法律结果完全由本人承担。
毕业论文(设计)成果归武昌工学院所有。
特此声明
作者专业:电子信息工程
作者学号:0930********
作者签名:
年月日
基于STM32的嵌入式操作系统
程序设计及实现
郝宇
The Design and Implementation of embedded operating system program based on STM32
Hao, Yu
2013年5月20日
摘要
随着科学技术不断的进步,工业生产越来越先进复杂,操作系统µC/OS-II 是高效、稳定、可靠、节能的系统,广泛应用安防,消费电子中。
而基于Cortex-M3架构下的STM32是一款性价比优越新型微处理器,将µC/OS-II移植到STM32
上能够发挥其高效的性能,从而投入社会生产,制造出很多有用又实惠的电子产品,为我们的生活带来便利。
本文主要的研究内容是µC/OS-II操作系统理论分析、移植方法、应用程序设计及调试仿真实现。
首先,对µC/OS-II的理论分析,研究其实际应用及系统结构;其次,分析STM32硬件平台及µC/OS-II的移植需求;最后,在µC/OS-II 上开发LCD,LED,按键KEY等应用程序,并对多任务系统调试分析。
主要研究结论如下:
(1)µC/OS-II操作系统主要分为任务管理、内存管理和时间管理三大部分,其间通信是通过消息队列和消邮箱。
(2)µC/OS-II移植主要在OS_CPU.H,OS_CPU_C.C,OS_CPU_A.ASM三个文件中,涉及到数据类型、堆栈、中断定义和任务切换等。
(3)应用程序设计优先级分配要合理,硬件平台初始化模块化处理。
关键词:嵌入式系统;µC/OS-II;移植
Abstract
With the progress of science and technology constantly, advanced industrial production to more complex, the operating system µC/OS-II is efficient, stable, reliable, energy saving system, widely used in the security, and consumer electronics. And based on the STM32 architecture Cortex-M3 framework is a superior cost-effective new microprocessor, µC/OS-II transplantation to STM32 can play its efficient performance, thus in social production and create a lot of useful and affordable electronic product, bring convenience to our lives.
This article main research content is µC/OS-II operating system theory analysis, method of transplantation, application design and debugging of the simulation implementation. First of all, the theoretical analysis of µC/OS-II, research the actual application and system structure; Second, analysis of STM32 hardware platform and the demand µC/OS-II transplantation. Finally, on the µC/OS-II development of LCD, LED, button KEY applications, and analysis of multitasking system debugging. Main research conclusion is as follows:
(1) µC/OS-II operating system consists of three major task management, memory management and time management, in which communication is through the message queue and email.
(2) µC/OS-II transplantation mainly in OS_CPU_C.C, OS_CPU_A.ASM file, OS_CPU.H, three involves the data type definition and task switching etc, stack, interrupt.
(3)The application design to the allocation of priorities, initialize the modular processing hardware platform.
Key words:embedded system; µC/OS-II; transplant
目录
1 概述 (1)
1.1研究的目的及意义 (1)
1.2国内外研究状况综述 (1)
1.3研究的主要内容 (2)
2 µC/OS-II的理论介绍 (3)
2.1 µC/OS-II各模块的基本功能 (3)
2.2STM32上移植方法 (7)
3 LCD屏程序设计及调试 (12)
3.1工具概述 (12)
3.2硬件结构 (13)
3.3C程序设计 (15)
3.4调试 (16)
结语 (18)
主要参考文献 (19)
附录 (20)
附录1主程序代码 (20)
1 概述
1.1 研究的目的及意义
µC/OS-II是由美国工程师Jean Labrosse编写的嵌入式多任务的实时操作系统,包括实时内核、任务管理、时钟管理、任务间通信同步(信号量、邮箱、消息队列)和内存管理。
除了有上面的优点外,µC/OS-II它具有别的操作系统没有的优点,具体如下:
(1)源代码开放:µC/OS-II的源代码可以免费获取,且标有清晰的注释,可读性好。
(2)可移植性好:µC/OS-II的源代码90%以上是用C语言编写的,可以很容易地把它移植到各类8位、16位和32位处理器上。
(3)稳定性高:µC/OS-II已得到FAA的标准认证,且目前已有上百个商业应用实例,其稳定性和可靠性是经过实践验证的。
因此,µC/OS-II广泛的应用于控制系统中,如在衍射仪高压控制系统中使用µC/OS-II操作系统是一种很好的选择。
控制系统是一个复杂的系统,它需要多个系统协同工作。
传统的系统开发我们往往使用前后台的方式,但是这种开发方式在任务较简单的开发中比较适用,对于任务比较复杂的系统往往力不从心。
对于任务较多而且复杂的情况我们就要引入实时操作系统RTOS。
RTOS体现了一种新的应用程序设计思想和开放的框架,用户在编写程序时,可以分别编写各个任务,不必同时将所有任务运行的各种可能情况记在心中,大大减小了程序编写的工作量,而且减小了出错的可能,保证最终程序具有高可靠性,从而降低程序的复杂度和开发周期。
由于控制系统功能较复杂,诸多的功能可以划分成许多不同的模块,模块之间既彼此联系又相对独立,可以当作不同的任务来进行处理。
所以,使用实时操作系统,将不同的功能划分成不同的任务进行处理使得设计大大简化。
1.2 国内外研究状况综述
嵌入式系统是继IT网络技术之后,又一个新的技术发展方向。
中国单片机二十年论坛总结出,我国嵌入式起步较早,但总体来说发展缓慢,和国外的开发应用具有很大的差距,造成这一局面的原因是多方面的。
在国内嵌入式系统开发方面,多是一些低层次的应用,停留在以前老的技术基础之上。
例如,经典51系列单片机在上世纪我国的工业信息化改造过程中发挥了重要的作用,渗透到生产生活的各个方面。
与此同时在大学电类相关的工科单片机教学中,依然是经典的51,微机原理依然是8086/88,这显然体现不了最新的技术特征,造成了大学教育与实际社会需要的脱节。
国外的大部分高校和国内的极少数大学相继开设嵌入式微处理器设计等相关的前沿性的课程,可见基于STM32技术将是未来微控制开发的主流方向。
由于µC/OS-II系统具有体积小、性能强、功耗低、可靠性高以及面向
行业应用的突出特征,目前已经被广泛的应用于军事国防、消费电子、网络通信、工业控制等各个领域。
今天嵌入式系统带来的工业年产值已超过了1万亿美元,1997年来自美国嵌入式系统大会(Embedded System Conference)的报告指出,未来5年仅基于嵌入式计算机系统的全数字电视产品,就将在美国产生一个每年1500亿美元的新市场。
美国汽车大王福特公司的高级经理也曾宣称,“福特出售的‘计算能力’已超过了IBM”,由此可以想见嵌入式计算机工业的规模和广度。
1998年11月在美国加州举行的嵌入式系统大会上,基于RTOS的Embedded Internet成为一个技术新热点。
在国内,“维纳斯计划”和“女娲计划”一度闹得沸沸扬扬,机顶盒、信息加电这两年更成了IT热点,而实际上这些都是嵌入式系统在特定环境下的一个特定应用。
据调查,目前国际上已有两百多种嵌入式操作系统,而各种各样的开发工具、应用于嵌入式开发的仪器设备更是不可胜数。
在国内,虽然嵌入式应用、开发很广,但该领域却几乎还是空白,只有三两家公司和极少数人员在从事这方面工作。
由此可见,嵌入式系统技术发展的空间真是无比广大。
1.3 研究的主要内容
本文是在基于32位的ARM微处理器STM32和嵌入式实时操作系统µC/OS-II上进行嵌入式操作系统的移植和功能实现。
通过将嵌入式实时操作系统µC/OS-II移植到STM32微处理器上,并对其进行软件功能的扩展和硬件扩展,实现了一个基本完整的嵌入式实时操作系统。
建立了基于嵌入式ARM处理器的应用软件体系;将µC/OS-II移植到STM32,建立了嵌入式操作系统研究及µC/OS-II下的开发环境体系。
包括µC/OS-II系统配置、µC/OS-II下的移植、启动、测试和功能实现等。
完成了基于STM32的µC/OS-II的应用设计。
本文主要分为4章,章节安排如下:
(1)绪论。
主要介绍了开题的背景和研究意义,以及µC/OS-II的国内外研究现状。
(2)µC/OS-II的理论介绍。
主要介绍µC/OS-II各模块的基本功能和在STM32上移植方法。
(3)硬件平台介绍及LCD屏程序设计及调试。
多任务的建立并实现基本功能。
(4)结语。
主要介绍本论文中的优点和不足之处。
2 µC/OS-II 的理论介绍
2.1 µC/OS-II 各模块的基本功能
2.1.1 µC/OS-II 内核结构
(1)µC/OS-II 是以源代码形式提供的实时操作系统内核,其包含的文件结构如图2.1所示:
基于µC/OS-II 操作系统进行应用时,设计时的主要任务是将系统合理划分成多个任务,并由RTOS 进行调度,任务之间使用µC/OS-II 提供的系统服务进行通
图2.1 µC/OS-II 内核结构
软
件 硬件
信,以配合实现应用系统的功能。
与前后台系统一样,基于µC/OS-II的多任务系统也有一个main主函数,main函数由编译器所带的C启动程序调用。
在main主函数中主要实现µC/OS-II的初始化OSInit()、任务创建、一些任务通信方法的创建、µC/OS-II的多任务启动OSStart()等常规操作。
另外,还有一些应用程序相关的初始化操作,例如:硬件初始化、数据结构初始化等。
(2)OSInit()初始化µC/OS-II所有的变量和数据结构,并建立空闲任务OS_TaskIdle(),这个任务总是处于就绪态。
2.1.2 µC/OS-II内核体系结构图
µC/OS-II内核主要对用户任务进行调度和管理,并为任务间共享资源提供服务。
包含的模块有任务管理、任务调度、任务间通信、时间管理、内核初始化等。
µC/OS-II内核体系结构如图2.2所示:
图2.2 内核结构图
2.1.3 任务状态及其转换关系
在多任务系统中,任务是设计者实现应用系统的基本形式,也是µC/OS-II系统进行调度的基本单元。
任务可以是一个无限的循环,也可以在一次执行后被操作系统删除。
任务函数和任何C函数一样,具有一个返回类型和一个参数,但是它决不返回。
任务控制块(TCB)是一个数据结构OS_TCB,一旦一个任务创建,就有一个和它关联的TCB被赋值。
当任务的CPU使用权被剥夺时,它用来保存该任务的状态。
这样,当任务重新获得CPU使用权时,可以从TCB中获取任务切换前的信息,准确的继续运行。
2.1.4 任务调度器
µC/OS-II总是运行进入就绪态的优先级最高的任务。
任务调度器的功能是:在就绪表中查找最高优先级的任务,然后进行必要的任务切换,运行该任务。
µC/OS-II的任务调度有两种情况:任务级的任务调度由OS_Sched()完成;中断级的任务调度由OSIntExt()完成。
这两种任务调度情况调用的任务切换函数不同:任务级的任务调度OS_Sched()调用了任务切换函数OS_TASK_SW(),而中断级的调度OSIntExt()调用了任务切换函数OSIntCtxSw()。
任务级的任务调度是由于有更高优先级的任务进入就绪态,当前的任务的CPU使用权被剥夺,发生了任务到任务的切换;中断级的调度是指当前运行的任务被中断打断,由于ISR运行过程中有更高优先级的任务被激活进入就绪态。
而中断返回前ISR调用OSIntExt()函数,该函数查找就绪表发现有必要进行任务切换,从而被中断的任务进入等待状态,运行被激活的高优先级的任务。
(1)任务切换
任务切换有两种:OS_TASK_SW()和OSIntCtxSw()。
任务级的任务切换OS_TASK_SW()是宏调用,通过软中断指令来实现CPU寄存器内容切换。
例如:#define OS_TASK_SW() asm(“int #32”)。
任务级的任务切换过程:①保存当前运行的任务的CPU寄存器值到该任务的堆栈。
如:堆栈指针,程序计数器,状态寄存器等。
②将要运行的高优先级的任务的寄存器值从堆栈恢复到CPU寄存器。
③进行TCB的切换,并运行任务。
中断级的任务切换OSIntCtxSw()是在OSIntExt()中调用的,我们一般在用户ISR中调用OSIntExt()以实现中断返回前的任务调度。
由于ISR已经将CPU寄存器的值存入被中断的任务的堆栈中,所以OSIntCtxSw()的实现和OS_TASK_SW()不一样,具体参见移植文档。
(2)就绪表
每个就绪的任务都放在就绪表中,就绪表有两个变量:OSRdyGrp和OSRdyTbl[]。
OSRdyGrp中,将任务按优先级分组,八个为一组。
OSRdyGrp的每一位代表每组任务是否有进入就绪态的任务。
在就绪表中查找优先级最高的任务不需要扫描整个OSRdyTbl[],只要查优先级判定表OSUnMapTbl[]。
OSUnMapTbl[]是常量表,所以查找优先级最高的任务的执行时间为常量,和就绪表的任务数无关。
2.1.5 中断服务
在用户的ISR中可以调用OSIntEnter()和OSIntExit()通知µC/OS-II发生了中断,这样可以实现ISR返回前的任务调度。
2.1.6 时钟节拍
µC/OS-II要求用户提供一个周期性的时钟源,来实现时间的延迟和超时功能,时钟节拍应该每秒发生10~100次/秒。
时钟节拍率越高,系统的额外负荷就
越重。
应该在多任务系统启动后,也就是调用OSStart()后再开启时钟节拍器。
系统设计者可以在第1个开始运行的任务中调用时钟节拍启动函数。
假设用定时器TA0作为时钟中断源,那么,在移植过程中实现了函数init_timer_ta0(),此函数用来初始化定时器TA0,并将其打开。
µC/OS-II中的时钟节拍服务是在ISR中调用OSTimeTick()实现的。
OSTimeTick()跟踪所有任务的定时器以及超时时限。
2.1.7 µC/OS-II的初始化和启动
调用µC/OS-II的服务之前要先调用系统初始化函数OSInit()。
OSInit()初始化µC/OS-II所有的变量和数据结构,并建立空闲任务。
µC/OS-II初始化任务控制块、事件控制块、消息队列缓冲、标志控制块等数据结构的空缓冲区。
多任务的启动是通过调用OSStart()实现的。
启动之前要至少创建一个任务。
OSStart()调用就绪任务启动函数OSStartHighRdy(),其功能是将任务栈的值恢复到CPU寄存器,并执行中断返回指令,强制执行该任务代码。
2.1.8 内存管理
在ANSI C中是使用malloc和free两个函数来动态分配和释放内存。
但在嵌入式实时系统中,多次这样的操作会导致内存碎片,且由于内存管理算法的原因,malloc和free的执行时间也是不确定。
µC/OS-II中把连续的大块内存按分区管理。
每个分区中包含整数个大小相同的内存块,但不同分区之间的内存块大小可以不同。
用户需要动态分配内存时,系统选择一个适当的分区,按块来分配内存。
释放内存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的。
2.1.9 任务管理
µC/OS-II中最多可以支持64个任务,分别对应优先级0~63,其中0为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
µC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整型变量做累加运算;另一个是统计任务,它的优先级为次低,该任务负责统计当前CPU的利用率。
2.1.10 µC/OS-II任务间通信方式
(1)信号量
信号量由两部分组成:一部分是16位的无符号整型信号量的计数值;另一部分是由等待该信号量的任务组成的等待任务表。
信号量用于对共享资源的访问,用钥匙符号,符号旁数字代表可用资源数,对于二值信号量该值为1。
信号量还可用于表示某事件的发生,用旗帜符号表示,符号旁数字代表事件已经发生的次数。
互斥型信号量用于处理共享资源。
(2)消息邮箱
一种通信机制,可以使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量,通常该指针指向一个包含了消息的特定数据结构。
(3)消息队列
另一种通信机制,允许一个任务或者中断服务子程序向另一个任务发送以指针方式定义的变量或其它任务,因具体应用不同,每个指针指向的包含了消息的数据结构的变量类型也有所不同。
2.2 STM32上移植方法
2.2.1 平台需求
µC/OS-II的正常运行需要处理器平台满足以下要求:
(1)处理器的C编译器能产生可重入代码。
(2)用C语言就可以打开和关闭中断。
(3)处理器支持中断,并且能产生定时中断(通常在10至100Hz之间)。
(4)处理器支持能够容纳一定量数据(可能是几千字节)的硬件堆栈。
(5)处理器有将堆栈指针和其它CPU寄存器读出和存储到堆栈或内存中的指令。
2.2.2 移植方法
(1)内核头文件(OS_CPU.H)
在OS_CP U.H 中,主要声明了一些与微处理器相关的常量、宏和typedef。
定义与处理器无关的数据类型
typede f unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char NT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int NT32S;
typedef float FP32;
typedef double FP64;
typedef unsigned int OS_STK;
typedef unsigned int OS_CPU_SR;
在STM32处理器及keil MDK 或者IAR 编译环境中可以通过查手册得知short类型是16位而int类型是32位,这对于Cortex-M3内核是一致的。
故这部分代码无需修改。
尽管µC/OS-II定义了float 类型和double 类型,但为了方便移植它们在µC/OS-II源代码中并未使用。
为了方便使用堆栈,µC/OS-II定义了一个堆栈数据类型。
在Cortex-M3 中寄存器为32位,故定义堆栈的长度也为32位。
Cortex-M3 状态寄存器为32位,定义OS_CPU_SR主要是为了在进出临界代码段
保存状态寄存器。
(2)临界代码段
µC/OS-II为了保证某段代码的完整执行,需要临时的关闭中断,在这
段代码执行完成之后再打开中断。
这样的代码段称作临界代码段。
µC/OS-II通过定义两个宏OS_ENTER_CRITICAL() 和OS_EXIT_CRITICAL() 来分别实现中断的关闭和打开。
一般来说,采用方法3来实现这两个宏。
这两个宏分别定义如下:#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);}
函数OS_CPU_SR_Save()和OS_CPU_SR_Restore(cpu_sr)在OS_CPU_A.ASM 中定义。
同时得注意,在使用这两个宏之前,必须定义OS_CPU_SR cpu_sr;否则编译时将出错。
(3)栈的增长方向
尽管µC/OS-II支持两种方向生长的栈,但对于以Cortex-M3为内核的STM32 微处理器来说,它支持向下增长的满栈,故需要定义栈增长方向宏为1。
即定义成如下形式
#define OS_STK_GROWTH 1
(4)任务级任务切换
任务级任务切换调用宏OS_TASK_SW()来实现。
因为这个宏也是与处理器相关的,因此这个宏在OS_CPU_A.ASM中描述。
(5)其他函数声明
在OS_ CPU.H中,还声明了以下几个函数,这几个函数均在OS_CPU_A.ASM 中实现。
void OSCtxSw(void);
void OSIntCtxSw(void);
void OSStartHighRdy(void);
void OS_CPU_PendSVHandler(void);
(6)与处理器相关的汇编代码(OS_CPU_A.ASM)
在OS_CP U_A.ASM中实现的是下面五个与处理器相关的函数。
OS_CPU_SR_Save();
OS_CPU_SR_Restore();
OSStartHighRdy();
OSCtxSw();
OSIntCtxSw();
2.3.3 函数实现
(1)关中断函数(OS_CPU_SR_Save())
即先保存当前的状态寄存器然后关中断。
故关中断实现代码如下
OS_CPU_SR_Save
MRS R0, PRIMASK;
CPSID I
BX LR
这也是宏OS_ENTER_CRITICAL() 的最终实现。
(2)恢复中断函数(OS_CPU_SR_Restore())
这是宏OS_EXIT_CRITICAL()的最终实现。
也就是将状态寄存器的内容从R0中恢复,然后跳转回去。
此函数完成的将中断状态恢复到关中断前的状态。
其代码如下:
OS_CPU_SR_Restore
MSR PRIMASK, R0
BX LR
Cortex-M3处理器有单独的指令来打开或者关闭中断,所以这两个函数实现起来很简单。
(3)启动最高优先级任务运行(OSStartHighRdy())
OSStart()调用OSStartHighRdy()来启动最高优先级任务的运行,从而启动整个系统。
OSStartHighRdy()主要完成以下几项工作:
①为任务切换设置PendSV的优先级;
②为第一次任务切换设置栈指针为0;
③设置OSRunning = TRUE,以表明系统正在运行;
④触发一次PendSV,打开中断等待第一次任务的切换。
(4)任务级和中断级任务切换
因为Cortex-M3进入异常自动保存寄存器R3-R0,R12,LR,PC和xPSR这种的特殊机制,这两个函数都是触发一次PendSV来实现任务的切换。
首先是微处理器自动保存上面提到的寄存器,然后把当前的堆栈指针保存到任务的栈中,将要切换的任务的优先级和任务控制块的指针赋值给运行时的最高优先级指针和运行时的任务控制块指针,最后再把要运行的任务的堆栈指针赋值给微处理器的堆栈指针,这样就可以退出中断服务程序了。
中断服务程序退出的时候将自动出栈R3-R0,R12,LR,PC和xPSR。
具体的PendSV服务程序的伪代码如下:OS_CPU_PendSVHandler :
// 进入异常,处理器自动保存R3-R0,R12,LR,PC和xPSR
if (PSP != NULL) //判断不是开始第一次任务
{
保存R4-R11到任务的堆栈;
OSTCBCur->OSTCBStkPtr = SP; //保存堆栈的指针到任务控制块
}
OSTaskSwHook(); //实现用户扩展功能而定义的钩子
OSPrioCur = OSPrioHighRdy; //设置运行任务为最高优先级就绪任务
OSTCBCur = OSTCBHighRdy; // 设置运行的任务控制块为最高
//就绪任控制块务
PSP = OSTCBHighRdy->OSTCBStkPtr;//将要切换的任务堆栈指
// 针赋给微处理器的堆栈指
// 针从而实现切换
从堆栈中恢复R4-R11; 从异常中返回;
// 退出异常,处理器自动恢复R3-R0,R12,LR,PC和xPSR
这样很容易写出PendSV中断服务程序的代码了。
(5)与CPU 相关的C 函数和钩子函数(OS_CPU_C.C )
这个文件中包含10个函数,具体如下:
OSInitHookBegin ();
OSInitHookEnd ();
OSTaskCreateHook ();
OSTaskDelHook ();
OSTaskIdleHook ();
OSTaskStatHook ();
OSTaskStkInit ();
OSTaskSwHook ();
OSTCBInitHook ();
OSTimeTickHook ();
这10个函数有9个是为了扩展用户功能而定义的钩子函数,这些钩子函数可以都为空函数,也可以加上一些用户需要的扩展功能。
另外一个不是钩子函数,它是OSTaskStkInit()。
这个函数的功能是当一个任务被创建时,它完成这个任务堆栈的初始化。
这个函数首先将用户为任务分配的堆栈顶地址赋值给一个栈指针变量,然后再通过这个栈指针向任务的栈空间写入初值。
这个初值无关紧要,为0就可以了。
这个函数的代码时下如下:
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *p_arg,
OS_STK *ptos, INT16U opt)
{
OS_STK *stk;
(void)opt; //防止编译器报错
stk = ptos; // 将栈顶地址赋值给栈指针变量
// 以进入异常的顺序来给栈赋初值
*(stk) = (INT32U)0x00000000L; //xPSR
*(--stk) = (INT32U)task; //Entry Point
*(--stk) = (INT32U)0x00000000L; // R14 (LR)
*(--stk) = (INT32U)0x00000000L; //R12
*(--stk) = (INT32U)0x00000000L; //R3
*(--stk) = (INT32U)0x00000000L; // R2
*(--stk) = (INT32U)0x00000000L; // R1
*(--stk) = (INT32U)p_arg; //R0 : 传递的参数
// 剩下的寄存器初始化
*(--stk) = (INT32U)0x00000000L; // R11
*(--stk) = (INT32U)0x00000000L; //R10
*(--stk) = (INT32U)0x00000000L; // R9
*(--stk) = (INT32U)0x00000000L; //R8
*(--stk) = (INT32U)0x00000000L; //R7
*(--stk) = (INT32U)0x00000000L; // R6
*(--stk) = (INT32U)0x00000000L; // R5
*(--stk) = (INT32U)0x00000000L; // R4
return (stk);
}
其他的钩子函数都为空函数。
这样,整个移植的代码就介绍完了。
整个移植的过程非常容易。
剩下的工作就是编写用户任务,并在开发板上验证,以此来验证该移植方案是可行的和成功的。
3 LCD屏程序设计及调试
3.1 工具概述
RVMDK源自德国的KEIL公司,是RealView MDK的简称。
RealView MDK 集成了业内最领先的技术,支持ARM7、ARM9和Cortex-M3核处理器,自动配置启动代码,集成Flash烧写模块,强大的Simulation设备模块,性能分析等功能。
3.1.1 keil4工程建立以及仿真方法
(1)新建工程。
打开MDK软件,选择Project→New uVision Project菜单项,新建一个文件夹名为“毕业设计”,保存,则弹出器件选择对话框,这里选择STM32F103RB。
单击“OK”按钮,则弹出一个对话框加载启动文件到工程中。
打开“毕业设计”文件夹,在里面添加子文件夹
(2)添加系统文件与工程管理。
回到“毕业设计”文件夹中,把系统SYSTEM文件夹(delay,sys,usart文件夹)复制过来,再建立main和hardware文件夹用于主函数和各外设资源函数。
回到工程中,点击manage components,添加工程中的文件,进行分类管理工程。
(3)最后新建 main文件,在编辑区写代码。
3.1.2 硬件平台绍
ALIENTEK MiniSTM32选择的是STM32F103RBT6 作为MCU,STM32F103的型号众多,作为一款低端开发板,选择STM32F103RBT6是最佳的选择。
128K FLASH、20K SRAM、2个SPI、3个串口、1个USB 、1个CAN、2个12位的ADC、RTC、51个可用IO脚···,这样的配置无论放到那里都是很不错的了,更重要的是其价格,18元左右的零售价,相对其他芯片配置及价格,所以我们选择了它作为我们的主芯片。
BOOT1用于设置STM32的启动方式,其对应启动模式如表3.1所示:
表3.1 BOOT0、BOOT1启动模式表
为1,BOOT1为0,而如果想让STM32一按复位键就开始跑代码,则需要配置BOOT0为0,BOOT1随便设置都可以。
ALIENTEK这款开发板专门设计了一键下载电路,通过串口的DTR和RTS信号,来自动配置BOOT0和BOOT1,因此不需要用户来手动切换他们的状态,直接串口下载和软件自动控制,可以非常
方便的下载代码。
P3和P1分别用于PORTA和PORTB的IO口引出,其中P2还有部分用于PORTC口的引出。
PORTA和PORTB都是按顺序排列的,这样设计的目的是为了让大家更方便地与外部设备连接。
P2连接了DS18B20的数据口以及红外传感器的数据线,它们分别对应着PA0和PA1,只需要19通过跳线帽将P2和P3连接起来就可以使用了。
这里不直接连在一起的原因有二:1,防止红外传感器和DS18B20 对这两个IO口作为其他功能使用的时候的影响;2,DS18B20 和红外传感器还可以用来给其他板子提供输入,等于我们的板子为别的板子提供了红外接口和温度传感器,在调试的时候,还是蛮有用的。
P4口连接了PL2303的串口输出,对应着STM32的串口1(PA9/PA10),在使用的时候,也是通过跳线帽将这两处连接起来。
这样设计有2个好处:1,使得PA9和PA10用作其他用途。
使用的时候,不受到PL2303的影响。
2,USB 转串口可以用作他用,并不仅限在这个板上的STM32使用,也可以连接到其他板子上,这样ALIENEK MiniSTM32 就相当于一个USB 串口。
P5口是另外一个IO引出排阵,将PORTC 和PORTD等的剩余IO口从这里引出。
在此部分原理图中,我们还可以看到STM32F103RBT6 的各个IO口与外设的连接关系,这些将在后面给大家介绍。
这里STM32的VBAT 采用CR1220 纽扣电池和VCC3.3混合供电的方式,在有外部电源(VCC3.3)的时候,CR1220不给VBAT供电,而在外部电源断开的时候,则由CR1220给VBAT供电。
这样,VBAT总是有电的,以保证RTC的走时以及后备寄存器的内容不丢失。
3.2 硬件结构
3.2.1 STM32最小系统
STM32F103最小系统包括电源电路,复位电路,时钟电路,主芯片和下载接口。
STM32F103使用3.3V供电,且引脚接有滤波电容,保证芯片工作稳定;复位电路使用的低电平复位,该电路上电可以复位,按键按下时也可以复位;时钟电路使用8MH Z晶振,和22pF电容助振。