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()来获取下一个要运行的任务,也就是查找已经就绪了的优先级最高的任务,最后切换新的任务。

相关推荐
逐步前行5 小时前
STM32_标准库结构
stm32·单片机·嵌入式硬件
Hello_Embed5 小时前
libmodbus STM32 主机实验(USB 串口版)
笔记·stm32·学习·嵌入式·freertos·modbus
不做无法实现的梦~6 小时前
PX4各个模块的作用(3)
linux·stm32·嵌入式硬件·机器人·自动驾驶
不能跑的代码不是好代码6 小时前
STM32独立看门狗(IWDG)知识点及标准库使用指南
stm32·嵌入式硬件
Trouvaille ~7 小时前
【Linux】进程间关系与守护进程详解:从进程组到作业控制到守护进程实现
linux·c++·操作系统·守护进程·作业·会话·进程组
-Springer-7 小时前
STM32 学习 —— 个人学习笔记5(EXTI 外部中断 & 对射式红外传感器及旋转编码器计数)
笔记·stm32·学习
_OP_CHEN8 小时前
【Linux系统编程】(二十九)深度解密静态链接:从目标文件到可执行程序的底层魔法
linux·操作系统·链接·文件系统·c/c++·静态链接
xuxg20051 天前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT1 天前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen1 天前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制