FreeRtos进阶——中断的内部逻辑

中断与非中断API的区别

c 复制代码
BaseType_t xQueueSendToBack(
                                QueueHandle_t    xQueue,
                                const void       *pvItemToQueue,
                                TickType_t       xTicksToWait
                            );
BaseType_t xQueueSendToBackFromISR(
                                      QueueHandle_t xQueue,
                                      const void *pvItemToQueue,
                                      BaseType_t *pxHigherPriorityTaskWoken
                                   );

以写队列的API为例,在非中断的api中最后一项参数为等待时间,而在中断api中最后一项参数仅仅是说明有无优先级更高的任务被唤醒。

在非中断api中,执行的逻辑是这样,如果遇到更高优先级的任务被唤醒,那么更高优先级的任务将会抢占当前任务。而在中断api中,会先记录更高优先级的任务,在中断里的任务处理完成后,在中断末尾对任务进行切换。

中断的范围

在FreeRtos中,关中断并不是关闭所有中断,能够关闭的中断都是对于系统来说都是等级相对较低的,等级高的中断不能关断。因为在FrerRtos中,根本就没有涉及到高等级的中断,在操作系统的api中仅仅只包含了低级的中断。

注意:即使最低优先级的中断 也比最高优先级的任务 优先级要高

中断服务函数 xPortPendSVHandler()

在系统滴答定时器中断服务函数中调用API函数xPortSysTickHandler(),xPortSysTickHandler()函数中通过向中断和状态寄存器的bit28写入1来启动PendSV中断,具体PendSV中断服务函数是 PendSV_Handler,并且任务切换的具体任务是在PendSV中断服务函数中完成的。

c 复制代码
#define xPortPendSVHandler 	PendSV_Handler 

_asm void xPortPendSVHandler( void )
{
	extern uxCriticalNesting;
	extern pxCurrentTCB;
	extern vTaskSwitchContext;

	PRESERVE8

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

	/* Is the task using the FPU context?  If so, push high vfp registers. */
	tst r14, #0x10
	it eq
	vstmdbeq r0!, {s16-s31}

	/* Save the core registers. */
	stmdb r0!, {r4-r11, r14}

	/* Save the new top of stack into the first member of the TCB. */
	str r0, [r2]

	stmdb sp!, {r3}
	mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
	msr basepri, r0
	dsb
	isb
	bl vTaskSwitchContext  //在此处 调用函数vTaskSwitchContext() ,该函数用来获取下一个要运行的任务,并将 pxCurrentTCB更新为这个要运行的任务。
	mov r0, #0
	msr basepri, r0
	ldmia sp!, {r3}

	/* The first item in pxCurrentTCB is the task top of stack. */
	ldr r1, [r3]
	ldr r0, [r1]

	/* Pop the core registers. */
	ldmia r0!, {r4-r11, r14}

	/* Is the task using the FPU context?  If so, pop the high vfp registers
	too. */
	tst r14, #0x10
	it eq
	vldmiaeq r0!, {s16-s31}

	msr psp, r0
	isb
	#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
		#if WORKAROUND_PMU_CM001 == 1
			push { r14 }
			pop { pc }
			nop
		#endif
	#endif

	bx r14  //至此,任务切换成功。
}

在PendSV中断服务函数中实现了一下的功能,首先保存现场,然后调用了函数vTaskSwitchContext()来获取下一个要运行的任务,也就是查找已经就绪了的优先级最高的任务,最后切换新的任务。

相关推荐
远望创客学堂8 小时前
【单片机毕业设计选题24047】-基于阿里云的工地环境监测系统
stm32·单片机·嵌入式硬件·阿里云·云计算·课程设计·arduino
极客小张8 小时前
利用 STM32 实现多协议物联网网关:Modbus/Zigbee 到以太网/Wi-Fi 的数据桥接
stm32·单片机·嵌入式硬件·物联网·网络协议·https·硬件工程
@一二三四五10 小时前
STM32 看门狗 HAL
stm32·单片机·嵌入式硬件
快秃头的码农15 小时前
STM32-HAL-FATFS(文件系统)(没做完,stm32f103zet6(有大佬的可以在评论区说一下次板子为什么挂载失败了))
stm32·单片机·嵌入式硬件
嵌入式详谈20 小时前
STM32智能家居安防系统教程
stm32·嵌入式硬件·智能家居
YONYON-R&D20 小时前
STM32中的I2S(Inter-IC Sound)接口和SA接口(Serial Audio Interface)的区别
stm32·单片机·嵌入式硬件
heater4041 天前
【STM32标准库】USART+DMA
stm32·单片机·嵌入式硬件
OpenAnolis小助手2 天前
正式邀测! OS Copilot——一款基于大模型构建的 Linux 智能操作系统助手
运维·操作系统·龙蜥社区·智能操作系统助手·os copilot
小小怪下士的编程小屋2 天前
stm32中断
c语言·stm32·单片机·嵌入式硬件
ooolmf2 天前
蓝牙模块的使用01,OOOLMF蓝牙模块HC05调试使用01AT设置从机,手机用软件对接
stm32·单片机·51单片机