原创 FreeRTOS 到ARM7的移植(原创),送官方说明文档

2008-8-18 20:35 9995 11 102 分类: MCU/ 嵌入式

在网上找到一个官方的PDF说明文档,不敢独享,与兄弟们分享.(文件太大--3.4Mb,压缩后仍有1Mb,有哪位朋友需要的留下email地址,隔天就发送.)


移植OS,主要需处理的有:
     1)  现场的保护与恢复;
     2)  系统时钟节拍的处理;
     3)  OS运行的模式与中断处理等;
     


               


(1)      这里首先考虑现场的保护与恢复,这里利用ARM7的SWI来触发任务切换,主要代码如下:


vPortYieldProcessor   ;;walter 20080816
 ADD  LR, LR, #4          
 portSAVE_CONTEXT    
; Save the context  (宏)
 LDR R0, =vTaskSwitchContext
;  selecting the next task 
 MOV LR, PC
 BX R0
 portRESTORE_CONTEXT ; Restore the context (宏)


 MACRO  
portSAVE_CONTEXT 
;;;保存当前场景
 STMDB SP!, {R0}
 ; Set R0 to point to the task stack pointer.  
 STMDB SP, {SP}^
 SUB SP, SP, #4
 LDMIA SP!, {R0} 
 STMDB R0!, {LR}
 MOV LR, R0
 ; Pop R0 so we can save it onto the system mode stack.
 LDMIA SP!, {R0}
 ; Push all the system mode registers onto the task stack.
 STMDB LR, {R0-LR}^
 SUB LR, LR, #60
  ; Push the SPSR onto the task stack.  
 MRS R0, SPSR
 STMDB LR!, {R0}
 LDR R0, =ulCriticalNesting
 LDR R0, [R0]
 STMDB LR!, {R0}
 ; Store the new top of stack for the task.  
 LDR R1, =pxCurrentTCB
 LDR R0, [R1]
 STR LR, [R0]
 MEND


 MACRO 
portRESTORE_CONTEXT 
;;恢复现场
; Set the LR to the task stack.
 LDR R1, =pxCurrentTCB
 LDR R0, [R1]
 LDR LR, [R0]
 ; The critical nesting depth is the first item on the stack.  
 ; Load it into the ulCriticalNesting variable.
  
 LDR R0, =ulCriticalNesting
 LDMFD LR!, {R1}
 STR R1, [R0]
 
; Get the SPSR from the stack.
 LDMFD LR!, {R0}
 MSR SPSR_cxsf, R0
 ; Restore all system mode registers for the task.   
 LDMFD LR, {R0-R14}^ 
 NOP
 ; Restore the return address.
 LDR LR, [LR, #+60]
 
; And return - correcting the offset in the LR to obtain the  
 ; correct address.   
 SUBS PC, LR, #4
 MEND

这里注意:要将vPortYieldProcessor注册为SWI中断响应
;; LDR R0, =Handler_SWI   ;;替换以前的SWI中断
 LDR R0, =vPortYieldProcessor
 STR R0, [R1, #0x04]  ;SWI


开始时启动任务切换,直接采用恢复现场的宏:
vPortStartFirstTask
   portRESTORE_CONTEXT



 


(2)  系统时钟节拍处理,FreeRTOS提供的时钟节拍函数为: vTaskIncrementTick();
根据我的芯片特点,如下设置我的时钟中断:
 MCU_REG_RW_PERI_CLKCON |= dMCU_CLK_ENABLE_TIMER;
 ExceptionSetISRHandler (dMCU_INT_INDEX_TIMER2,vPortOSSystemTick);
 MCU_REG_RW_T2DATA = (12000000/1000/32); // 1ms 的时钟节拍
 MCU_REG_RW_T2MOD = (0x4<<4) | (0<<2) | (1<<0); //Timer 2 Match Interrupt
 MCU_REG_RW_TCON |= (3<<4); //Timer 2 Clear & Run


extern void LtCheckYield(void); // Add by Walter 20080818
void  vPortOSSystemTick( void ) // walter 20080816
{
    vTaskIncrementTick();
#if (configUSE_PREEMPTION == 1)
    //这里为我自己添加的,用以在配置为可剥夺型内核时,
    //若检查到有高优先级的任务进入RDY状态,则进行调度
    //也是移植的一部分,只是和官方给的移植方式不一样,目前运行良好
    LtCheckYield(); // Add by Walter 20080818
#endif   
}


 


3)  OS运行的模式与中断处理等;  这里采用SYS模式运行,FIQ中断,ARM-code
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
{
portSTACK_TYPE *pxOriginalTOS;
 pxOriginalTOS = pxTopOfStack;


 *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; // PC  
 pxTopOfStack--;
 *pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
 pxTopOfStack--; 
 *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS;
 pxTopOfStack--;
 *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
 …………………………………………
 …………………………………………
 *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
 pxTopOfStack--;
 *pxTopOfStack = ( portSTACK_TYPE ) 0x9F;/* SYS,ARM,FIQ */
 pxTopOfStack--;
 *pxTopOfStack = portNO_CRITICAL_NESTING;


 return pxTopOfStack; 
}

同时要注意中断允许的处理:
vPortEnableInterruptsFromARM
 STMDB SP!,  {R0}
 MRS R0, CPSR
 BIC R0, R0,   #0x40 ;;20080818 only use fiq int--;#0xC0
 MSR CPSR_cxsf,R0
 LDMIA SP!, {R0}
 MOV PC, LR
 END


再附张原打算要上传的文档目录图:


点击看大图

文章评论91条评论)

登录后参与讨论

用户377235 2015-4-16 15:58

麻烦给我也发一份hasee_fl@163.com

用户377235 2014-12-2 13:52

多谢博主,我的邮箱:hailanyeying@163.com

用户377235 2014-10-28 15:35

麻烦一下,teriaywl@126.com

用户1338451 2014-3-28 11:49

谢谢博主,可否发份给我. fefe36@163.com

用户377235 2012-7-11 07:52

谢谢搂主ouu_cn@yahoo.com.cn

用户377235 2012-4-25 11:25

谢谢楼主,我正需要这样的示示例代码,能否给我也发一份呢,邮箱lovexi8@qq.com

用户377235 2012-3-1 20:30

15040048976@63.com 谢谢楼主了

用户1515457 2011-7-18 11:43

我现在正有一个FREERTOS的项目代码需要移植 ,希望你能发给我一份让我参考以下! thanks! zhouhuaguo@163.com

用户166622 2010-10-14 10:55

刚入门.麻烦发一份吧.etpmial@163.com 谢谢

用户1237979 2010-6-22 16:19

似乎来得晚了点,还是想要zhouyuannian@126.com
相关推荐阅读
walnutcy_696810119 2012-11-21 08:37
Linux下使用smartCOM调试串口
在Windows下的串口调试一直使用sscom,在Linux下只找到一个cutecom,用了几次,很不喜欢,就着手开发了一款自己的串口调试工具,smartCOM。 smartCOM介绍:http...
walnutcy_696810119 2012-03-29 18:12
【博客大赛】原创--测量基础:什么是测量
写在正文之前: 适逢EDNChina搞活动,而我本人也算在测量业工作,就一起作下笔记吧。若有错误,请大家一起斧正。笔者写本文一方面是梳理知识,另一方面也希望与大家探讨有关测量的知识、应用等,希...
walnutcy_696810119 2011-12-20 18:29
GLONASS 15年来,首次实现24颗星在轨可用
  EDN的博客改版后,不太好用,在SINA重开一个,不过重点改为关注GNSS行业新闻 http://blog.sina.com.cn/s/blog_7420cd1701012en9....
walnutcy_696810119 2011-12-20 17:49
逆向工程第一步:通信协议分析
工程中常有这样的事,想分析下其他知名公司产品中的通信协议,以便生产设计兼容产品。 1) 逆向工程,首先要了解产品,知己知彼,百战不怠;     去年受命想仿一款GARMIN的导航盒,但无法...
walnutcy_696810119 2011-11-14 11:30
通用代码调试方法 (Keil, VCC)
调试代码一般需要定位问题,这里给出一个解决方案, 一般的编译器均支持这些宏指令。   #define DEBUG_WALT_1113     1 extern void log_t...
我要评论
91
11
关闭 站长推荐上一条 /2 下一条