本页内容发表于MCUZone,但不代表MCUZone的观点。
如果你对本页的技术内容有疑问,请到 MCUZone技术论坛 发帖。
如果你认为本页的内容侵害了你的权益,请与hotislandn@hotmail.com;hdapple_2000@hotmail.com 联系,我们会在确认后移除。

FreeRTOS 在 S32 上的移植

FreeRTOS 介绍

  • 开源,免费的嵌入式实时内核

相对于uC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统, 具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。

  • 支持抢占式与合作式调度

FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下情况下,同一优先级的任务共享CPU的使用时间。FreeRTOS的内核可根据用户需要设置为可剥夺型内核或不可剥夺型内核。当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。

  • 提供多种系统服务

作为一个轻量级的操作系统,FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能等,可基本满足较小系统的需要。

FreeRTOS 相关站点

在国内似乎无法直接访问。

可以直接访问,在线文档,但是较旧。

可以下载FreeRTOS的最新代码,浏览相关讨论。

移植

环境

  • FreeRTOS

FreeRTOS版本4.2.0。

  • 编译工具

IDE使用Keil 3.04, 工具链使用RealView 3.0。

  • 硬件平台

MCUZone AT91SAM7S32 EVB Rev 1.0。

移植框架

www.mcuzone.com_project_freertos_s32_fs32.jpg

代码分析

运行模式

  • 在移植中, 任务运行于ARM的SYS模式,任务切换操作通过SWI来实现。
/* portYIELD must be a function, otherwise it cannot be called from thumb. */
void portYIELD(void) {
  //__asm{	SVC	0	};
    __asm{	SWI	0	}; 
}
  • SWI的处理

由于系统中只有这一个SWI调用,因此在SWI的异常处理中,不判断SWI号,而是直接跳往vPortYieldProcessor执行。

RESET
        LDR    PC,=SYSINIT         ; Reset
        B      UDFHANDLER          ; UNDEFINED
        LDR    PC,SWIHANDLER       ; SWI
        B      PABTHANDLER         ; PREFETCH ABORT
        B      DABTHANDLER         ; DATA ABORT
        B      .                   ; RESERVED  
        LDR    PC,_OS_CPU_IRQ_ISR  ; IRQ
        LDR    PC,_OS_CPU_FIQ_ISR  ; FIQ
 
        EXTERN vPortPreemptiveTick
        ;EXTERN OS_CPU_FIQ_ISR
_OS_CPU_IRQ_ISR
        DCD    vPortPreemptiveTick
_OS_CPU_FIQ_ISR
        DCD    vPortPreemptiveTick
		       			
UDFHANDLER
        B      .
 
        EXTERN vPortYieldProcessor
SWIHANDLER
        DCD    vPortYieldProcessor

任务建立

任务运行于sys模式,且根据任务代码设置T bit,使得以THUMB模式编译的任务能正确运行于THUMB模式。

#define portINITIAL_SPSR				( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
 
......
	/* The last thing onto the stack is the status register, which is set for
	system mode, with interrupts enabled. */
	*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
 
        if ((unsigned int)pxCode & 0x01)
        {
	   *pxTopOfStack |= portTHUMB_MODE_BIT;
        }
 
	pxTopOfStack--;

任务上下文切换

注意其中的LDMFD指令,加载到的是user模式的寄存器。

	MACRO
	portRESTORE_CONTEXT
;	/* Set the LR to the task stack. */
	LDR	R0, =pxCurrentTCB
	LDR	R0, [R0]
	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

相关资料

购买产品

 
user\dracula\freertos_s32.txt · 最后更改: 2008/06/30 23:51 由 hzxiao
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki