FreeRTOS源码分析-异常处理

本文详细介绍了在 ARM Cortex-M 系列处理器上实现的任务调度机制,包括 SVC 处理器服务例程、首次任务启动过程、挂起服务例程处理以及系统滴答定时器中断处理等内容。这些内容对于理解实时操作系统如何在该系列处理器上运行至关重要。

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

__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. */
	mov r0, #0
	msr	basepri, r0
	orr r14, #0xd
	bx r14
}
/*-----------------------------------------------------------*/

__asm void prvStartFirstTask( void )
{
	PRESERVE8

	/* Use the NVIC offset register to locate the stack. */
	ldr r0, =0xE000ED08
	ldr r0, [r0]
	ldr r0, [r0]
	/* Set the msp back to the start of the stack. */
	msr msp, r0
	/* Globally enable interrupts. */
	cpsie i
	/* Call SVC to start the first task. */
	svc 0
	nop
}
__asm void xPortPendSVHandler( void )
{
	extern uxCriticalNesting;
	extern pxCurrentTCB;
	extern vTaskSwitchContext;

	PRESERVE8

	mrs r0, psp

	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
	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
	bx r14
	nop
}

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. */
	( void ) portSET_INTERRUPT_MASK_FROM_ISR();
	{
		/* 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;
		}
	}
	portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );
}
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     vPortSVCHandler           ; SVCall Handler
                DCD     DebugMon_Handler          ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     xPortPendSVHandler        ; PendSV Handler
                DCD     xPortSysTickHandler       ; SysTick Handler


 

 


 

### FreeRTOS 中的异常处理机制 FreeRTOS异常处理主要依赖于底层硬件的支持以及操作系统层面的任务管理和调度。当发生异常时,系统通常通过特定的中断服务程序(ISR)来响应并处理这些事件。 #### SysTick 异常处理 在基于 ARM Cortex-M 架构的微控制器上,SysTick 定时器被广泛用来触发周期性的操作系统的滴答定时器中断。每次 systick 中断发生后,会调用 `xPortSysTickHandler` 函数,在该函数内部执行如下动作: - 调用 `xTaskIncrementTick()` 来更新当前时间戳,并检查是否有任务应该解除阻塞状态[^3]。 如果此时存在更高优先级就绪态的任务,则不会立即在此处进行上下文切换;相反,这一步骤仅负责维护内核的数据结构。实际的任务切换发生在 PendSV (Pending Supervisor Call) ISR 中,这是因为在某些情况下可能不适合即时改变正在运行的任务——比如正处于临界区或中断嵌套期间。 #### 自定义异常处理器 对于应用程序开发者来说,可以通过编写自定义的异常处理逻辑来增强 FreeRTOS 对错误条件的反应能力。例如,可以在项目中加入全局未定义指令陷阱或其他类型的硬故障中断服务例程,以便捕获可能导致系统崩溃的情况。一旦检测到严重问题,可以选择采取诸如重启设备、保存调试信息或将控制权转移给安全模式等措施[^1]。 此外,还可以考虑集成第三方工具如 Segger's SystemView 或 Tracealyzer 这样的实时跟踪分析软件包,它们能够提供详细的执行流程日志和性能统计资料,有助于快速定位潜在的问题根源并优化应用行为。 ```c void HardFault_Handler(void) { /* 用户可在这里添加自己的代码 */ while(1); // 停留在这里直到复位或者其他干预 } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值