将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里的佼佼者。 支持。我一个项目也准备使用RTT了,今天已经着手打印手册了。 楼主很快啊,猛赞。。。 不错,不错!有兴趣维护这个分支吗?这个应该是第一个16位的分支(应该会是基于0.4.x开发分支)。 回复【3楼】ffxz
不错,不错!有兴趣维护这个分支吗?这个应该是第一个16位的分支(应该会是基于0.4.x开发分支)。
-----------------------------------------------------------------------
好的 【4楼】 lgnq
能加我个 qq 么 ^_^ 1106693754 回复【5楼】lvhaian 安哥
【4楼】 lgnq
能加我个 qq 么 ^_^ 1106693754
-----------------------------------------------------------------------
好的,安哥,明天上班后加你,家里的禁止用QQ ^^ 楼上,家规?比较严格的说话。 回复【7楼】zchong
楼上,家规?比较严格的说话。
-----------------------------------------------------------------------
hehe 修正了一个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 I have posted a mail to you. Please check it. 这个分支已经提交到svn上了,ansi color的修改没有加入,因为这个并不是普遍存在的(难道需要做一个宏定义选项来选择是否产生ansi color?),只是感觉意义不是太大。 ffxz速度好快啊,我刚把bsp/m16c62p和libcpu/m16c commit到google svn上,ffxz就把相应的__ICCM16C__内核修改部分commit了 ^^赞!
现在我把本地的SVN update了,正在看M16C分支,发现编译有几个小问题,等我整理后,再提交ffxz修改吧。
关于shell ansi color,这个并不是很重要,看个人喜好吧 ^^ ^-^
因为这个是16位的,是否应该把一些基本类型也修改为16位?例如rt_ubase_t/rt_base_t。16位处理与32位处理差别是否比较大? 我感觉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 这两个反而就不明确了。
个人意见,可能我的想法也不是全面,仅供参考 #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。 回复【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。
----------------------------------------------------------------------- MARK!!! 可惜现在没法下载了,先记着,以后再来拜读~ just_be_fine 发表于 2012-5-14 22:17 static/image/common/back.gif
可惜现在没法下载了,先记着,以后再来拜读~
http://code.google.com/p/rt-thread/downloads/list
从 SVN 下载最新的吧
页:
[1]