嵌入式课程设计-嵌入式操作系统µCOS在M16C62芯片上的移植_第1页
嵌入式课程设计-嵌入式操作系统µCOS在M16C62芯片上的移植_第2页
嵌入式课程设计-嵌入式操作系统µCOS在M16C62芯片上的移植_第3页
嵌入式课程设计-嵌入式操作系统µCOS在M16C62芯片上的移植_第4页
嵌入式课程设计-嵌入式操作系统µCOS在M16C62芯片上的移植_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式操作系统µCOS在M16C62芯片上的移植嵌入式操作系统µCOS在M16C62芯片上的移植全套源程序代码加扣 3346389411或3012250582姓名: 学号: 同组: 班级: 自动化1006班 指导老师: 完成时间: 2013年12月7日 2013年12月9日目录目录2第一篇实验报告3一、前言3二、移植细节31.对硬件平台的认识32.uC/OS-II的移植4三、多任务系统设计91. M16C62单片机资源分配92. 多任务设计10四、结束语24五、参考文献24第二篇调试记录25一、了解芯片资料和编译器原理25二、调试过程281.验证OSTaskStkInit(

2、) 和 OSStartHighRdy()282.验证OSCtxSw()323.验证OSIntCtxSw() 和 OSTickISR()33三、加入应用程序34第三篇附录34一、对应启动代码341.sect30.inc352.ncrt0.a30,36二、对应的移植代码381.OS-CPU-A.a30382.OS_CPU_C.C41第一篇实验报告嵌入式操作系统µC/OS在M16C/62芯片上的移植摘要:C/OS-是一个源码公开的实时嵌入式操作系统,它的特点在于公开的源代码,很强的移植性,占先式多任务,每个任务有单独的栈,中断管理及很强的稳定性与可靠性等,目前越来越受到实时嵌入式系统设计者

3、的关注,本文详细讲述了如何把uC/OS-II操作系统移植到M16C62单片机中,并给出了以M16C62单片机为核心处理器构成的一个实时多任务系统的设计方案。关键词:嵌入式操作系统、 uC/OS-II、  M16C62 单片机、 实时、 多任务一、 前言    随着微电子技术和网络的发展,人们对网络的认识日益深入。网络终端产品也越来越受到人们的关注,嵌入式操作系统的应用也得到了前所未有的发展,人们对嵌入式的研究也有了长足的进步。基于某个操作系统的实时、多任务系统的设计合应用成为单片机应用的新的发展

4、趋势。uC/OS是一个公开源代码的嵌入式操作系统,uC/OS-II是由uC/OS V1.1版升级而来,在原来版本的基础上,uC/OS-II有了许多新功能,如:内存管理;在任务建立、删除、任务切换、时钟节拍切换处理过程中,允许用户调用自定义的函数;支持任务控制块(TCB)功能扩展;能效验各堆栈使用情况;以及其它一些新功能。M16C62单片机是三菱公司在90年代末推出的新一代16位单片机,是目前应用最广泛的16位单片机之一。M16C族单片机融合了基于寄存器和基于存储器型两种结构的优点,从而能够实现类似RISC的高速处理性能。M16C62单片机具有超低功耗、极强的抗干扰能力和很高的C语言编

5、程效率等特点,片内集成了10位A/D转换器、DMA控制器、异步通信通道、定时器等丰富的周边功能电路模块,非常适合应用在小型实时、多任务、嵌入式系统中。把uC/OS-II移植到M16C62单片机中,就可以构成一个实时多任务应用系统。下面就来谈谈如何把uC/OS-II移植到M16C62单片机中,并以此设计一个实时多任务系统。二、 移植细节1. 对硬件平台的认识硬件基础:M16C62 单片机瑞萨芯片型号:M30620FCAFPIDE: TM (Tool Manager)Debugger: KD30Compiler: NC30WA V 4.00 R2闪存ROM写入工具:FlashstartM

6、16C/62 ROM: Flash Memory Version: 128Kb RAM: 10Kb晶振:16M电源:5V 5mA图2.1.1 M16C Registers图2.1.2 M16C Flag Register2. uC/OS-II的移植    uC/OS-II采用完全占先式的实时内核,最多可以管理56个任务,每个任务对应一个不同的优先级,因而,uC/OS-II操作系统并不支持时间片轮转调度法。但是全部UC/OS-II的函数调用与服务的执行时间是可知的,也就是,uC/OS-II系统服务的执行时间不依赖于应用程序任务的多少。另外,uC/OS-II

7、中每个任务都有自己单独的栈,每个栈的大小可以根据应用程序的需要进行分配,这样压低了系统对RAM的需求;在中断管理方面,uC/OS-II中的中断可以使正在执行的任务挂起,如果优先级更高的任务被中断唤醒,则高优先级的任务在中断嵌套全部退出后立即执行,uC/OS-II的中断嵌套可达255层。uC/OS-II的源码大部分是用可移植性很强的ANSI C 写的。只是和微处理器有关的很小一部分代码是用汇编写的,这样把uC/OS-II移植到MC16C62中就变得相对容易很多,主要是要修改和处理器有关的代码,如:OS-CPU.H、OS-CPU-A.ASM(OS_CPU_A.A30)、OS-C

8、PU-C.C。2.1 OS-CPU.H头文件OS_CPU.H头文件主要是定义和处理器有关的数据类型,在M16C62中的数据类型包括无符号整型、有符号整型、无符号字符型、有符号字符型等。因此,OS_CPU.H头文件对这些类型进行全新的定义。除了和处理器有关的数据类型定义外,在OS-CPU.H中还作了有关中断禁止、中断允许、堆栈的增长方向等一些简单宏的定义。2.1.1 数据类型 typedef unsigned char BOOLEAN;typedef unsigned char INT8U; /* Unsigned 8 bit quantity */typedef signed char INT

9、8S; /* Signed 8 bit quantity */typedef unsigned int INT16U; /* Unsigned 16 bit quantity */typedef signed int INT16S; /* Signed 16 bit quantity */typedef unsigned long INT32U; /* Unsigned 32 bit quantity */typedef signed long INT32S; /* Signed 32 bit quantity */typedef float FP32; /* Single precision

10、 floating point */typedef double FP64; /* Double precision floating point */typedef unsigned char OS_STK; /* Each stack entry is 16-bit wide */typedef INT16U OS_CPU_SR; /* Type of CPU status register */2.1.2 进出临界段代码#define OS_CRITICAL_METHOD 2#if OS_CRITICAL_METHOD = 1#define OS_ENTER_CRITICAL() _as

11、m("FCLR I") /* Disable interrupts*/#define OS_EXIT_CRITICAL() _asm("FSET I") /* Enable interrupts */#endif#if OS_CRITICAL_METHOD = 2#define OS_ENTER_CRITICAL() _asm("PUSHC FLG"); _asm("FCLR I") /* Disable interrupts*/#define OS_EXIT_CRITICAL() _asm("POPC

12、FLG")/* Enable interrupts*/#endif#if OS_CRITICAL_METHOD = 3#define OS_ENTER_CRITICAL() _asm("STC FLG, $", cpu_sr);_asm("FCLR I") /* Disable interrupts*/#define OS_EXIT_CRITICAL() _asm("LDC $, FLG", cpu_sr)/*Enable interrupts */#endif2.1.3 堆栈增长方向 #define OS_STK_GROW

13、TH 1 /* Stack grows from HIGH to LOW memory */2.1.4 任务级切换#define OS_TASK_SW() _asm("INT #32") /* Mapped to the software interrupt 0 */2.1.5 函数原型声明void OSCtxSw (void);void OSIntCtxSw (void);void OSStartHighRdy (void);void OSTickISR (void);2.2 OS-CPU-A.a30文件    在OS-CPU-A.

14、a30文件中包含四个汇编语言的函数:OSStartHighRdy()、OSCtxsw()、OSIntCtxsw()、OSTickISR()。在uC/OS-II中处于就绪态的任务的堆栈结构,看起来和刚中断的情形是一样的。要想运行最高优先级任务,移植要做的是就是将所有处理器的寄存器按顺序从任务堆栈中恢复出来,并且通过一条中断返回语句来实现任务的切换。因而,OSStartHighRdy()就是使要恢复的任务堆栈指针指到任务控制块的0偏址的内存单元中。也就是要把保存在任务堆栈中的数据以及CPU寄存器,如R0、R1、R2、R3、A0、A1、SB和FB返回到系统当前的寄存器中,并把当前堆栈指针指到PC指针

15、的位置。    在uC/OS-II中任务的切换问题是通过发软件中断命令或依靠处理器执行陷阱指令来完成的。但是中断服务例程、陷阱或异常处理例程的向量地址必须指向OSCtxSw()。在M16C62单片机中可以通过定义软件中断0来完成任务的切换。因而,在M16C62中的中断向量表中的32号软件中断地址指向OSCtxSW()。对应的中断号为32。    OSInCtxSw()用来在ISR中执行切换功能。由于这个函数本身就是在中断中被调用,因而,在中断处理时寄存器的状态已经都被正确保存了。在OSInCtxSw()函数中要进行

16、堆栈清理工作,只有这样被中断的任务的堆栈内容才能正确返回。OSTickISR()这个函数是UC/OS-II所要求的时钟基准,即时钟节拍,uC/OS-II的时钟节拍频率在10到100之间,通常为了计算方便而设为整数。在M16C62中有多个定时计数器可以选择用来作为系统的时钟基准。在该系统中利用时钟定时器A0来产生频率为10的一个时钟节拍。OSTickISR()是一个中断响应函数,因而必须在M16C62的中断向量表中,A0的中断向量应分配给OSTickISR(),对应的中断向量号是21。该文件核心代码见附录部分。2.3 OS_CPU_C.C文件 在这个C文件中包含6个简单的C函数,而这6

17、个函数中和移植关系最密切的OSTaskInit()函数,这个函数是用来创建一个任务堆栈。OSTaskCreat()和OSTaskExt()就是通过调用这个函数来初始化任务的堆栈结构的,由此看来,OSTaskInit()是移植的关键。在前面的OS_CPU_A.a30文件中,任务的切换是通过调用一个软中断32来实现任务切换,通过中断的返回指令使堆栈中的数据返回到CPU寄存器,使最高优先级的任务占有CPU,因而,OSTaskInit()函数要做的就是模拟中断发生时处理器压栈的过程,把CPU的寄存器内容压到任务堆栈中。在M16C62单片机中,系统分为两个堆栈,即:用户堆栈和中断堆栈,而在uC/OS-I

18、I进行任务切换是通过软中断32来实现的,因此,uC/OS-II的任务堆栈是M16C62中的中断堆栈。在M16C62中,响应中断后堆栈的状态如图(一)所示:图(一):响应中断后的堆栈状态 中断堆栈中依次保存程序计数器PC和标志寄存器FLG中的内容,因此,在OSTaskStkInit()函数中就是要模拟这样的一个压栈过程。先压入FLAG的高四位和PC指针的高四位,接着压入FLAG低位、PC中间八位和PC的低八位。在保存完PC和FLAG位后就应该为CPU的寄存器FB、SB、A1、A0、R3、R2、R1和R0分配相应存储空间。OSTaskInit()函数返回的是任务堆栈的指针。该文件核心代码

19、见附录部分。2.4 M16C/62系列芯片中断机制分析图2.4.1:固定中断向量表图2.4.2 浮动中断向量表2.4.1 定义固定中断向量表42.org0fffdchUDI:.lworddummy_intOVER_FLOW:.lworddummy_intBRKI:.lworddummy_intADDRESS_MATCH:.lworddummy_intSINGLE_STEP:.lworddummy_intWDT:.lworddummy_intDBC:.lworddummy_intNMI:.lworddummy_intRESET:.lwordstart2.4.2 定义浮动中断向量表.section

20、vector; variable vector VECTOR_ADR .lworddummy_int ; vector 0 (BRK).org(VECTOR_ADR +44).lworddummy_int; DMA0 (for user).lworddummy_int ; DMA1 2 (for user).lworddummy_int; input key (for user).lworddummy_int; AD Convert (for user).org(VECTOR_ADR +68).lworddummy_int;uart0 trance (for user).lw

21、orddummy_int;uart0 receive (for user).lword000fcb6bh; uart1 trance (for user).lword000fcb6bh; uart1 receive (for user).GLB _OSTickISR.lword_OSTickISR; TIMER A0 (for user).lworddummy_int; TIMER A1 (for user).lworddummy_int; TIMER A2 (for user).lworddummy_int; TIMER A3 (for user).lword dummy_int; TIME

22、R A4 (for user) (vector 25).lworddummy_int; TIMER B0 (for user) (vector 26).lworddummy_int; TIMER B1 (for user) (vector 27).lworddummy_int; TIMER B2 (for user) (vector 28).glb _int0.lword_int0 ; INT0 (for user) (vector 29).glb _int1.lword_int1 ; INT1 (for user) (vector 30).lworddummy_int; INT2 (for

23、user) (vector 31).GLB _OSCtxSw .lword_OSCtxSw ; vector 32 (for user or MR30).lworddummy_int; vector 33 (for user or MR30).lworddummy_int; vector 34 (for user or MR30).lworddummy_int; vector 35 (for user or MR30).lworddummy_int; vector 36 (for user or MR30).lworddummy_int; vector 37 (for user or MR30

24、).lworddummy_int; vector 38 (for user or MR30).lworddummy_int; vector 39 (for user or MR30).lworddummy_int; vector 40 (for user or MR30).lworddummy_int; vector 41 (for user or MR30).lworddummy_int; vector 42 (for user or MR30).lworddummy_int; vector 43 (for user or MR30).lword dummy_int; vector 44 (

25、for user or MR30).lworddummy_int; vector 45 (for user or MR30).lworddummy_int; vector 46 (for user or MR30).lworddummy_int ; vector 47 (for user or MR30)嵌入式操作系统µCOS在M16C62芯片上的移植三、 多任务系统设计1. M16C62单片机资源分配M16C62单片机是一个16位单片机,线性寻址空间是1M,但片内的RAM大小只有3Kbyte,因此要使多任务系统能正常稳定地工作必须合理分配资源。uC/OS-II中所有内核代码必须在R

26、AM区而把系统堆栈区划块到3K RAM 区外。通过对Ncrt0.a30和Sect30.inc这两个M16C62配置文件,可以完成对单片机的资源划分。NC30编译器一开始就会编译Ncrt0.a30和Sect30.inc这两个文件,完成对CPU的初始化,和资源分配,主要包括:存储器空间、RAM区分配、中断向量分配、堆栈区划分等。2. 多任务设计2.1. 选题说明本次课设我们选择自定义题目,完成的功能有:1. LCD 显示字符与LED 流水灯并行执行,KEY控制 LED 流水模式切换;2. KEY 控制 LCD,显示、切换、清屏等;3. LCD 显示图形动画。2.2. 任务分配此

27、次课设,我们小组由两个同学共同完成,其中陈志鹏同学由于考研复习紧张,故酌情给其分配的任务。具体分配如下:陈志鹏:1、LCD 显示字符与LED 流水灯并行执行,KEY控制 LED 流水模式切换;龚 捷:1、uCos操作系统移植;2、KEY 控制 LCD,显示、切换、清屏等;3.、 LCD 显示图形动画。2.3. 文件结构2.4. 功能描述本工程采用三任务并行运行,分别是:LCD显示任务、LED流水任务、检测Key状态任务。工程可分为两个模块描述,分别为自动运行和手动控制。其中,自动运行模块实现了LCD动画和LED流水灯并行运行效果。手动控制模块实现按键控制LCD动画行进与LED流水进度。由于开发

28、板只有4个按键,远远满足不了设计需求,故采用了按键复用的方案,最终实现多个功能。下面对各按键分配进行描述:1、 自动循环说明:默认情况Key1:切换循环模式,左循环或者右循环;Key2:切换LED流水灯流水方向,向左或向右;Key3:切换LCD显示内容,图片或汉字;Key4:暂停运行,此时LCD暂停动画、LED全灭。2、 手动控制说明:按下Key4,暂停运行,即切换为手控模式。Key1:LCD清屏,并切换为作者信息内容页,LED全亮;Key2:LCD图像右移,LED向右流水。若为清屏状态,则恢复手控模式;Key3:LCD图像左移,LED向左流水。若为清屏状态,则恢复手控模式;Key4:恢复自动

29、循环模式,注意清屏状态下不可切换。说明:由于所谓的多任务其实本质上一次只能执行一个任务,只不过任务切换的时间相当短,给人的感觉是执行多个任务。基于此原因,某些现象存在一定的延迟,具体表现比如:1、汉字显示完一行后,再按Key,方能响应;2、Led灯灭时,再按Key,方能响应;3、切换循环模式时,等待一定时间,方能看到效果;4、清屏后,等待一段时间再切换为其它模式; 2.5. 代码实现1、 main.c-/* * Project: KeyCtrLcdLed * Filename: main.c * Description TODO工程入口函数 * Author:Jairkung * Creati

30、on_Time: 2013-12-06 * Copyright: Copyright (C)2013 Jairkung.All Rights Reserved. * * Modification History * Modified_By:Jairkung * Modification_Time: 2013-12-07 * Version:2.0 */#include "includes.h"#include "LoadLcd.h"#include "LoadLed.h"#include "KeyListener.h&quo

31、t;/*-任务堆栈大小-*/#define TASK_STK_SIZE 100/*-任务堆栈-*/OS_STK TaskLedStkTASK_STK_SIZE;OS_STK TaskLcdStkTASK_STK_SIZE;OS_STK TaskKeyStkTASK_STK_SIZE;/* * Name: main * Description:主函数 * Param: void * return: void*/void main(void)/*-硬件初始化-*/ hardware_init();/*-uCOS初始化-*/OSInit(); /*-uCOS创建任务-*/OSTaskCreate(L

32、oadLcd,NULL,&TaskLcdStkTASK_STK_SIZE-1,3);OSTaskCreate(LoadLed,NULL,&TaskLedStkTASK_STK_SIZE-1,4); OSTaskCreate(KeyListener,NULL,&TaskKeyStkTASK_STK_SIZE-1,5);/*-uCOS任务运行-*/OSStart();2、 LoadLcd.c-/* * Project: KeyCtrLcdLed * Filename: LoadLcd.c * Description TODO装载LCD * Author:Jairkung *

33、 Creation_Time: 2013-12-06 * Copyright: Copyright (C)2013 Jairkung.All Rights Reserved. * * Modification History * Modified_By:Jairkung * Modification_Time: 2013-12-07 * Version:2.0 */#include "includes.h"#include "board.h"#include "lcd.h"#include "LoadLcd.h"#

34、include "LcdLed.h"static unsigned char mLcdContent=LCD_CONTENT_MAP;static unsigned char mCircleMode=LCD_LED_CIRCLE_RIGHT;static signed char mOffset = -1;/* * Name: LoadLcd * Description:装载LCD内容,死循环执行动画过程 * Param: * return: void*/void LoadLcd( void *pdata )INT8U time=0;byte i, j;byte k,l;Bo

35、ardInitial(); showOne(7, 0);OSTimeDlyHMSM(0, 0, 1, 0);while(1)switch(getLcdLedState()case LCD_LED_STATE_PAUSE:/暂停、手动控制动画/key1:显示作者if(mOffset = 7)showOne(mOffset, 300);OSTimeDlyHMSM(0, 0, 0, 500);/key2:右移 key3:左移elseshowOne(mOffset, 0);OSTimeDlyHMSM(0, 0, 0, 150);break;case LCD_LED_STATE_RUN:/自动循环切换图

36、片,显示动画showContent(150);break;case LCD_LED_STATE_RESET:break;default:break;/* * Name: showOne * Description:LCD全屏显示一张图片,从PIXEL_BMP数组中加载点阵数据 * Param: unsigned char num :图片标号 *int delay:1/6屏幕刷频延时 * return: void*/void showOne(unsigned char num, int delay)if(num>=0&&num<8)LcdInit( );ClearBu

37、ffer( );CacheFullScr(num);CommitBuffer(delay);/* * Name: activeLcdOffset * Description:根据key2、key3状态更新图片动画偏移地址 * Param: signed char flag:循环模式标记 * return: void*/void activeLcdOffset(signed char flag )if(flag > 0)mOffset+;if(mOffset > 6)mOffset=0;else if(flag < 0)mOffset-;if(mOffset < 0)mO

38、ffset=6;elsemOffset=7;/* * Name: showContent * Description:LCD显示内容 * Param: int frequence:动画帧更新周期 * return: void*/void showContent(int frequence)byte l,k;switch(getLcdContent()case LCD_CONTENT_HZ:ClearBuffer();CommitBuffer(0);if(getLcdContent()!=LCD_CONTENT_HZ)|(getLcdLedState()!=LCD_LED_STATE_RUN)

39、break;for( k = 0; k < 4; k+ )if(getLcdContent()!=LCD_CONTENT_HZ)|(getLcdLedState()!=LCD_LED_STATE_RUN) break;for( l = 0; l < 6; l+ )if(getLcdContent()!=LCD_CONTENT_HZ)|(getLcdLedState()!=LCD_LED_STATE_RUN) break;BufferPixelStuff( 3, 2 + k * 6 + l, l * 12, k * 12, 12, 12);CommitBuffer(0);LcdIni

40、t();OSTimeDlyHMSM(0, 0, 0, 10);OSTimeDlyHMSM(0, 0, 0, frequence);break;case LCD_CONTENT_MAP:if(getLcdContent()!=LCD_CONTENT_MAP)|(getLcdLedState()!=LCD_LED_STATE_RUN) break;switch(getLcdCircle()case LCD_LED_CIRCLE_RIGHT:if(getLcdCircle()!=LCD_LED_CIRCLE_RIGHT) break;for( l = 0; l < 7; l+ ) if(get

41、LcdCircle()!=LCD_LED_CIRCLE_RIGHT)|(getLcdContent()!=LCD_CONTENT_MAP)|(getLcdLedState()!=LCD_LED_STATE_RUN) break;CacheFullScr(l);CommitBuffer(0);OSTimeDlyHMSM(0, 0, 0, frequence);LcdInit( );break;case LCD_LED_CIRCLE_LEFT:if(getLcdCircle()!=LCD_LED_CIRCLE_LEFT) break;for( l = 6; l >= 0&&l

42、<7; l- )if(getLcdCircle()!=LCD_LED_CIRCLE_LEFT)|(getLcdContent()!=LCD_CONTENT_MAP)|(getLcdLedState()!=LCD_LED_STATE_RUN) break;CacheFullScr(l);CommitBuffer(0);OSTimeDlyHMSM(0, 0, 0, frequence);LcdInit();break;default:break;break;default:break;/* * Name: setLcdCircle * Description:设置Lcd动画循环模式 * Pa

43、ram: unsigned char mode: 循环模式标记 * return: void*/void setLcdCircle(unsigned char mode)mCircleMode=mode;/* * Name: getLcdCircle * Description:获取Lcd动画循环模式标记值 * Param: void * return: unsigned char:循环模式标记值*/unsigned char getLcdCircle(void)return mCircleMode;/* * Name: setLcdContent * Description:设置Lcd显示内容(图片 or 汉字) * Param: unsigned char mode: 显示内容标记值 * return: void*/void setLcdContent(unsigned char mode)mLcdContent=mode;/* * Name: getLcdContent * Description:获取Lcd显示内容 * Param: void * return: unsigned char: 显示内容标记值*/unsigned char getLcdContent(void)return mLcdContent;3、 LoadLed.c-/* * Project

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论