9396|52

72

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

uC/OS-II移植到瑞萨SH2A平台详解及源代码,欢迎交流 [复制链接]

刚移植好的。
因为不能上传附件
大家可邮箱咨询我
我可以把工程包发给你们。


以下为移植说明.....



---------------------------------------------------------------------------------------------------------------
AUTHOR: 邱庆康
DATE: 2008-8-26
UPDATE: 2008-8-28
E-mail: qqk_qqk@163.com   欢迎交流
---------------------------------------------------------------------------------------------------------------


系统配置:
IDE: HEW SuperH 9.1.1.0 for SH2A-FPU
CPU: Renesas SH2A/7261
OS: uC/OS-II  2.51
Memory: 64M SDRAM
Emluator: E10A-USB


本机系统时钟根据CPU定时器T0来配置,默认为每秒溢出20次,也就是每秒产生20个时钟节拍。


CPU说明:
SH7261属于SH2A系列微处理器,32位RISC,采用哈佛体系结构,5级流水线,内部包含一个高速缓存,一个浮点协处理器和16个用于快速中断响应的Register Bank。
内部最高时钟频率为120MHz , 总线频率为60MHz
寄存器包括:通用寄存器,系统寄存器,控制寄存器和浮点寄存器。本机未做浮点运算,故浮点寄存器将不作考虑。


uC/OS-II说明:
该实时操作系统内核为2.51版本。可由用户运行56个任务。具体功能参见《uC/OS-II》。


移植步骤:
1.建立编译环境。
  本系统将映像文件下载到SDRAM中进行调试。需要修改section段,并使用SH系列的命令行语句初始化总线控制器,以便将程序下载到SDRAM相应的map映像区。

2.修改中断向量表。
  本系统使用向量号为32的陷阱指令来进行任务切换,需要在中断向量表INT_Vectors中将INT_TRAPA32替换为OSCtxSw。另外,系统时钟使用8位定时器T0溢出中断,故需要将中断向量表中的INT_TMR0_OVI0替换为OSTickISR。

3.硬件初始化
在hwsetup.c文件中初始化时钟,总线控制器,定时器,Cache等CPU及片上I/O资源,以便为uC/OS-II建立运行环境。

4.编写os_cpu_c.c文件。
  根据CPU的体系结构,模拟中断发生后的栈状态。
  中断发生后,SR和PC先入栈。
  task()中的参数默认传递到R0

  如下:
// SH2A任务栈初始化
// 栈从高地址向低地址增长
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
    OS_STK *stk;

    opt    = opt;                          
    stk    = (OS_STK *)ptos;         

    *stk-- = 0;                /* SR  任务启动后允许中断(interrupt mask bits set to 0) */
    *stk-- = (OS_STK)task;              /* PC */

        *stk-- = 0xeeeeeeee;                         /* R14 */   
        *stk-- = 0xdddddddd;                         /* R13 */
        *stk-- = 0xcccccccc;                         /* R12 */
    *stk-- = 0xbbbbbbbb;                         /* R11 */
    *stk-- = 0xaaaaaaaa;                         /* R10 */
    *stk-- = 0x99999999;                         /* R9 */
    *stk-- = 0x88888888;                         /* R8 */
    *stk-- = 0x77777777;                         /* R7 */
    *stk-- = 0x66666666;                         /* R6 */
    *stk-- = 0x55555555;                         /* R5 */
    *stk-- = 0x44444444;                         /* R4 */
    *stk-- = 0x33333333;                         /* R3 */
    *stk-- = 0x22222222;                         /* R2 */
    *stk-- = 0x11111111;                         /* R1 */
    *stk-- = (OS_STK)pdata;             /* R0 */

        *stk-- = 0x11000000;                   // GBR
        *stk-- = 0x22000000;                   // MACH
        *stk-- = 0x33000000;                   // MACL
        *stk = 0x44000000;                     // PR

    return ((OS_STK *)stk);
}



5.编写os_cpu.h文件。
  开中断和关中断使用set_imask()函数
  陷阱指令使用trapa()函数
  以上两个函数包含在系统头文件machine.h中

  另,还要申明用于os_cpu_a.src的四个汇编程序。为了防止Register Bank溢出,本系统将不使用Register Bank
  如下:

#pragma interrupt OSCtxSw//(resbank) // SH2A执行陷阱指令时不使用Register Bank
extern void OSCtxSw(void);           // 任务切换

#pragma interrupt OSTickISR//(resbank) // 该中断不使用Register Bank
extern void OSTickISR(void);                 // 定时器中断

extern void OSStartHighRdy(void);    // 开始任务
extern void OSIntCtxSw(void);        // 中断任务切换



6.编写os_cpu_a.src文件。

1) 压栈,出栈操作宏定义:
;R0 ~ Rn入栈
.MACRO PUSH Rn      
MOVML.L \Rn,@-SPR        ;将Rn~R0依入栈.  R0入栈后,SP = SP-4                          
.ENDM

;R0 ~ Rn出栈
.MACRO POP Rn     
MOVML.L @SPR+,\Rn     ;该指令执行完时,也就是Rn出栈后,(SP = SP + 4)???
.ENDM

;保存系统和控制寄存器
.MACRO PUSH_REG      
STC.L GBR,@-SPR       ;将控制寄存器送入stack

STS.L MACH,@-SPR      ;将系统寄存器送入stack
STS.L MACL,@-SPR
STS.L PR,@-SPR        ;SP始终指向栈顶元素  
.ENDM

;恢复系统和控制寄存器
.MACRO POP_REG      
LDS.L @SPR+,PR    ;恢复系统寄存器
LDS.L @SPR+,MACL
LDS.L @SPR+,MACH

LDC.L @SPR+,GBR   ;恢复控制寄存器
.ENDM


2)   OSStartHighRdy函数:
注意:子函数跳转指令JSR和中断返回指令RTE为delay branch指令,需要在后面插入一条单周期指令,以便在delay slot中填充CPU流水线。

;获得任务栈指针
MOV.L #_OSTCBHighRdy,R2  
MOV.L @R2,R2              
MOV.L @R2,SPR           

POP_REG
POP R14

RTE
NOP


3)  任务切换OSCtxSw函数:
OSTaskSwHook函数可以不执行,以加快任务切换时间

PUSH R14
PUSH_REG

;保存当前任务SP
MOV.L #_OSTCBCur,R3
MOV.L @R3,R2     
MOV.L SPR,@R2        ;保存当前任务栈指针SP到OSTCBCur首地址

;执行用户程序
MOV.L #_OSTaskSwHook,R4
JSR @R4  
NOP               

;OSPrioCur = OSPrioHighRdy
MOV.L #_OSPrioHighRdy,R0
MOV.B @R0,R0
MOV.L #_OSPrioCur,R1
MOV.B R0,@R1

;OSTCBCur = OSTCBHighRdy
MOV.L #_OSTCBHighRdy,R0
MOV.L @R0,R0
MOV.L #_OSTCBCur,R3
MOV.L R0,@R3      

;恢复新任务的SP
MOV.L #_OSTCBHighRdy,R5
MOV.L @R5,R5
MOV.L @R5,SPR      

POP_REG
POP R14
  
RTE               
NOP


4)         中断级别的任务切换OSIntCtxSw:
OSTaskSwHook函数可不执行,以加快任务切换
注意栈顶的多余部分只有OSIntExit的返回地址,代码如下

;去掉栈顶多余单元
ADD #OFFSET,SPR           ;NOTE!!!
                             ;在HEW环境下,只有OSIntExit()的返回地址入栈
                                             ;OSIntCtxSw()的返回地址保存到PR
                                 ;系统函数set_imask(15)将SR的值送入Rn,而不是入栈

;保存当前SP
MOV.L #_OSTCBCur,R7
MOV.L @R7,R7
MOV.L SPR,@R7

;执行用户自定义程序
MOV.L #_OSTaskSwHook,R0
JSR @R0                  
NOP

;OSTCBCur = OSTCBHighRdy
MOV.L #_OSTCBHighRdy,R0
MOV.L @R0,R0
MOV.L #_OSTCBCur,R3
MOV.L R0,@R3      

;OSPrioCur = OSPrioHighRdy
MOV.L #_OSPrioHighRdy,R2
MOV.B @R2,R2
MOV.L #_OSPrioCur,R3
MOV.B R2,@R3

;恢复新任务SP
MOV.L #_OSTCBHighRdy,R6
MOV.L @R6,R6
MOV.L @R6,SPR

POP_REG
POP R14

RTE
NOP


5)  系统时钟处理
定时器溢出标志位可清除也可不清除,反正T0就是一直计数-溢出-中断,不停循环

OSTickISR:

PUSH R14
PUSH_REG

;清除定时器溢出标志位
MOV.L #TCSR_0,R1
MOV.B @R1,R2
BCLR #5,R2
MOV.B R2,@R1

;进入中断,将嵌套数加1
MOV.L #_OSIntEnter,R5
JSR @R5
NOP

;时间节拍处理
MOV.L #_OSTimeTick,R5
JSR @R5
NOP

;中断退出处理
MOV.L #_OSIntExit,R5
JSR @R5
NOP

POP_REG
POP R14

RTE
NOP  



7.main()函数测试任务切换
本系统运行三个简单的任务,分别点亮3个LED。
分别将各个任务调度上锁和开锁,并将任务延迟一定的时间。
三个任务之间都能精确的切换,并且优先级最高的任务一直在运行。

最新回复

这篇文章我在瑞萨单片机论坛见过,楼主不厚道。原帖:www.renesas-mcu.com  详情 回复 发表于 2009-11-28 17:35
点赞 关注

回复
举报

66

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
我的邮箱
qqk_qqk@163.com  
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
若是自己写的果真很厉害,uc/os官方网站上有很多移植的指导很有用。不懂sh2a的汇编语言,所以没看很懂。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

4
 
回楼上,SH2A的汇编语言和ARM汇编差不多。
不过如果你懂了X86的汇编,看懂这些代码应该不是难事。。

这当然是我自己写的,之前我一直在搜索瑞萨SH系列的UCOS移植例子,但一直找不到。所以干脆自己来移植了。
从接触UCOS,到移植调试完毕,整个过程花了大概2个月时间。
 
 
 

回复

96

帖子

0

TA的资源

一粒金砂(初级)

5
 
;-----------------------------------------------------------------------------
;  TITLE:  os_cpu_a.src
;  CPU:    Renesas SH2A/7261
;  AUTHOR: Qiu QingKang
;  Email:  qqk_qqk@163.com
;  DATE:   2008-7-15
;  UPDATE: 2008-8-26
;------------------------------------------------------------------------------


.CPU SH2A                                            ;申明CPU类型

;---------------------------------------------------
;符号申明
;---------------------------------------------------
OFFSET: .EQU H'4                                     ;栈指针偏移量
TCSR_0: .EQU H'FFFE5402                              ;定时器状态寄存器地址
SPR:    .REG R15                                     ;定义R15为栈指针

;---------------------------------------------------
;函数申明
;---------------------------------------------------
.EXPORT _OSStartHighRdy                              ;开始最高级任务
.EXPORT _OSCtxSw                                     ;任务切换
.EXPORT _OSIntCtxSw                                  ;中断任务切换
.EXPORT _OSTickISR                                   ;定时器中断

.IMPORT _OSTaskSwHook                                ;用户定义的对外接口函数
.IMPORT _OSIntEnter                                  ;进入中断
.IMPORT _OSTimeTick                                  ;时钟处理
.IMPORT _OSIntExit                                   ;退出中断

;----------------------------------------------
;变量申明
;----------------------------------------------
.IMPORT _OSTCBHighRdy                                ;新任务TCB
.IMPORT _OSTCBCur                                    ;当前任务TCB
.IMPORT _OSPrioCur                                   ;当前优先级  8 bits
.IMPORT _OSPrioHighRdy                               ;新任务优先级  8 bits

