Freertos Trace任务可视化分析(三)互斥量 SystemView

本文详细解析了FreeRTOS中任务切换的过程,结合SystemView工具进行事件记录,探讨了systick中断、任务优先级、延迟与阻塞、调度器开销以及互斥量的优先级继承机制。通过具体代码示例展示了任务执行与上下文切换的细节,强调了实时操作系统中的时间精确性和效率优化的重要性。
摘要由CSDN通过智能技术生成

SystemView 记录Trace通过Event进行事件记录。
举个简单的例子
prvAddCurrentTaskToDelayedList函数中
traceMOVED_TASK_TO_DELAYED_LIST();
Freertos内核代码中有很多traceXXX的函数,SystemView重新定义这些函数。
SEGGER_SYSVIEW_FreeRTOS.h

#define traceMOVED_TASK_TO_DELAYED_LIST()           SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB,  (1u << 2))
#define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST()  SEGGER_SYSVIEW_OnTaskStopReady((U32)pxCurrentTCB,  (1u << 2))
#define traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB)    SEGGER_SYSVIEW_OnTaskStopReady((U32)pxTCB,         ((3u << 3) | 3))

当Freertos的tracexxxxxx函数运行的时候,会执行SEGGER_SYSVIEW定义的trace函数。把对应的 事件写入到指定的事件缓冲区域。所以我们可以人为去增加trace的位点。调试器会读取内存区域的数据传输到PC上,完成图形界面的变化。

trace大致的工作原理就是这样。
1.记录的是tracexxxx,所有没有trace函数的地方不会有trace
2.事件时间不是非常的精确,但是一定程度上已经非常够用了。

代码如下,这里建立两个任务LED0_Task ,LED1_Task
SystemView 记录的文档 点击这里

  xTaskCreate(LED0_Task, "LED0_Blink", 128, (void*)NULL,4 , NULL);
  xTaskCreate(LED1_Task, "LED1_Blink", 128, (void*)NULL,5 , NULL);
LED0_Task 优先级4
LED1_Task 优先级5
void do_things(int i)
{	
    int k,n;
	for(n=0;n<i;n++)
	{
		k=0;
		while(k<655)
		{
			k++;
		}
	}
		
}

static void LED0_Task(void *args) {
  while (1) {
  	
	xSemaphoreTake(mutex_1, 0xffff);

	do_things(10);
	xSemaphoreGive(mutex_1);
	vTaskDelay(4);
	
  };
}
static void LED1_Task(void *args) {
  while (1) {
  	
  	vTaskDelay(2);
	xSemaphoreTake(mutex_1, 0xffff);
	do_things(10);
  	
    xSemaphoreGive(mutex_1);
  
  };
  
}

运行程序,进行记录
在这里插入图片描述
sysTick ,是ARM cortex-M3内核专门用来提供操作系统tick的定时器,Freertos在调度器的初始化中对它的间隔进行了设定。上图可以看到每个systick 1ms运行一次,每一次运行都会打断用户函数的运行,并且systick handler处理函数执行也需要花费时间。
在这里插入图片描述
这里需要耗费23us的时间执行。
在这里插入图片描述
先看Event 这个时候LED1任务接收了队列,对应大码是line85,获取互斥量。然后执行do_things。
在这里插入图片描述
经过了多个systick LED1任务释放了信号量,跳回while(1)开头的taskdelay(2),也就是说任务要进入阻塞状态,任务的切换是由调度器完成的。可以看到调度器的执行也需要耗费时间
在这里插入图片描述
下一个事件,LED0任务获取了 互斥量,开始执行dothings。
在这里插入图片描述
dothings(10)还没完成。systick计数器+1,LED1的Delay2超时解除阻塞状态。调度器执行上下文切换LED1任务执行。
在这里插入图片描述
箭头时刻,LED1 尝试获取互斥量,这时互斥量的拥有着LED0 继承优先级,那么LED0优先执行。
在这里插入图片描述
直到下一个时刻LED0 do_things(10);执行完成释放互斥量。这个时候优先级回复成原始优先级 。LED1是最高优先级,马上切换运行,获取互斥量。
在这里插入图片描述
下一个时间,LED1释放了互斥量进入taskdelay(2),那么任务LED0运行执行delay(4).这个时候所有的用户任务都在阻塞状态,那么空闲任务Idea task运行。
在这里插入图片描述
下一个时刻LED1 的Taskdelay(2) 完成切换LED1运行。

上面的过程可以理解以下内容
1.任务的切换需要CPU运行一段时间的调度器任务
2.systick周期性的唤醒短暂的打断正在运行的任务
3.systick,调度器的设计要精简,减少耗时
4.taskdelay计数依赖systick 计数误差1 tick
5.互斥量的优先级继承机制
6.Freertos的 API可以直接发起PendSV,进行上下文切换,不需要在下一个systick来触发

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值