Free RTOS学习之启动任务源码分析

本文深入解析了FreeRTOS V10.0.1中任务调度器的启动过程,包括创建空闲任务以清理内存和提供CPU运行任务,设置PendSV和systick中断优先级,以及通过触发SVC异常启动第一个任务。详细介绍了SVC异常中断函数的工作原理,展示了启动任务的关键步骤和中断处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言


在创建完一个任务后,下一步要做的就是启动任务,本文对Free RTOS V10.0.1的启动任务的源码进行分析

一、创建空闲任务

创建空闲任务的目的:
1)释放被删除任务的TCB与栈 (清理内存)
2)在没有其他任务时,供CPU运行的任务。

二、启动调度器

2.1.设置PendSV和systick中断为最低优先级

在Free RTOS中,所有的中断优先级都大于任务的优先级,即最小的中断优先级>最大的任务优先级
PendCV和systick中断是为Task服务的,所以需要将PendCV和systick的优先级设置为最低。

	/* Make PendSV and SysTick the lowest priority interrupts. */
	portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;	
	portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;

2.2.使能systick中断

systick与其他定时器不同,systick属于内核定时器,是一个24位的倒计数定时器。
有4个寄存器控制systick定时器。systick在rtos中作为心脏,每1ms产生一次中断,在中断中切换任务。

寄存器名称地址
systick控制和状态寄存器0xE000_E010
systick重装载数值寄存器0xE000_E014
systick当前数值寄存器0xE000_E018
systick校准数值寄存器0xE000_E01C
		/* Stop and clear the SysTick. */
		portNVIC_SYSTICK_CTRL_REG = 0UL;/* 控制和状态寄存器复位 */
		portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;/* 当前数值寄存器复位 */

		/* Configure SysTick to interrupt at the requested rate. */
		portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
		portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

三、触发SVC异常、启动第一个任务

启动任务部分使用汇编实现。任务在SVC异常中断中完成启动。

3.1.触发SVC异常

__asm void prvStartFirstTask( void )
{
	PRESERVE8

	/* Use the NVIC offset register to locate the stack. */
	ldr r0, =0xE000ED08 /* 向量表偏移寄存器地址 */
	ldr r0, [r0]
	ldr r0, [r0]		/* 此时R0保存的地址和启动文件中的__initial_sp一样 */

	/* Set the msp back to the start of the stack. */
	msr msp, r0			/* MSP指向__initial_sp */
	/* Globally enable interrupts. */
	cpsie i
	cpsie f
	dsb			/* 数据同步屏障Data Synchronization Barrier */
	isb			/* 指令同步屏障Instruction synchronization barrier */
	/* Call SVC to start the first task. */
	svc 0   	/* 开启SVC异常 启动pxCurrentTCB指向的任务 */
	nop
	nop
}

3.2.SVC异常中断函数

发生SVC异常后,会执行一下操作
1)硬件保存寄存器值
2)LR寄存器保存一个特殊地址
3)调用C函数
4)返回LR地址,硬件恢复寄存器值

__asm void vPortSVCHandler( void )
{
	PRESERVE8

	ldr	r3, =pxCurrentTCB	/* Restore the context. */
	ldr r1, [r3]			/* Use pxCurrentTCBConst to get the pxCurrentTCB address. */
	ldr r0, [r1]			/* The first item in pxCurrentTCB is the task top of stack. */
	ldmia r0!, {r4-r11}		/* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */
	msr psp, r0				/* Restore the task stack pointer. */
	isb
	mov r0, #0
	msr	basepri, r0
	orr r14, #0xd
	bx r14
}

总结

详细过程查看Free RTOS源码 和《ARM Cortex-M3与Cortex-M4权威指南》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值