;---------------------------------------------------
;入栈/出栈     HEW的宏定义语句
;---------------------------------------------------
;R0 ~ Rn入栈
.MACRO PUSH Rn      
MOVML.L \Rn,@-SPR                                    ;将Rn~R0依入栈.  R0入栈后,SP = SP-4                          
.ENDM

;R0 ~ Rn出栈
.MACRO POP Rn     
MOVML.L @SPR+,\Rn                                    ;该指令执行完时,也就是Rn出栈后,SP = SP + 4
.ENDM

;保存系统和控制寄存器
.MACRO PUSH_REG      
STC.L GBR,@-SPR                                      ;将控制寄存器送入stack

STS.L MACH,@-SPR                                     ;将系统寄存器送入stack
STS.L MACL,@-SPR
STS.L PR,@-SPR                                       ;SP始终指向栈顶元素  
.ENDM

;恢复系统和控制寄存器
.MACRO POP_REG      
LDS.L @SPR+,PR                                       ;系统寄存器出栈
LDS.L @SPR+,MACL
LDS.L @SPR+,MACH

LDC.L @SPR+,GBR                                      ;控制寄存器出栈
.ENDM

       
.SECTION P,CODE,ALIGN=4                              ;HEW的段申明,程序段,宽度为4
;--------------------------------------
;任务开始
;--------------------------------------
_OSStartHighRdy:  

;获得任务栈指针
MOV.L #_OSTCBHighRdy,R2                               ;指向指针的指针(指针的地址)
MOV.L @R2,R2                                          ;指针值
MOV.L @R2,SPR                                         ;将指针指向的值送入SP.  
                                             
POP_REG
POP R14

