FreeRTOS的任务(Task)与信号量(Semphaoretake)互斥

一直以来,对FreeRTOS的使用与教程看了好多个系列教程,操作了很多原始代码,都没有很好的理解与掌握。今天终于全面理解了这几个东西的作用与使用方法了,并将它们进行了极简单化的改造并跑了起来。

一、它们之间的关系:

在FreeRTOS中队列(Queue)、信号量(Semaphore)、任务(Task)是核心组件,但他们设计目标、功能、任务、使用场景截然不同,不能随意互换。在 FreeRTOS 中,队列(Queue)、信号量(Semaphore)和任务(Task)是核心组件,但它们的设计目标、功能和使用场景截然不同,不能随意相互替换。以下是具体分析:

  • 1. 核心区别
  • (1)任务(Task)
  • • 本质:是操作系统调度的基本单位,是一段独立运行的代码(函数),拥有自己的栈空间和运行状态(就绪、运行、阻塞等)。
  • • 作用:负责实现具体的业务逻辑(如数据处理、设备控制等),是系统功能的实际执行者。
  • • 特点:由 FreeRTOS 调度器管理,可根据优先级抢占 CPU 资源;任务之间相对独立,通过内核对象(队列、信号量等)通信。
  • (2)队列(Queue)
  • • 本质:是一种数据缓冲区,用于在任务之间(或任务与中断之间)传递数据(如数值、结构体、指针等)。
  • • 作用:实现任务间的数据交换,支持异步通信(发送方无需等待接收方立即处理)。
  • • 特点:
  • ◦ 采用 FIFO(先进先出)机制,也可配置为 LIFO(后进先出);
  • ◦ 数据通过“拷贝”方式传递(避免指针引用的安全性问题);
  • ◦ 可设置阻塞时间(发送/接收数据时,若队列满/空,任务可阻塞等待)。
  • (3)信号量(Semaphore)
  • • 本质:是一种同步/互斥机制,本质是一个“计数器”或“标志位”,不传递具体数据,仅用于传递“事件发生”的信号。
  • • 作用:
  • ◦ 同步:协调多个任务的执行顺序(如任务 A 完成后通知任务 B 开始);
  • ◦ 互斥:保护共享资源(如同一时间只允许一个任务访问硬件设备);
  • ◦ 计数:限制同时访问某资源的任务数量(如有限的缓冲区资源)。
  • • 分类:
  • ◦ 二值信号量(0 或 1,用于互斥或简单同步);
  • ◦ 计数信号量(计数器,用于资源计数);
  • ◦ 递归信号量(允许同一任务多次获取,避免死锁)。

二、在 FreeRTOS(以及大多数实时操作系统 RTOS)中,任务(Task)必须包含一个无限循环(while(1)或类似结构),否则任务会 立即执行完并退出,导致 任务被 FreeRTOS 自动删除,甚至可能引发 系统不稳定或崩溃。

以下是最简单的示例代码了:注:必须有 vTaskDelete(NULL);

#include <Arduino.h>          // 必须!用于 Serial 和 setup()/loop()#include <FreeRTOS.h> // 必须!用于 FreeRTOS 函数
#include <task.h>     // 必须!用于任务相关定义
#include <stdio.h>             // 可选!用于 printf(但 Arduino 的 Serial 更常用)

void setup() {
  Serial.begin(115200);

  xTaskCreate(
    blink1, "Blink 1", 8192, NULL, 1, NULL);
  xTaskCreate(
    blink2, "Blink 2", 8192, NULL, 1, NULL);
}

void blink1(void *parameter) {
  printf("this is task_1\n");
  vTaskDelay(pdMS_TO_TICKS(1000));  // FreeRTOS 延迟 500ms
  vTaskDelete(NULL);
}

void blink2(void *parameter) {
  printf("this is task_2\n");
  vTaskDelay(pdMS_TO_TICKS(5000));  // FreeRTOS 延迟 500ms
  vTaskDelete(NULL);
}

void loop() {
}

三、FreeRTOS信号量(Semaphoretake) 与互斥

如果任务访问相同的资源,例如外部传感器,EEPROM,ADC,串行通信等,则它们可能会互相干扰。如果可能发生这种情况,那么必须将任务同步(在协调的意义上,而不是同时)

#include <Arduino.h>          // 必须!用于 Serial 和 setup()/loop()
#include <FreeRTOS.h>         // 必须!用于 FreeRTOS 函数
#include <freertos/task.h>    // 必须!用于任务相关定义(如 xTaskCreate)
#include <freertos/semphr.h>  // 必须!用于信号量(SemaphoreHandle_t, xSemaphoreCreateBinary)

SemaphoreHandle_t sem;  // Create semaphore handle

void setup() {
  Serial.begin(115200);
  sem = xSemaphoreCreateBinary();  // Create binary semaphore
  xSemaphoreGive(sem);

  xTaskCreate(
    blink1, "Blink 1", 2048, NULL, 1, NULL);
  xTaskCreate(
    blink2, "Blink 2", 2048, NULL, 1, NULL);
}

void blink1(void *parameter) {
  while (1) {
    for (int i = 0; i < 10; i++) {
      xSemaphoreTake(sem, portMAX_DELAY);
      printf("this is task_1_%d\n", i);
      xSemaphoreGive(sem);
      vTaskDelay(pdMS_TO_TICKS(1000));  // FreeRTOS 延迟 500ms
    }
  }
  vTaskDelete(NULL);
}

void blink2(void *parameter) {
  while (1) {
    for (int i = 0; i < 10; i++) {
      xSemaphoreTake(sem, portMAX_DELAY);
      printf("this is task_2_%d\n", i);
      xSemaphoreGive(sem);
      vTaskDelay(pdMS_TO_TICKS(1000));  // FreeRTOS 延迟 500ms
    }
  }
  vTaskDelete(NULL);
}

void loop() {
}

“小小桌”即将成功开发完

近期完成PCB制作与代码软件写入,完成了对温湿度传感器的验证、GPS模块的验证、一氧化碳传感器验证、甲醛传感器验证、天气时钟的获取等功能。基本完成了第一块PCB功能板的制作。虽然经过很多困难与坑,但终于走出来了!开心

为解决SPI点屏的问题,用逻辑分析仪居然发现有些ESP32的模块存在BUG耽误了我近2个月的进度,不过这两个月也在慢慢学习C语言,真是非常复杂的系统工程。

GPS模块RTK

逻辑分析仪

废置工程板:

近期完成了步进电机的驱动与海康威视球头

首先,步进电机的驱动,在自己摸索下已经取得成功。但同时发现这个东西的深度有点难。要想启用它、用好它都是有成熟的方案,但下一步如何让它控制“随心所欲”还是需要时间来研究。刚开始,我的电机只会颤抖。后来发现是信号频率存在问题,修正后顺利转动,也算是走出了第一步,为未来精确控制它下功夫有了信心。

其次,海康威视的球头与电脑对接已经完成,但参数的获取:在写了几封信给海康威视的工程部门,一直要公司名称、联系方式,很烦。过程中,一个单片机群高手给了我很大帮助,本来这种摄像头是AC电源输入,但请教了相关设计者后建议我在仅有DC直流情况下大胆使用,他们设计产品时都会考虑直流与交流问题……在接通直流24V的情况下果然能顺利使用。然后就是软件对接……

完成单片机Arduino平台与Thonny平台的布署

在做机器视觉的同时,由于无法时时得到相机的焦距f,所以又想了一个办法是否可以自动对齐目标,加上激光测距仪进行自动测距呢?所以就有了搞一个单片机自动捕捉对像,自动转向,自动激光测距的想法。然后可以通过测得的距离反算各像素点“各点之间的距离”。这个笨办法可以实现精确的测距,又能得到一套自动化的设备,可谓一举两得,但开发难度有点大。最近看到单片机ESP32芯片的Wifi功能,控制功能,以及对Micro Python的支持让我口水止不住。(于是说干就干,弄了两个芯片的开发板,尽管我对芯片电路开发一无所知)

今天终于将两个平台的固件测试环境搞定了,对于专业开发单片机的人来说,应该是手到擒来,我这个外行可能走了两天弯路。个人感觉比较好安装的是Arduino的环境比较友好,据说库也比较全,但大部分都是C与C++的开发,当然也能安装Micro Python,后面如果有时间也可以试试。

对于Thonny平台能支持Miro Python的平台是我比较喜欢的,开发速度快!但安装着实卡了我两天时间,期间碰到了“ESP32 s3 PSRAM ID read error: 0x00ffffff”错误。

原因是ESP32-S3R8模块内置的RSRAM 为八线模式PSRAM(OCTAL MODE PSRAM)
在menuconfig中配置

于是拼了老命去找menuconfig的配置修改办法,挣扎了两天,无果。

后来看到有刷固件的时候,别人找的固件似乎和我自动在网上烧录的不一致,于是乎手动下载了适配的RSRAM版本,果然烧录进去,运行良好~!在此做一个笔记。

新买的步进电机:共了300多元,唷,饭钱没了……

找回自己以前买的激光测距模块:(50米测距精度 +-0.1mm大约)不知道能不能融合成功……现在只是假想。

3D打印也跟上:(各模块外壳设计与制作已经不用发愁)

总之,随着开发的深入,如果单片机能够取得成功,那么未来可以做很多事情,不再限于土木工程。结合机器视觉,也许能做一个非常实用的单品。

接下来,就是用单片机:点个灯~!多个灯~!

第三步:驱动电机~各种感应器!

完成Yolov5与Yolov8对人物、控制点检测与测距

通过Yolov5与v8的验证“精确找到人与物体”是可行的,而且效果非常好。接下就是要进行测量计算了,通过这两天研究也将相关计算找到了突破口,并完成了计算案例的复现。非常顺利和丝滑。现在要完成精确的测距计算,还需要完善算法与对应参数的修正,应该是决定这个测距功能的重大工程了!要完成精确测距算法,已经有了被步实现的想法,需要进一步深度研究一下OpenCV的功能,还有视屏矫正技术,我的初步想法是:将已知几何空间位置与《标准参照点》的距离进行相似算法,应该可以实现这个功能。

近期取得的成果:

1、完成了物体查找与测距的Demo,并顺利运行;

2、找到了测距的接口和思路,但可能需要自己重写算法;

接下来,在自己写的算法上取得距离测量的精度上,测量方法上的突破,有信心~!加油~!欧利给。

完成了Yolo5对隧道内的人员与控制点进行识别

相当于一个大作业,但也只完成了项目应用落地的一部分工作。

具体内容如下:

1、布署完成了Yolo5对图像的识别与视屏的识别架构;

2、完成了隧道工程内部人物person、控制点pt的标注与模型训练;

3、应用自己训练的模型进行视屏识别;

4、再应启用自己编写过的PyQt5,在界面内对照片、视屏进行识别。

结论:

1、人物识别较好,控制点目标太小,需要进一步改进(重点);

2、对工程的代码需要进一步理解才能写出自己算法;

3、对工程应用“绝对变形”在思维上进一步进行构架,如何选取参照来实现判断需要进一步试验;

4、需要进一步研究Yolo8案例当中单目视距测量的问题(这个大部分博客需要付费);

5、需要考虑conda的环境移植问题,以后相关应用要转移到其它机器内如何实现快速布署问题需要解决;

虽然还有需要改进的地方,但首次训练自己的模型,并能识别,本来由于pt像素太小,已经报着失败的准备。

最后:

非常遗憾,我对PHP不感冒,也不再准备进修PHP准备投入到Django或者Flak平台更容易对接Python的数据交换,同时对ComfyUI功能喜欢,希望能在线搞一套出来。于是Wordpress的站点,看来得花时间移植,这也将是一个大工程。以前的笔记在过程当中,不能搞丢呀~!汗。自定义的网盘已经把数据搞丢两次了~!

