基于STM32F407的FreeRTOS学习笔记(12)

发布者:psi33最新更新时间:2024-04-02 来源: elecfans关键字:STM32F407  FreeRTOS 手机看文章 扫描二维码
随时随地手机看文章

在上一期内容中我们简单的介绍了任务通知的几个函数以及简单的使用了任务通知来实现两个信号之间的通信


本期我们将利用任务通知来模拟三种方式的任务间通信。


信号量

在我们介绍信号量的文章中介绍过,信号分为二进制信号量和计数信号量。

接着我们使用任务通知来模拟这两项功能。

二进制信号量可以看作长度为1的队列,我们不关心其值为多少,只关心它的状态。

图片

图片

在直达任务通知中我们可以用xTaskNotifyGive来模拟二进制信号量的释放以及ulTaskNotifyTake()来模拟二进制信号量的读取。

在ulTaskNotifyTake()中需要注意的是,我们需要设置一个参数用来确定我们模拟的是二进制信号量还是计数信号量。

图片

image.png?imageView2/2/w/1000

代码测试


void Mid_Task(void * pvParameters)//参数为 void * pvParameters

{

  while(1)

  {

    if(KEY_Scan(0)==1)

    {

      printf('Key_Pressrn');

      xTaskNotifyGive(High_Handler);//传入任务函数句柄,模拟信号量释放

    }

  }

    vTaskDelay(10);

}



void High_Task(void * pvParameters)

{

  BaseType_t err;

  while(1)

  {

    err = ulTaskNotifyTake(pdFALSE,10);//读取后清零,模拟二进制信号量

    if(err == pdTRUE)

    {

      printf('Recieve Message!rn');

    }

    vTaskDelay(10);

  }

}


模拟二进制信号量成功。

之后,我们将接收的函数中的pdFALSE修改为pdTRUE,这样子我们就可以模拟我们的计数信号量了。

这里就不作演示了,但是要注意的是,只用这样子的模拟二进制信号量也要注意优先级反转问题,关于优先级反转的问题可以参考公众号中的关于二进制信号量的文章。

事件组

合理的运用RTOS中的事件组可以很好的处理许多事件,在事件组的介绍中我们说过,我们常用的事件组可以做到24位事件位。而在直达任务通知中,我们也同样可以指定某些位的改变来实现事件组的效果。

图片

我们可以修改xTaskNotify中的eAction来将通知值作为事件组,修改特定位来实现事件位的效果。


代码测试


复制

void Mid_Task(void * pvParameters)//参数为 void * pvParameters

{

  int i = 0; 

  while(1)

  {

    if(KEY_Scan(0)==1)

    {

      printf('Key_Press keynumber : 1rn');

      xTaskNotify( (TaskHandle_t) High_Handler,//目标任务句柄

                   (uint32_t) 0x04,//第二位 00000100

                   (eNotifyAction) eSetBits);//位设置模式,模拟事件组

    }

    if(KEY_Scan(0)==2)

    {

      printf('Key_Press keynumber : 2rn');

      xTaskNotify( (TaskHandle_t) High_Handler,//目标任务句柄

                   (uint32_t) 0x08,//第三位  00001000

                   (eNotifyAction) eSetBits);//位设置模式,模拟事件组

    }

  }

    vTaskDelay(10);

}



void High_Task(void * pvParameters)

{

  BaseType_t err;

  uint32_t number;//存放通知值

  uint32_t Value;  //模拟事件组

  while(1)

  {

     err =  xTaskNotifyWait( (uint32_t) 0x0000,//不清理

                             (uint32_t) 0xffff,//清理当前

                             (uint32_t*) &number,//接收任务值

                             (TickType_t) 10 );//等待事件

    Value = Value | number ; //获得事件位

    if((Value&(0x08+0x04)) == (0x08+0x04))

    {

      printf('KEY1 and KEY2 have Pressedrn'); 

      Value = 0;//事件组清零

    }

    vTaskDelay(10);

  }

}

图片

关键字:STM32F407  FreeRTOS 引用地址:基于STM32F407的FreeRTOS学习笔记(12)

上一篇:stm32一个强制类型转换死机bug解读
下一篇:基于STM32F407的FreeRTOS学习笔记(8)

推荐阅读最新更新时间:2026-03-23 04:52