RTE
NOP

   
;-------------------------------------
;任务切换
;--------------------------------------
_OSCtxSw:                                              ;该ISR的入口地址对应指令(TRAPA   #32)

PUSH R14
PUSH_REG

;保存当前任务SP
MOV.L #_OSTCBCur,R3
MOV.L @R3,R2     
MOV.L SPR,@R2                                         ;保存当前任务栈指针SP到OSTCBCur首地址

;执行用户程序
MOV.L #_OSTaskSwHook,R4
JSR @R4  
NOP               

;OSPrioCur = OSPrioHighRdy
MOV.L #_OSPrioHighRdy,R0      
MOV.B @R0,R0
MOV.L #_OSPrioCur,R1
MOV.B R0,@R1

;OSTCBCur = OSTCBHighRdy
MOV.L #_OSTCBHighRdy,R0
MOV.L @R0,R0
MOV.L #_OSTCBCur,R3
MOV.L R0,@R3      

;恢复新任务的SP
MOV.L #_OSTCBHighRdy,R5
MOV.L @R5,R5
MOV.L @R5,SPR      

POP_REG
POP R14
  
RTE               
NOP

   
;--------------------------------------------------
;中断级的任务切换
;本系统的所有中断程序将不使用Register Bank
;当使用Bank发生中断时,寄存器自动保存到Register Bank
;Register Bank满时,寄存器将入栈
;---------------------------------------------------
_OSIntCtxSw:

;去掉栈顶多余单元
ADD #OFFSET,SPR                                      ;NOTE !!!!!!!!
                                                      ;在HEW环境下,只有OSIntExit()的返回地址入栈
                                                                      ;OSIntCtxSw()的返回地址保存到PR
                                                                          ;系统函数set_imask(15)将SR的值送入Rn,而不是入栈

;保存当前SP
MOV.L #_OSTCBCur,R7
MOV.L @R7,R7
MOV.L SPR,@R7

;执行用户自定义程序
MOV.L #_OSTaskSwHook,R0
JSR @R0                  
NOP

;OSTCBCur = OSTCBHighRdy
MOV.L #_OSTCBHighRdy,R0
MOV.L @R0,R0
MOV.L #_OSTCBCur,R3
MOV.L R0,@R3      

;OSPrioCur = OSPrioHighRdy
MOV.L #_OSPrioHighRdy,R2
MOV.B @R2,R2
MOV.L #_OSPrioCur,R3
MOV.B R2,@R3

;恢复新任务SP
MOV.L #_OSTCBHighRdy,R6
MOV.L @R6,R6
MOV.L @R6,SPR

POP_REG
POP R14

RTE
NOP
   
   
;-------------------------------------------------
;系统时钟中断
;该中断不使用Register Bank
;-------------------------------------------------
_OSTickISR:

PUSH R14
PUSH_REG

;清除定时器溢出标志位
MOV.L #TCSR_0,R1
MOV.B @R1,R2
BCLR #5,R2
MOV.B R2,@R1

;进入中断,将嵌套数加1
MOV.L #_OSIntEnter,R5
JSR @R5
NOP

;时间节拍处理
MOV.L #_OSTimeTick,R5
JSR @R5
NOP

;中断退出处理
MOV.L #_OSIntExit,R5
JSR @R5
NOP

POP_REG
POP R14

RTE
NOP  

.END

  
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
这个是测试文件



/*----------------------------------------------------
*  TITLE:   main.c
*  CPU:     Renesas SH2A/7261
*  AUTHOR:  Qiu QingKang
*  Email:   qqk_qqk@163.com
*  DATE:    2008-7-15
*  UPDATE:  2008-8-26
*---------------------------------------------------*/

#include "includes.h"

OS_STK task_stack[3][100];      // 任务栈
INT32U system_time;             // 系统时钟

void my_task1(void *pdata);
void my_task2(void *pdata);
void my_task3(void *pdata);


void main(void)
{
        OSInit();        
       
        // 用户程序中不能使用优先级0,1,2,3以及最低的四个优先级                 

    OSTaskCreate(my_task1, (void *)0, &task_stack[0][100 - 1], 4);
        OSTaskCreate(my_task2, (void *)0, &task_stack[1][100 - 1], 5);
        OSTaskCreate(my_task3, (void *)0, &task_stack[2][100 - 1], 6);
       
    OSStart();      
}  

void my_task1(void *pdata)
{       
        pdata = pdata;       
        OSTimeSet(0);
        start_os_time();     // 启动系统时钟
                  
        while(1){               
                OSTimeDlyHMSM(0, 0, 1, 0);
                OSSchedLock();
               
            LED_Monitor1 ^= 1;
               
                OSSchedUnlock();
        }
}      
        
void my_task2(void *pdata)
{
        pdata = pdata;
               
        while(1){
                OSTimeDlyHMSM(0, 0, 5, 0);
                OSSchedLock();

                LED_Monitor2 ^= 1;         
            
                OSSchedUnlock();
        }
}   
   
void my_task3(void *pdata)
{
        pdata = pdata;
               
        while(1){
                OSTimeDlyHMSM(0, 0, 10, 0);
                OSSchedLock();

                LED_Monitor3 ^= 1;         
        
                OS_ENTER_CRITICAL();
                system_time = OSTimeGet();         // 获得系统时钟
                OS_EXIT_CRITICAL();

                OSSchedUnlock();               
        }
}   
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

7
 
zhangxiaoping1983@gmail.com
我的邮箱,很感兴趣!
 
 
 

回复

86

帖子

0

TA的资源

一粒金砂(初级)

8
 
我用的是SH2-7145 麻烦发一下fyepe@yahoo.com.cn谢谢
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

9
 
我的邮箱:lzyabs@gmail.com,我非常感兴趣。非常感谢楼主的分享!
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

10
 
希望能交流 呵呵
whywhyyyz8@163.com
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

11
 
z 顶上去!
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

12
 
...好高深~~~看不懂
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

13
 
楼主好厉害,我只做潜入式应用程序开发,没接触过内核,但是很感兴趣,xjbabc123@126.com,请发过来,很感兴趣
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

14
 
这几天一直做ucosii在51上的移植,多多交流,bjhkffx@126.com
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

15
 
楼主很强嘛!!!!!!
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

16
 
楼主真是牛人啊
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

17
 
没有用过SH2A平台,不过感谢楼主分享,麻烦发送一份“nettman@sohu.com”,谢谢!
 
 
 

回复

85

帖子

0

TA的资源

一粒金砂(初级)

18
 
mark
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

19
 
mark
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

20
 
呵呵,已经发给你们了。注意查收
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表