
本页内容发表于MCUZone,但不代表MCUZone的观点。
如果你对本页的技术内容有疑问,请到 MCUZone技术论坛 发帖。
如果你认为本页的内容侵害了你的权益,请与hotislandn@hotmail.com;hdapple_2000@hotmail.com 联系,我们会在确认后移除。
相对于uC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统, 具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。
FreeRTOS内核支持优先级调度算法,每个任务可根据重要程度的不同被赋予一定的优先级,CPU总是让处于就绪态的、优先级最高的任务先运行。FreeRT0S内核同时支持轮换调度算法,系统允许不同的任务使用相同的优先级,在没有更高优先级任务就绪的情况下情况下,同一优先级的任务共享CPU的使用时间。FreeRTOS的内核可根据用户需要设置为可剥夺型内核或不可剥夺型内核。当FreeRTOS被设置为可剥夺型内核时,处于就绪态的高优先级任务能剥夺低优先级任务的CPU使用权,这样可保证系统满足实时性的要求;当FreeRTOS被设置为不可剥夺型内核时,处于就绪态的高优先级任务只有等当前运行任务主动释放CPU的使用权后才能获得运行,这样可提高CPU的运行效率。
作为一个轻量级的操作系统,FreeRTOS提供的功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能等,可基本满足较小系统的需要。
在国内似乎无法直接访问。
可以直接访问,在线文档,但是较旧。
可以下载FreeRTOS的最新代码,浏览相关讨论。
FreeRTOS版本4.2.0。
IDE使用Keil 3.04, 工具链使用RealView 3.0。
MCUZone AT91SAM7S32 EVB Rev 1.0。
/* portYIELD must be a function, otherwise it cannot be called from thumb. */ void portYIELD(void) { //__asm{ SVC 0 }; __asm{ SWI 0 }; }
由于系统中只有这一个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