freeRTOS V10.0.1移植到STM32F407标准库 - 环境Keil5
最近因为工作需要用到FreeRTOS,其实开始本人内心是拒绝的因为自己只学习过UCOSIII还没实际上过什么大又复杂的工程,但是谁让FreeRTOS他是Free的呢公司成本考虑肯定是不会选择USOS的,这个道理就像公司内心深处不想给你涨工资一样。好了跑偏了言归正传,既然要用自然是要熟悉一下这个实时操作的内核的工作过程了,说道到里想起来自己当初学USOC时是把代码几乎进行了逐行的走读,最后因为各种原因都没能实际使用最后还是忘记了,所以我建议对于这一类的操作系统的学习还是重在API函数的用法学习上,不需要太对代码集体实现细节进行研究,时间成本高有这个时间建议移植一个系统进行一些应用实践是最有实际效果的。因此我现在就在践行自己的经验移植
[单片机]
<font color='red'>freeRTOS</font> V10.0.1移植到<font color='red'>STM32F407</font>标准库 - 环境Keil5
基于STM32F407FreeRTOS学习笔记(10)
在介绍二进制信号量时曾经讲过,二进制信号量可以代替我们裸机开发中的标志位来使用。在裸机开发中我们使用标志位来表示某个事件是否发生,并且其他程序利用标记位的状态来判断程序是否可以继续进行。但是这种大量使用标记位的情况会导致代码的逻辑异常的复杂。 虽然使用二进制信号量可以很好的实现标志位的实现以及相应的任务安排,但是二进制信号量并不适用于大量的标志位。因为一个二进制信号量只能表示一个事件,假如我们的程序有大量的事件那有没有办法不用二进制信号量可以很好的管理这些事件呢? 这就是本期介绍的内容:事件位和事件组 在FreeRTOS中我们把一个用作判断事件是否发生的情况作为事件位,用0或1表示。它可以用来表示一个事件是否发生。比如函数
[单片机]
基于<font color='red'>STM32F407</font>的<font color='red'>FreeRTOS</font>学习笔记(10)
基于STM32F407FreeRTOS学习笔记(4)
CPU工作的时候,各个任务运行会占用CPU的资源,在Windows系统中我们可以通过任务管理器来看各任务(进程)占用系统资源的情况。 那么,FreeRTOS怎么实现这个功能呢? 我们翻阅FreeRTOS官网,查询API文档,在内核控制函数部分找到了相关的函数。 文档指出实现运行时间功能需要配置外设定时器,即32板载定时器,计时器频率应为滴答计时器(1ms)的至少10倍。 传入参数为pcWriteBUffer,其实是一个char类型的数组用以存储相关信息。 我们现在工程上调用这个函数。 char informationbuff ; void Get_info(void * pvParameters) {
[单片机]
基于<font color='red'>STM32F407</font>的<font color='red'>FreeRTOS</font>学习笔记(4)
FreeRTOS移植-基于STM32F407
首先新建或找一个基于Keil的STM32基础工程,这里我已经创建好了一个STM32F407VET6的工程模板,工程结构如下图的第1步的矩形框内所示。 下面需要移植FreeRTOS了,将FreeRTOS的源码文件复制到工程文件夹中,一些用不到的文件可删除(哪些文件需要用到可参考 上一篇的源码结构分析部分),然后在Keil中也创建一个FreeRTOS目录,将c文件添加进工程,注意port.c来自于RDVS的ARM_CM4F,对应于移植到的SMT32F407硬件。 添加完c文件后,还要添加对应的h文件的搜寻路径,具体如下: 然后就可以编译了,先进行第1次编译: ......(省略显示若干行) FreeRTOSportabl
[单片机]
<font color='red'>FreeRTOS</font>移植-基于<font color='red'>STM32F407</font>
基于STM32F407和OV7670的低端视频监控系统
引言 本系统着眼于经济型视频监控系统,可应用于工业自动化设备、汽车安全驾驶、医疗设施或大楼供水、供电等系统的监控,应用前景广阔、成本低廉、系统简洁。 1 芯片简介 1.1 STM32F407简介 本系统采用的处理器是意法半导体公司的STM32F407,该处理器以32位Cortex—M4为内核,具有浮点运算功能的低端高速ARM,其内部集成了大量可供立即使用的资源,如TFT液晶显示器接口(Flexible Stactie Memory Control,FSMC)、摄像头接口(Camera Inter face)、DMA控制器等,方便且实用。 1.2 OV7670简介 OV7670是OmniVision公司基于CMOS VGA的图像
[单片机]
基于<font color='red'>STM32F407</font>和OV7670的低端视频监控系统
使用MicroPython开发STM32F407的CAN总线
首先烧录 .dfu 固件到你自己的开发板上,之后把串口 0 的两个引脚上拉。 // A9 is used for USB VBUS detect, and A10 is used for USB_FS_ID. 不然连接电脑后不会识别。 然后就可以尝试使用 CAN 总线了。我这里使用的是 CAN2(PB12 - CAN2_RX, PB13- CAN2_TX)。发送器使用 TJA1050,据说 1050 配合 STM32 使用的时候 1050 的供电需要使用 5V。 代码也很简单。三行就能发送出去了。默认的波特率是 28K。 from pyb import CAN can = CAN(2, CAN.NORMAL)can.sen
[单片机]
stm32F407(TJA1050)CAN通信成功--Apple的学习笔记
一,前言 最近我在公司玩单片机玩的不亦乐乎,好多开发板供我玩,总算MCU底层现在算告一段落。现在我又开始玩自己的开发板咯,之前stm32先移植了一个can,目的是测试买的TJA1050模块,以及自己买的canable设备。结果can不通,不过我用了公司开发板,验证了canable是正常的。TJA1050之前玩linux的时候也验证过是正常的。那么剩下的问题就是stm32我移植的can有问题。 二,瞬间解决问题 移植的can怎么会有问题呢?先猜测下复用引脚错误或者波特率选择的clock源不同导致波特率错误。果然看了code果然是这个原因。连示波器都不需要看了。 由于F429的主频为180M,而F407的主频为168M导致的原因。
[单片机]
UCOSII在STM32F407上的移植
1、ucosii移植准备工作 1.1准备基础工程: 移植的时候需要一个基础工程,为了方便起见我们就选取跑马灯实验,作为ucossii移植的基础工程。 1.2Ucossii源码: 1)Micrium官网下载 2)开发板光盘自带 2、Ucossii移植步骤 1)step1 在基础工程文件夹中先建立UCOSII文件夹,然后在基础工程中UCOSII下建立相应的文件夹:CONFIG、CORE和PORT。 2)step2 向core文件夹中添加文件, 3)step3 向CONFIG文件夹中添加文件, 4)step4 向PORT文件件中添加文件, 5)step5 将Ucosii源码添加到工程中,打开工程,选择 新建三个分组:
[单片机]
UCOSII在<font color='red'>STM32F407</font>上的移植
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved