lgnq 发表于 2010-4-11 18:57:29

将RT-Thread 0.3.0正式版移植到了Renesas M16C

手头有瑞萨的M16C62P(M30627FHP)和M16C64(R5F3640M)两个开发平台。于是就尝试把RT-Thread移植到瑞萨的M16C上。

经过几天的努力,终于可以运行LED任务和finsh任务了。
现在上传到论坛上,和大家共享。
点击此处下载 ourdev_545550.rar(文件大小:3.98M) (原文件名:RTT2M16C_20100411.rar)

=================================================================================================================

移植版本 :RT-Thread 0.3.0正式版
移植平台 :瑞萨的M16C62P(M30627FHP)和M16C64(R5F3640M)
开发工具 :IAR Embedded Workbench for R32C v3.401

移植过程 :

移植的过程主要涉及两个文件/libcpu/m16c/contex.asm,/libcpu/m16c/stack.c
/libcpu/m16c/stack.c 这个文件只有一个堆栈初始化函数,基本上是参考ucosii移植到M16C的方案

/libcpu/m16c/contex.asm 这个文件主要是和上下文切换相关的,还有两个中断处理函数
rt_hw_context_switch_to            //用于切换到第一个任务
    MOV.W   R0, A0
    LDC   , ISP
    POPM    R0,R1,R2,R3,A0,A1,SB,FB
    REIT

rt_hw_context_switch               //非中断时,切换上下文
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB
    MOV.W    R0, A0
    STC      ISP,
    MOV.W    R1, A0
    LDC      , ISP
    POPM   R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack
    REIT

rt_hw_context_switch_interrupt //中断时,切换上下文
    MOV.W    rt_thread_switch_interrput_flag, A0
    CMP.W    #1,A0
    MOV.W    R0, rt_interrupt_from_thread
    JEQ      jump
    MOV.W    #1, A0
    MOV.W    A0,rt_thread_switch_interrput_flag
jump
    MOV.W    R1, rt_interrupt_to_thread
    RTS

//时钟中断处理函数,一般的中断处理函数也是这个结构,只要把相应的中断处理部分替换就可以了。
rt_hw_timer_handler:
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB             ; Save current task's registers
    JSR      rt_interrupt_enter                        
    JSR      rt_tick_increase                  //中断处理部分                        
    JSR      rt_interrupt_leave

    MOV.W    rt_thread_switch_interrput_flag, R0
    CMP.W    #1, R0
    JEQ      jump_switch
   
    POPM   R0,R1,R2,R3,A0,A1,SB,FB             ; Restore registers from the new task's stack
    REIT                                       ; Return from interrup
   
jump_switch
    MOV.W    #0, R0
    MOV.W    R0, rt_thread_switch_interrput_flag
   
    MOV.W    rt_interrupt_from_thread, A0
    STC      ISP,    
   
    MOV.W    rt_interrupt_to_thread, A0
    LDC      , ISP
    POPM   R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack
    RTS                                    //这个比较关键,是普通函数返回而不是中断返回

================================================================================================================

除了移植部分,还修改了几处针对IAR EW M16C编译器会出问题的地方,比如:
将原来的 thread->number_mask = 1 << thread->current_priority;   //1在16位的编译器中默认是short型的,即16位的
改为   thread->number_mask = 1L << thread->current_priority;//1L 在任何编译器中都定义为1是long型的,即32位的

还增加了finsh shell的ANSI color显示,请把超级终端的ANSI color打开就能看到绿色的“finsh>>”提示符
http://cache.amobbs.com/bbs_upload782111/files_28/ourdev_545552.jpg
(原文件名:finsh.jpg)
=================================================================================================================

谢谢ffxz开发并开放了RT-Thread这个系统。

我是参加了ffxz上个月组织的RT-Thread网友见面会,才开始关注起RT-Thread的,
虽然接触RT-Thread没多久,但RTT给我的感觉还是很好用的,移植方便,finsh也不错,开发者也很活跃。。。

希望RT-Thread能推广开来,使RT-Thread迅速成为开源RTOS里的佼佼者。

luxinsun 发表于 2010-4-11 23:23:36

支持。我一个项目也准备使用RTT了,今天已经着手打印手册了。

shaolin 发表于 2010-4-12 00:51:01

楼主很快啊,猛赞。。。

ffxz 发表于 2010-4-12 07:47:19

不错,不错!有兴趣维护这个分支吗?这个应该是第一个16位的分支(应该会是基于0.4.x开发分支)。

lgnq 发表于 2010-4-12 08:17:42

回复【3楼】ffxz
不错,不错!有兴趣维护这个分支吗?这个应该是第一个16位的分支(应该会是基于0.4.x开发分支)。

-----------------------------------------------------------------------

好的

lvhaian 发表于 2010-4-12 16:13:29

【4楼】 lgnq
能加我个 qq 么 ^_^ 1106693754

