STM32之HAL例程-FreeRTOS任务调度流程

FreeRTOS中的SysTick和PendSV中断优先级别

在函数xPortStartScheduler中设置PendSV和Systick中断为最低优先级中断,中断编号为15。

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

#define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24U

#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

FreeRTOS调度

1、SYSTICK中断调度

sysytick作为系统时钟基准,每1ms触发一次中断。分析中断程序,可知系统对各个状态链表进行查询,若需要进行任务切换,就使能PendSV位。

复制代码
void xPortSysTickHandler( void )
{
	/* The SysTick runs at the lowest interrupt priority, so when this interrupt
	executes all interrupts must be unmasked.  There is therefore no need to
	save and then restore the interrupt mask value as its value is already
	known - therefore the slightly faster vPortRaiseBASEPRI() function is used
	in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
	vPortRaiseBASEPRI();
	{
		/* Increment the RTOS tick. */
		if( xTaskIncrementTick() != pdFALSE )
		{
			/* A context switch is required.  Context switching is performed in
			the PendSV interrupt.  Pend the PendSV interrupt. */
			portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
		}
	}
	vPortClearBASEPRIFromISR();
}

systick定时器全局监测变量xTickCount。

复制代码
PRIVILEGED_DATA static volatile TickType_t xTickCount 				= ( TickType_t ) configINITIAL_TICK_COUNT;

2、taskYIELD()任务切换

复制代码
#define taskYIELD()					portYIELD()
#define portYIELD()																\
{																				\
	/* Set a PendSV to request a context switch. */								\
	portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;								\
																				\
	/* Barriers are normally not required but do ensure the code is completely	\
	within the specified behaviour for the architecture. */						\
	__dsb( portSY_FULL_READ_WRITE );											\
	__isb( portSY_FULL_READ_WRITE );											\
}

3、PendSV中断中任务切换

任务的切换都是在PendSV中断中进行。

复制代码
__asm void xPortPendSVHandler( void )
{
	extern uxCriticalNesting;
	extern pxCurrentTCB;
	extern vTaskSwitchContext;

	PRESERVE8

	mrs r0, psp
	isb

	ldr	r3, =pxCurrentTCB		/* Get the location of the current TCB. */
	ldr	r2, [r3]

	stmdb r0!, {r4-r11}			/* Save the remaining registers. */
	str r0, [r2]				/* Save the new top of stack into the first member of the TCB. */

	stmdb sp!, {r3, r14}
	mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
	msr basepri, r0
	dsb
	isb
	bl vTaskSwitchContext
	mov r0, #0
	msr basepri, r0
	ldmia sp!, {r3, r14}

	ldr r1, [r3]
	ldr r0, [r1]				/* The first item in pxCurrentTCB is the task top of stack. */
	ldmia r0!, {r4-r11}			/* Pop the registers and the critical nesting count. */
	msr psp, r0
	isb
	bx r14
	nop
}
相关推荐
傍晚冰川13 分钟前
FreeRTOS任务调度过程vTaskStartScheduler()&任务设计和划分
开发语言·笔记·stm32·单片机·嵌入式硬件·学习
SY师弟3 小时前
51单片机基础部分——矩阵按键检测
嵌入式硬件·矩阵·51单片机
Lester_11014 小时前
嵌入式学习笔记 - freeRTOS xTaskResumeAll( )函数解析
笔记·stm32·单片机·学习·freertos
阿超爱嵌入式4 小时前
STM32学习之I2C(理论篇)
stm32·嵌入式硬件·学习
三月雪落无痕7 小时前
altium designer2024绘制stm32过程笔记x`
笔记·嵌入式硬件
天天爱吃肉82189 小时前
新能源汽车热管理核心技术解析:冬季续航提升40%的行业方案
android·python·嵌入式硬件·汽车
章鱼哥嵌入式开发9 小时前
# STM32F103 SD卡读写程序
stm32·单片机
广药门徒10 小时前
定时器时钟来源可以从输入捕获引脚输入
单片机·嵌入式硬件
爱睡觉的王宇昊14 小时前
二、【ESP32开发全栈指南:ESP32 GPIO深度使用】
单片机·嵌入式硬件
学生哥-_-20 小时前
STM32通过KEIL pack包轻松移植LVGL,并学会使用GUI guider
stm32·lvgl·tftlcd·gui guider·gt911