FreeRTOS 任务、中断解读--zynq

本文深入解析了FreeRTOS中任务和中断的切换机制。在中断处理中,通过设置ulPortYieldRequired变量来决定是否在中断返回后进行任务切换。任务切换实际发生在中断返回的汇编代码中。而在代码中,通过调用portYIELD()函数触发软中断,实现任务的切换。此外,外设中断向量的初始化应在任务中进行,以避免影响Tick中断和系统调度。

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

FreeRTOS 任务、中断解读–zynq

1. 中断中如何进行任务切换

FreeRTOS在中断返回时判断ulPortYieldRequired变量的值,如果该值为true则执行进程切换,否则不执行。所以在中断中只看到了ulPortYieldRequired变量的赋值,没有看到任务的切换,实际切换是在中断返回后的汇编代码中实现的。

	FreeRTOS_IRQ_Handler:
  /* Return to the interrupted instruction. */
  SUB		lr, lr, #4

  /* Push the return address and SPSR. */
  PUSH	{lr}
  MRS		lr, SPSR
  PUSH	{lr}

  /* Change to supervisor mode to allow reentry. */
  CPS		#SVC_MODE

  /* Push used registers. */
  PUSH	{r0-r4, r12}

  /* Increment nesting count.  r3 holds the address of ulPortInterruptNesting
  for future use.  r1 holds the original ulPortInterruptNesting value for
  future use. */
  LDR		r3, ulPortInterruptNestingConst
  LDR		r1, [r3]
  ADD		r4, r1, #1
  STR		r4, [r3]
	LDR		r1, =ulPortYieldRequired ; /*判断该变量是否为True*/
  LDR		r0, [r1]
  CMP		r0, #0
  BNE		switch_before_exit

exit_without_switch:
  /* No context switch.  Restore used registers, LR_irq and SPSR before
  returning. */
  POP		{r0-r4, r12}

2. 代码中如何进行任务切换

代码中直接调用portYIELD(),实现任务切换,该函数实际为软中断指令,软中断中实现任务切换,portYIELD()定义如下:

 #define  portYIELD()  __asm volatile ( "SWI 0" ::: "memory" );
 //软中断中实现了任务切换
 FreeRTOS_SWI_Handler:
	/* Save the context of the current task and select a new task to run. */
	portSAVE_CONTEXT
	LDR R0, vTaskSwitchContextConst
	BLX	R0
	portRESTORE_CONTEXT

3 外设中断向量初始化

外设中断向量初始化必须启动一个Task,在Task中初始化。
原因:FreeRTOS的任务调度是由cpu 32bit private Timer的硬件定时器中断实现,在调用xPortStartScheduler()函数启动任务的时候会对中断寄存器进行重新配置,将Tick中断使能,映射中断处理函数,这个过程会将原来的中断寄存器值覆盖掉,因此只能在Task中初始化外设中断向量,同时注意保证中断寄存器其他位的数据不变,否则可能导致Tick不工作,整个系统无法执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值