您当前的位置:五五电子网电子知识单片机-工控设备综合-其它典型范例:uCOSii在Coldfire MCF52235上的移植 正文
典型范例:uCOSii在Coldfire MCF52235上的移植

典型范例:uCOSii在Coldfire MCF52235上的移植

点击数:7608 次   录入时间:03-04 11:53:18   整理:http://www.55dianzi.com   综合-其它

     

image

     

    2. 3. 3 OS_CPU_A. ASM 的移植

    这个文件包含5 个相当简单的汇编函数, 因为一般不能用C 语言来保存和恢复寄存器。

    ( 1) OS_CPU_SR_Save( )

    这个函数是通过保存中断屏蔽寄存器, 然后关闭中断来实现OS_CRITICAL_MET HOD # 3 的。当函数返回时, D0 包含了状态寄存器的内容, 里面包含当前的中断关闭状态。这个返回值被调用函数保存到变量

    cpu_sr 中。

    ( 2) OS_CPU_SR_Restore( )

    这个函数用来实现恢复中断屏蔽到调用OS _ENTER_CRITICAL( ) 之前的状态。也就是说调用OS_

    ENTER_CRITICAL( ) 之前中断是关闭的, 那么在OS_EXIT_CRITICAL( ) 之后, 中断是关闭的。

    ( 3) OSStartHighRdy( )

    这个函数被OSStar t ( ) 调用来运行优先级最高的任务。OSStar t ( ) 设置OSTCBHighRdy 指向优先级最高任务的OS _T CB。一旦从OSTaskSwHoo k( ) 返回,就把OSRunning 设为OS_T RU E, 它表明现在RT OS

    将要运行。从最高优先级任务的OS_T CB 中恢复堆栈指针, 然后从任务堆栈里取出CPU 寄存器。最后执行

    一个RET 指令, 这个指令可以从堆栈中弹出SR 和PC,现在的任务代码就开始执行。

    ( 4) OSCtx Sw( )

    当一个任务不再运行时就会发生一个任务级的任务切换, 比如任务调用一个延迟10 个时钟节拍的函数。

    这时, C/ OS 需要找出下一个最重要的任务准备去运行。OSCtx Sw ( ) 的功能是保存需要挂起的任务的CPU 寄存器和堆栈, 恢复需要运行任务的CPU 寄存器和堆栈。任务级上下文切换如图4 所示。

     

image

     

    ( 5) OSINTCtx Sw( )

    当中断服务函数完成时, 调用OSIntEx it ( ) 函数去决定是否有一个更重要的任务比被中断的任务更需要执行。这种情况下, OSIntEx it( ) 决定运行哪个任务, 然后调用OSIntCtx Sw ( ) 。这种情况下, 中断服务程序已经保存了被中断任务的CPU 寄存器, 而需要做的只是去恢复新任务的CPU 寄存器。

    2. 3. 4 OS_CPU _I. ASM 的编写

    如果用到增强的乘法累加单元( eMAC) 模块, 在上下文切换和中断时就应该保存和恢复eMAC 寄存器。保

    存和恢复eMAC 寄存器通过两个宏来实现[ 10] 。代码如下:

    . macro OS_EM AC_SAVE

    MOVE. L MACSR, D7

    CLR. L D0

    MOVE. L D0, M ACSR

    MOVE. L ACC0, D0

    MOVE. L ACC1, D1

    MOVE. L ACC2, D2

    MOVE. L ACC3, D3

    MOVE. L ACCEXT01, D4

    MOVE. L ACCEXT23, D5

    MOVE. L MASK, D6

    LEA 32( A7) , A7

    MOVEM. L D0D7, ( A7)

    . endm

    . macro OS_EM AC_REST ORE

    MOVEM. L ( A7) , D0D7

    MOVE. L # 0, MACSR

    MOVE. L D0, ACC0

    MOVE. L D1, ACC1

    MOVE. L D2, ACC2

    MOVE. L D3, ACC3

    MOVE. L D4, ACCEXT01

    MOVE. L D5, ACCEXT23

    MOVE. L D6, MASK

    MOVE. L D7, MACSR

    LEA 32( A7) , A7

    . endm

    2. 4 时钟节拍的产生

    最后还需要编写利用片内定时器产生时钟节拍的中断服务程序。C/ OS要求微控制器提供一个简单的时钟, 用于任务的延时等功能。在此利用可编程中断定时器来产生时钟节拍中断。在定时器中断服务程序中调用OSTimeTick( ) 就产生了系统所需要的时钟节拍。C/OS中产生中断后的中断处理程序如下所示:

    _BSP_TickISR:

    MOVE. W # 0x2700, SR

    LEA 60( A7) , A7



www.55dianzi.com

    MOVEM. L D0D7/ A0 A6, ( A7)

    OS_EMAC_SAVE

    MOVEQ. L # 0, D0

    MOVE. B ( _OSI ntNesting) , D0

    ADDQ. L # 1, D0

    MOVE. B D0, ( _OSI ntNesting)

    CMPI. L # 1, D0

    BNE _BSP_TICkISR_1

    MOVE. L ( _OSTCBCur) , A1

    MOVE. L A7, ( A1)

    _BSP_TickISR_1:

    JSR _BSP_T ickISR_H andler

    JSR _OSInt Ex it

    OS_EMAC_RESTORE

    MOVEM. L ( A7) , D0D7/ A0A6

    LEA 60( A7) , A7

    RTE

    3 任务的创建和移植代码的测试

    源程序移植完, 用户就可以试着制作自己的项目。编写任务代码, 与以前在前后台系统中基本相同, 不同

    的是要把每个任务独立编写成一个文件, 最后由主程序统一调度。为了测试是否移植成功, 用STaskCreateExt ( ) 创建了两个任务。一个任务使板上LED 每一秒闪动一次, 另一个任务是用片内A/ D 采样板上的加速度传感器信号, 并在数码管上显示出当前加速度数值。最后调用OSStar t( ) 启动多任务调度。

    3. 1 定义每个任务的堆栈大小

    OS_STK

    TaskStartStk[ T ASKSTART ST K_SIZE] ;

    OS_STK ADT askStk[ T ASKSTK_SIZE] ;

    然后在main( ) 函数里系统初始化:

    OSInit( ) ;

    3. 2 创建任务

    OST askCreateEx t( TaskStart, ( void * ) 0, ( OS _ ST K * )

    & T askStar tSt k[ T ASKSTARTST K_SIZE1] , T ASK _START _

    PRIO, TASK_START_PRIO, ( OS_ST K* ) & T askStart St k[ 0] ,

    TASK_ST ART_ST K_SIZE, ( vo id * ) 0, OS_TASK_OPT _ST K_

    CH K| OS_TASK_OPT_STK_CLR) ;

    OSTaskCreateExt ( ADT ask, ( vo id * ) 0, ( OS _ STK * )

    & ADTaskStk[ TASKST K_SIZE1] , ADTASK_PRIO, ADT ASK

    _ PRIO, ( OS _ ST K * ) & ADTaskStk [ 0] , TASK _ ST K _SIZE,

    ( vo id * ) 0, OS_TASK_OPT_STK_CHK) ;

    3. 3 系统启动运行

    OSStart( ) ;

    3. 4 测试结果

    测试代码经过编译下载到实验板上运行后, 通过实验板上显示的信息, 表示两个任务在交替运行, 说明移植工作是成功的, 如图5 所示。

     

image


上一页  [1] [2] 


本文关键字:暂无联系方式综合-其它单片机-工控设备 - 综合-其它

《典型范例:uCOSii在Coldfire MCF52235上的移植》相关文章>>>