解决了网站SSL许可证的问题

网站的SSL许可证一直因为个人网站没有得到重视,最近发现部分浏览器没有SSL许可证的话会被设置成为“不安全的网站”,所以花了两天时间申请了一个网站的SSL许可证。并通过宝塔服务器进行了设置->WordPress界面设设https后终于解决了这个最后问题。在这里做一下笔记,便于以后个人的维护。唯一的遗憾就是SSL证书三个月有效期,到时间得维护。

由于WordPress用的是PHP写制,和Django有些出入,但CSS基本相通。顺手把公信部备案号底部公示位置也修改了一下,完美。

从使用语言来看,我还是偏向于用Django做网站,可自己定义的东西,自己写比较好。如果要做自己的AI界面的话,对WordPress没有太多的时间再来看一遍底层构架和代码。相比能用Python平台矩阵计算pytorch对数据进行操作更顺手一些吧。

笔记一:布署SSL后的网站图片不能正确显示解决:

在主题文件的 functions.php(WP后台“外观”-“编辑”右侧可以找到)里加入如下代码(注意域名需要做相应修改)

function replacehttp($content){ if( is_ssl() ){ $content = str_replace(‘http://域名/wp-content/uploads’, ‘https://域名/wp-content/uploads’, $content); } return $content; } add_filter(‘the_content’, ‘replacehttp’);

笔记二:工信部备案号用CSS标签显示:

<div class="underline-text">
            <a href="https://beian.miit.gov.cn" target="_blank" rel="external nofollow noopener">滇ICP备20005124号-2</a>

            <a style='margin-left:40px' href="https://beian.miit.gov.cn/" target="_blank" rel="external nofollow noopener">滇ICP备20005124号-3</a>

笔记三:多个域名与IP可以在网站内进行重定向:将IP与其它域名进行跳转
REWRITE-START

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^www.aiynmt.com [NC]
    RewriteRule ^(.*) https://www.aimtss.com$1 [L,R=301]
</IfModule>

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{HTTP_HOST} ^121.196.22.46 [NC]
    RewriteRule ^(.*) https://www.aimtss.com$1 [L,R=301]
</IfModule>

REWRITE-END

AIMTSS取得了软著

今天看了一下申请页面,终于得到了软件著作权。接下来准备将隧道围岩收敛算法研究一下,看能不能突破成了软件专利。

今年要做的事情真多,计划完成一个课题80%;计划完成AICG的营利活动持续更新;计划专业提升;计划Django再开一个页面。

如果要节约成本的话,可以考虑这个网站与Django进行合并,但风险太大,很多笔记可能说没就没了……再开一个服务器,一年800多的费用有点纠结。

总是有非常重要知识出现,需要不断前进

AI在本年度发展的速度是越来越快,快到各类大语言模型的出现,我连测试和下载的时间都忙不过来,更别提去深入训练它们。在图像领域初步炼制Lora的经验告诉我,进行大语言模型的微调,不会和我炼制Lora有多大的困难了,真正的需要的是再沉下心来深入一下即可。

图像领域的绘图,逐渐深入学习到炼丹,再从炼丹又返回来学习OpenCV感觉都十分有用,并具好玩。然后又从3D方向不断探索,从Stable Diffusion至它的ComfyUI,不断更新的插件与Adadapt,以及视屏流的处理AnimateDiff的应用,并安装插件和多个Python环境下进行配置。我已经将所有python环境应用与配置搞得很清楚了。这种过程,也许是很多人学习路线必须要走的路吧。

现在仍然感觉到Django的重要性,因为没有一个好的前端,后端很多数据都没有办法“流动”与展示,时间真的很不够用。

AIMTSS的著作权

AIMTSS开发已完成一个阶段,还存在很多问题。但软件偿试申请著作权也是第一次,菜鸟认真填写,然后就是慢慢等待。通过接近1个半月的等待,今天收到补正通知,希望这次能过。