stm8 freertos移植_stm32 freertos can_freertos stm32 移植(2)

电脑杂谈  发布时间:2017-02-18 21:01:06  来源:网络整理

return pxTopOfStack;

}

2)启动任务调度

portBASE_TYPE xPortStartScheduler( void )

{

让任务切换中断和心跳中断位于最低的优先级,使更高优先级可以抢占mcu

*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;

*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;

设置并启动系统的心跳时钟

prvSetupTimerInterrupt();

初始化临界区的嵌套的个数

uxCriticalNesting = 0;

启动第一个任务

vPortStartFirstTask();

执行到vPortStartFirstTask函数,内核已经开始正常的调度

return 0;

}

3)主动释放mcu使用权

void vPortYieldFromISR( void )

{

触发PendSV系统服务中断,中断到来时由汇编函数xPortPendSVHandler()处理

*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;

}

进入临界区时,首先关闭中断;当退出所以嵌套的临界区后再使能中断

void vPortEnterCritical( void )

{

portDISABLE_INTERRUPTS();

uxCriticalNesting++;

}

void vPortExitCritical( void )

{

uxCriticalNesting--;

if( uxCriticalNesting == 0 )

{

portENABLE_INTERRUPTS();

}

}

4)心跳时钟处理函数

void xPortSysTickHandler( void )

{

unsigned portLONG ulDummy;

如果是抢占式调度,首先看一下有没有需要调度的任务

#if configUSE_PREEMPTION == 1

*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;

#endif

ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();

{ 通过task.c的心跳处理函数vTaskIncrementTick(),进行时钟计数和延时任务的处理

vTaskIncrementTick();

}

portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );

}

3、PORTASM.S 汇编处理部分

1)请求切换任务

xPortPendSVHandler:

保存当前任务的上下文到其任务控制块

mrs r0, psp

ldr r3, =pxCurrentTCB 获取当前任务的任务控制块指针

ldr r2, [r3]

stmdb r0!, {r4-r11} 保存R4-R11到该任务的堆栈

str r0, [r2] 将最后的堆栈指针保存到任务控制块的pxTopOfStack

stmdb sp!, {r3, r14}

关闭中断

mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY

msr basepri, r0

切换任务的上下文,pxCurrentTCB已指向新的任务

bl vTaskSwitchContext

mov r0, #0

msr basepri, r0

ldmia sp!, {r3, r14}

恢复新任务的上下文到各寄存器

ldr r1, [r3]


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-33191-2.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...