FreeRTOS的使用说明
中断程序
FreeRTOS 中如果ISR中如果使用了Quene,则需要进行任务切换,需要在ISR设计时考虑
portEND_SWITCHING_ISR( ( cContextSwitchRequired ) ); 如果没有任务切换,则无需特殊处理
任务调度
调度存在几种情况:
? 自动放弃时间(SWI),yeild以及wait导致的挂起都算 ? Tick时间到(也进行调度)
VTaskSwitchContext 仅仅查找优先级最高的调度 相同的级别 占有相同的PCU时间
对于IDLE任务而言,如果用抢占式,并且执行到IDLE时,必须让出执行时间的话 a task that is sharing the idle priority (与IDLE任务有相同优先级),则会让出。
假定该任务是while(1){},并且一直处于Ready状态,没有诸如挂起等操作,则一进入IDLE任务就让出
则vApplicationIdleHook()函数基本没有时间执行。也就失去了意义
CoRoutine是一个函数,可以迅速执行完成 在vApplicationIdleHook中调用。
调度时,直接调用了CreateCorountine的任务函数
当执行完之后,IDLE任务会重新循环,检查是否有同级任务执行。
所以在IDLE层次上,有任务,但该任务执行完了还是需要释放一段时间以便让hook函数执行操作。
否则CoRoutine函数基本上没有时间执行。
QUENE操作
其中quene的发送和等待都可能进行任务切换。
当quene发送时,如果quune队列已满,则会挂起;而如果队列为空,take操作就会导致任务挂起
queen
高优先级别 发送 低优先级别 接受
发送完了,继续执行;如果不主动让出CPU的话,低优先级的无法唤醒进行队列处理 如果发送的多了的话,队列满后,高优先级挂起,然后才会让低优先级的任务进行处理 所以程序检测发送的状态,根据状态确定是否是否需要主动让出CPU时间给相同的优先级的任务
另外一个办法就是有效发送后,将任务挂起,当低优先级的任务处理后,再重新将高优先级任务挂起
如果不这样处理的话,队列总是处于满状态
低级别发送 高级别接受
发送完了后,低级别立刻被挂起,然后高级别执行, 因此队列一直为空
任务的处理 任务的原型
void vATaskFunction( void *pvParameters ); Or,
portTASK_FUNCTION_PROTO( vATaskFunction, pvParameters );
是一个死循环
空闲任务
优先级:tskIDLE_PRIORITY 该优先级可以共享
空闲的钩子函数
The Idle Task Hook,在空闲任务中处理一些事情。 如果用相同优先级,又增加一个堆栈空间
Co-routines
configMAX_CO_ROUTINE_PRIORITIES 最高的优先级 例程有以下形式:
void vACoRoutineFunction( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) {
crSTART( xHandle );
for( ;; ) {
-- Co-routine application code here. -- }
crEND(); }
//实际经展开后如下:
switch( ( ( corCRCB * )pxCRCB )->uxState ) { case 0: ; for (;;) { } };
//延时函数的处理
#define crDELAY( xHandle, xTicksToDelay ) \\ if( xTicksToDelay > 0 ) \\ { \\ vCoRoutineAddToDelayedList( xTicksToDelay, NULL ); \\ } \\ crSET_STATE0( xHandle );
//#define crSET_STATE0( xHandle )
( ( corCRCB * )xHandle)->uxState = (__LINE__ * 2); return;
case (__LINE__ * 2):
//可见在延时函数处理过后,函数就退出了
协作例程是一个执行完了,才执行另外一个。执行完了,就意味着放弃CPU,即退出运行。
//协作例程的限制
如果需要保存数据,则需要定义成全局变量或者static变量
//block 函数只能在循环的最外层调用,不能在函数中调用,因为在函数中调用,宏已经不对了
因此也不能在switch语句中调用
void vACoRoutineFunction( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex ) {
// Co-routines must start with a call to crSTART().
crSTART( xHandle );
for( ;; ) {
// It is fine to make a blocking call here, crDELAY( xHandle, 10 );
// but a blocking call cannot be made from within // vACalledFunction(). vACalledFunction(); }
// Co-routines must end with a call to crEND(). crEND(); }
void vACalledFunction( void ) {
// Cannot make a blocking call here!
}
协作例程的调度
void vApplicationIdleHook( void ) {
vCoRoutineSchedule( void ); } 或者
void vApplicationIdleHook( void ) {
for( ;; ) {
vCoRoutineSchedule( void ); } }
/////=======================展开后的程序相当怪异 /* Co-routines MUST start with a call to crSTART. */ //crSTART( xHandle ); 展开
switch( ( ( corCRCB * )xHandle )->uxState ) {
case 0:

