stm32外设笔记-freertos配置(三)

前面的提到了关于FreeRtos的任务的挂起与恢复,消息队列,软件定时器等内容,今天就继续介绍其他几个参数吧!

1、任务通知

这里基本的还是配置按键作为事件触发,然后LED作为展示,cubemx中配置如下所示:
在这里插入图片描述
下一步我们来配置任务,这里使用默认的任务即可,当然我这里新建了一个任务但是没有用到
在这里插入图片描述
第二个部分就是中断的切换这里不要的影响好像不是很大,没什么大的问题,因为这里是中断中发布,所以用的函数不太一样
在这里插入图片描述
在设置另一个函数用来接收,这里是收到通知就就会有反应,还有一个函数是收到通知的内容,详情可以查看一些官方教程和二维码
在这里插入图片描述
最终我们将程序下载到开发板就可以看到效果了,按下我们led之后,就可以看到电平翻转。

2、消息队列打印串口数据

消息队列就是通过 RTOS 内核提供的服务,任务或中断服务子程序可以将一个消息放入到队列。

同样, 一个或者多个任务可以通过 RTOS 内核服务从队列中得到消息。注意这里消息队列传递的是真正的数据,不是和其他RTOS一样传递的地址信息,通常, 先进入消息队列的消息先传给任务,也就是说,任务先得到的是最先进入到消息队列的消息,即先进先出的原则( FIFO) , FreeRTOS的消息队列支持 FIFO 和 LIFO 两种数据存取方式。

在这里消息队列和数组很像,我们使用消息队列要注意,一般我们在裸机中需要一个变量北反复使用一般就直接定义相关的数组了,但是对于RTOS消息队列则更好,优点总结如下:

  • 使用消息队列可以让 RTOS 内核有效地管理任务, 而全局数组是无法做到的,任务的超时等机制需要用户自己去实现。
  • 使用了全局数组就要防止多任务的访问冲突, 而使用消息队列则处理好了这个问题, 用户无需担心。
  • 使用消息队列可以有效地解决中断服务程序与任务之间消息传递的问题。
  • FIFO 机制更有利于数据的处理。

关于FIFO的数据存取可以看下面的动图
在这里插入图片描述
这里我们还是用上面的两个任务来进行数据的收发,同时我们可以看到就是cube中其实可以配置消息队列 的函数,这里我们先不进行配置,直接在代码中来实现,这个等之后在图形化配置。
在这里插入图片描述
下面我们首先还是新建一个消息,如下所示
在这里插入图片描述
创建句柄如下

在这里插入图片描述
这里我们在一个任务中发送消息,并准备另一个任务用于接收任务
在这里插入图片描述
将程序下载到开发板,效果如下所示:

在这里插入图片描述
下面我们来尝试使用cube的图形化来配置信号量
在这里插入图片描述
下面是新建消息队列
在这里插入图片描述
在任务中发送函数如下所示

在这里插入图片描述
在另一个任务中接收函数
在这里插入图片描述
将程序下载到开发板,效果如下所示:
在这里插入图片描述

3、打印任务执行情况

1、打印任务占用的内存

我们可以使用打印任务状态用来查看任务执行情况,这里将程序下载到开发板,可以看到效果如下所示
在这里插入图片描述

参数说明:

  • 第一列为任务名称
  • 第二列为任务的状态(状态说明可见下面的表格)
  • 第三列为任务的优先级
  • 第四列为任务的剩余栈空间(空间利用率就可以根据这个查看)
  • 第五列为任务的创建顺序
X running
B blocked
R ready
D deleted
S suspended

这样需要先配置一些宏,主要是任务追踪的宏,全部设置为enable
在这里插入图片描述
然后我们初始化一个定时器用于计数
在这里插入图片描述
这里我们需要开启中断计数
在这里插入图片描述
在tim.c中加入如下代码用于计数
在这里插入图片描述
代码如下:

volatile unsigned long long FreeRTOSRunTimeTicks=0;

__weak void configureTimerForRunTimeStats(void)
{
    
    
	HAL_TIM_Base_Start_IT(&htim6);
	FreeRTOSRunTimeTicks = 0;
}

__weak unsigned long getRunTimeCounterValue(void)
{
    
    
	return FreeRTOSRunTimeTicks;
}

然后在中断回调加入计数,对上面定义的全局变量进行计数
在这里插入图片描述
代码如下:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    
    
  /* USER CODE BEGIN Callback 0 */

  /* USER CODE END Callback 0 */
  if (htim->Instance == TIM7) {
    
    
    HAL_IncTick();
  }
  /* USER CODE BEGIN Callback 1 */
  if (htim->Instance == TIM6) {
    
    
//    HAL_IncTick();
	FreeRTOSRunTimeTicks++;
	}
  /* USER CODE END Callback 1 */
}

在任务中加入如下函数
在这里插入图片描述
打印结果如下
在这里插入图片描述

2、打印任务对cpu的利用率

我们单片机一般都是单核的,那么系统调度的时候用的其实就是cpu不算的在任务之间进行切换,但是有的任务可能就会占用过高的资源,然后有的任务就没有这么高的占用,但是这个占用可能是异常的,就像任务死机了一样,因此我们就很有必要去监控CPU的这个占用率了!,调试的时候很有必要得到当前系统的CPU利用率相关信息,但是在产品发布时,就可以去掉CPU利用率统计功能,以避免消耗系统资源。

整个过程的思路大概如下:

**FreeRTOS 是使用一个外部的变量进行时间统计,并且消耗一个高精度的定时器,其用于定时的精度是系统时钟节拍的10-20倍。**这里选择一个50us的之中,上面已经配置过了,这里要注意的就是计数变量的累加在freertos里面:
在这里插入图片描述
这个东西千万不要放在其他地方测试,不然就会失效,就会获取不到任务信息,然后就会打印一个空的字符串,具体现象为
在这里插入图片描述
这样之后我们就可以打印我们需要的信息了,我们把他放到一个专门的任务里面
在这里插入图片描述
源码如下:

  for(;;)
  {
    
    
		memset(InfoBuffer, 0, 400);
		vTaskGetRunTimeStats((char*) InfoBuffer);
		printf("Name      Abs Time    Time\r\n");
		printf("******************************************************\r\n");
		printf("%s", InfoBuffer);
		printf("******************************************************\r\n");
	        
	  osDelay(1000);
  }

最终打印的结果如下所示:
在这里插入图片描述

这里简单的做下说明,因为其他任务啥也没干,基本就是转转led,所以占用的资源就很少,这样我们系统的富余资源就比较多了

猜你喜欢

转载自blog.csdn.net/m0_51220742/article/details/123516462