lgnq 发表于 2010-4-12 19:20:54

回复【5楼】lvhaian 安哥
【4楼】 lgnq   
能加我个 qq 么 ^_^ 1106693754
-----------------------------------------------------------------------

好的,安哥,明天上班后加你,家里的禁止用QQ ^^

zchong 发表于 2010-4-13 07:11:41

楼上,家规?比较严格的说话。

lgnq 发表于 2010-4-13 10:12:32

回复【7楼】zchong
楼上,家规?比较严格的说话。
-----------------------------------------------------------------------
hehe

lgnq 发表于 2010-4-13 10:22:16

修正了一个bug
rt_hw_context_switch_interrupt //中断时,切换上下文
1    MOV.W    rt_thread_switch_interrput_flag, A0
2    CMP.W    #1,A0
3    MOV.W    R0, rt_interrupt_from_thread
4    JEQ      jump
5    MOV.W    #1, A0
6    MOV.W    A0,rt_thread_switch_interrput_flag
7jump
8    MOV.W    R1, rt_interrupt_to_thread
9    RTS
原先的这段汇编代码有点问题,主要是第三行和第四行位置颠倒了

下面上传最新的context.asm,精简了上下文移植代码,修正了上面提到的bug
/*
* File      : context.asm
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date         Author       Notes
* 2010-04-09   fify         the first version
*
* For       : Renesas M16C
* Toolchain : IAR's EW for M16C v3.401
*/

;********************************************************************************************************
;                                           PUBLIC FUNCTIONS
;********************************************************************************************************

    RSEG      CSTACK

    RSEG      ISTACK

    RSEG      CODE(1)

    EXTERN    rt_thread_switch_interrput_flag
    EXTERN    rt_interrupt_from_thread
    EXTERN    rt_interrupt_to_thread
    EXTERN    rt_interrupt_enter
    EXTERN    rt_tick_increase
    EXTERN    rt_interrupt_leave
    EXTERN    u0rec_handler

    PUBLIC    rt_hw_interrupt_disable
    PUBLIC    rt_hw_interrupt_enable   
    PUBLIC    rt_hw_context_switch_to
    PUBLIC    rt_hw_context_switch
    PUBLIC    rt_hw_context_switch_interrupt
    PUBLIC    rt_hw_timer_handler
    PUBLIC    rt_hw_uart0_receive_handler

rt_hw_interrupt_disable
    FCLR    I
    RTS

rt_hw_interrupt_enable
    FSET    I
    RTS
   
;/*
; * void rt_hw_context_switch_to(rt_uint32 to);
; * r0 --> to
; * this fucntion is used to perform the first thread switch
; */
rt_hw_context_switch_to
    MOV.W   R0, A0
    LDC   , ISP
    POPM    R0,R1,R2,R3,A0,A1,SB,FB
    REIT

rt_hw_context_switch
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB
    MOV.W    R0, A0
    STC      ISP,
    MOV.W    R1, A0
    LDC      , ISP
    POPM   R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack
    REIT

rt_hw_context_switch_interrupt
    CMP.W    #1,rt_thread_switch_interrput_flag
    JEQ      jump
    MOV.W    #1,rt_thread_switch_interrput_flag
    MOV.W    R0, rt_interrupt_from_thread
jump
    MOV.W    R1, rt_interrupt_to_thread
    RTS

rt_hw_context_switch_interrupt_do
    MOV.W    #0, rt_thread_switch_interrput_flag   
    MOV.W    rt_interrupt_from_thread, A0
    STC      ISP,    
   
    MOV.W    rt_interrupt_to_thread, A0
    LDC      , ISP
    POPM   R0,R1,R2,R3,A0,A1,SB,FB         ; Restore all processor registers from the new task's stack
    RTS                                    ; Normal return
   
    .EVEN
rt_hw_timer_handler:
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB             ; Save current task's registers
    JSR      rt_interrupt_enter                  
    JSR      rt_tick_increase                           
    JSR      rt_interrupt_leave

    CMP.W    #1,rt_thread_switch_interrput_flag
    JEQ      rt_hw_context_switch_interrupt_do
   
    POPM   R0,R1,R2,R3,A0,A1,SB,FB             ; Restore registers from the new task's stack
    REIT                                       ; Return from interrup

    .EVEN
rt_hw_uart0_receive_handler:
    PUSHM    R0,R1,R2,R3,A0,A1,SB,FB             ; Save current task's registers
    JSR      rt_interrupt_enter
    JSR      u0rec_handler                        
    JSR      rt_interrupt_leave

    CMP.W    #1, rt_thread_switch_interrput_flag
    JEQ      rt_hw_context_switch_interrupt_do
   
    POPM   R0,R1,R2,R3,A0,A1,SB,FB             ; Restore registers from the new task's stack
    REIT                                       ; Return from interrup

    END

