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
}
相关推荐
夜间看花29 分钟前
49 基于单片机的湿度和光照监测
单片机·嵌入式硬件
石板小湫1 小时前
53 基于单片机的8路抢答器加记分
java·数据库·单片机
夜间去看海1 小时前
67 基于单片机的温湿度、烟雾、阈值切换、状态灯、串口收发
单片机·嵌入式硬件·串口·温湿度·状态灯
美式小田1 小时前
硬件工程师面试题 1-10
嵌入式硬件·面试·硬件工程师
小猪写代码1 小时前
STM32进阶 FSMC应用案例:扩展外部 SRAM
stm32·单片机·嵌入式硬件
lucy153027510793 小时前
D7000 低电压立体声手机功放电路芯片,电源纹波抑制比高静态电流低,内置节电模式开关和静噪开关 外接元件少所需外围元件少
单片机·嵌入式硬件·智能手机·音视频·便携式视盘播放器·cd-rom·便携式迷你播放器
南城花随雪。3 小时前
单片机:实现数码管00盗99显示(附带源码)
单片机·嵌入式硬件
物联高科3 小时前
电机驱动,为什么不需要变速器?
单片机·嵌入式硬件·物联网·能源·创业创新
极客小张3 小时前
基于STM32的智电表系统课题设计思路:python友好界面、ADC、UART串口、数据分析
c语言·python·stm32·单片机·数据分析·毕业设计·课程设计