ffxz 发表于 2010-4-13 10:37:40

I have posted a mail to you. Please check it.

ffxz 发表于 2010-4-14 08:42:31

这个分支已经提交到svn上了,ansi color的修改没有加入,因为这个并不是普遍存在的(难道需要做一个宏定义选项来选择是否产生ansi color?),只是感觉意义不是太大。

lgnq 发表于 2010-4-14 09:52:20

ffxz速度好快啊,我刚把bsp/m16c62p和libcpu/m16c commit到google svn上,ffxz就把相应的__ICCM16C__内核修改部分commit了 ^^赞!

现在我把本地的SVN update了,正在看M16C分支,发现编译有几个小问题,等我整理后,再提交ffxz修改吧。

关于shell ansi color,这个并不是很重要,看个人喜好吧 ^^

ffxz 发表于 2010-4-14 10:25:52

^-^

因为这个是16位的,是否应该把一些基本类型也修改为16位?例如rt_ubase_t/rt_base_t。16位处理与32位处理差别是否比较大?

lgnq 发表于 2010-4-14 11:18:16

我感觉16位和32位编译器主要的区别就是对默认类型的定义不同
举个例子
#define RT_VERSION                                                3
#define RT_SUBVERSION                                        0

在下面一行语句中
rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);

如果是32位编译器,那么参数 RT_VERSION和RT_SUBVERSION就自动转换为32位整型
但是如果是16位的编译器,那么参数RT_VERSION和RT_SUBVERSION就自动转换为16位整型

于是我改了一下宏定义,明确定义为long 整型
#define RT_VERSION                                                3L
#define RT_SUBVERSION                                        0L
这样不论是32位编译器还是16位编译器,编译出来的结果都是32位整型了。

所以为了可移植性,尽量避免使用默认类型。

这方面ucosii做得很好。
尽量不适用普通的int,short,long等。。。因为各个不同的编译器,sizeof(int)是不一样的。
而是改用INT8U,INT16U。。。
RT-Thread中也有这样的类型定义
/* date type defination                                        */
typedef signed        char                                        rt_int8_t;
typedef signed        short                                         rt_int16_t;
typedef signed        long                                        rt_int32_t;
typedef unsigned char                                        rt_uint8_t;
typedef unsigned short                                         rt_uint16_t;
typedef unsigned long                                        rt_uint32_t;
typedef int                                                  rt_bool_t;

但使用得不彻底,某些地方还是在使用常用的类型定义,比如finsh中。

以上的类型定义已经足够了,也很明确,8位,16位,32位
rt_ubase_t/rt_base_t 这两个反而就不明确了。

个人意见,可能我的想法也不是全面,仅供参考

ffxz 发表于 2010-4-14 11:52:47

#define RT_VERSION 3
#define RT_SUBVERSION 0

在下面一行语句中
rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);

这个转换成16位类型有什么不好吗,打印会乱?

rt_ubase_t/rt_base_t就是跟随机器位数而定的,因为有些地方,对应于16位或32位机器,使用它本身的位数会有更好的效果。要强制使用指定宽度的例如32位,才考虑使用rt_uint32_t的方式。

finsh当时并不是为了那种非常跨平台而准备的,并且成型的时间比RT-Thread要早一年,所以有finsh的时候还不存在RT-Thread。

lgnq 发表于 2010-4-14 13:22:43

回复【15楼】ffxz
#define RT_VERSION 3
#define RT_SUBVERSION 0
在下面一行语句中
rt_kprintf(" / | \\ 0.%d.%d build %s\n", RT_VERSION, RT_SUBVERSION, __DATE__);
这个转换成16位类型有什么不好吗,打印会乱?

是的,打印会有问题,或者没有输出,原因就是16位编译器编译出来是16位的整型,但是rt_kprintf()中又强制转化为32位
============================================================================================================

rt_ubase_t/rt_base_t就是跟随机器位数而定的,因为有些地方,对应于16位或32位机器,使用它本身的位数会有更好的效果。要强制使用指定宽度的例如32位,才考虑使用rt_uint32_t的方式。
finsh当时并不是为了那种非常跨平台而准备的,并且成型的时间比RT-Thread要早一年,所以有finsh的时候还不存在RT-Thread。
-----------------------------------------------------------------------

just_be_fine 发表于 2012-5-14 22:14:23

MARK!!!

just_be_fine 发表于 2012-5-14 22:17:43

可惜现在没法下载了,先记着,以后再来拜读~

lgnq 发表于 2012-5-18 17:00:30

just_be_fine 发表于 2012-5-14 22:17 static/image/common/back.gif
可惜现在没法下载了,先记着,以后再来拜读~

http://code.google.com/p/rt-thread/downloads/list
从 SVN 下载最新的吧
页: [1]
查看完整版本: 将RT-Thread 0.3.0正式版移植到了Renesas M16C