当前位置: 首页 > news >正文

freetros 信号量使用方法实例解析

1. 相关函数介绍

  • osSemaphoreNew:创建并初始化一个信号量对象。
  • osSemaphoreGetName:获取信号量对象的名称。
  • osSemaphoreAcquire:获取信号量令牌,如果当前没有令牌,则超时放弃。
  • osSemaphoreRelease:释放一个信号量令牌,直到初始最大计数。
  • osSemaphoreGetCount:获取当前信号量令牌计数。
  • osSemaphoreDelete:删除信号量对象。

2. 实例代码

// 定义信号量句柄和控制块等
osSemaphoreId_t myCountingSem01Handle;
osStaticSemaphoreDef_t myCountingSem01ControlBlock;
const osSemaphoreAttr_t myCountingSem01_attributes = {
  .name = "myCountingSem01",
  .cb_mem = &myCountingSem01ControlBlock,
  .cb_size = sizeof(myCountingSem01ControlBlock),
};

// 创建信号量的函数
void initTask( void ){ 
  // 创建计数信号量,初始值和最大值都为3
  myCountingSem01Handle = osSemaphoreNew(3, 3, &myCountingSem01_attributes); 
}

// 释放信号量的任务函数
void mainTask(void *argument){ 
  int cnt;
  osStatus_t sem_osStatus;
  for(;;) {
    // 释放计数信号量
    sem_osStatus = osSemaphoreRelease(myCountingSem01Handle); 
    if( sem_osStatus == osOK ){
      printf("mainTask: osSemaphoreRelease \r\n");
      // 获取当前的计数值
      cnt = osSemaphoreGetCount(myCountingSem01Handle); 
      printf("mainTask osSemaphoreGetCount: %d \r\n", cnt);
    }
    osDelay(30);
  }
}

// 获取信号量的任务函数
void monitorTask(void *argument){ 
  osStatus_t sem_osStatus;
  int cnt;
  for(;;) {
    // 获取计数信号量,等待超时时间为100
    sem_osStatus = osSemaphoreAcquire(myCountingSem01Handle, 100); 
    if( sem_osStatus == osOK ){
      printf("monitorTask: osSemaphoreAcquire \r\n");
      // 获取当前的计数值
      cnt = osSemaphoreGetCount(myCountingSem01Handle); 
      printf("monitorTask osSemaphoreGetCount: %d \r\n", cnt);
    }
    osDelay(10);
  }
}

3. 代码解析

  • 首先,定义了myCountingSem01Handle作为信号量句柄,myCountingSem01ControlBlock作为静态信号量控制块,myCountingSem01_attributes用于设置信号量的属性,包括名称、控制块内存和大小。
  • initTask函数中,使用osSemaphoreNew函数创建了一个名为myCountingSem01的计数信号量,初始值和最大值都为 3。
  • mainTask函数中,通过osSemaphoreRelease不断释放信号量,并在释放成功后使用osSemaphoreGetCount获取当前信号量的计数值并打印。
  • monitorTask函数中,通过osSemaphoreAcquire尝试获取信号量,设置了超时时间为 100。如果获取成功,同样使用osSemaphoreGetCount获取当前计数值并打印。

4. 测试结果

  编译代码并下载到板卡上运行后,根据计数信号量的定义,当Task获取到信号时,计数值会减一;当Task释放信号时,计数值会加一。通过打印的日志信息可以验证信号量的使用是否符合预期。例如,mainTask释放信号量后计数值增加,monitorTask获取信号量后计数值减少。

相关文章:

  • 【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 的自动配置:约定优于配置的设计美学
  • 激光雷达点云改善汇总
  • FastGPT原理分析-数据集创建第一步
  • Java学习第十二天--集合
  • Fisher信息、梯度方差与学习率调度器的计算流程
  • 3.17[Q]CV Bézier curve
  • TCP简单链接的编程实现
  • 使用vue3+el-form实现动态新增名称,值,并对名称进行必填校验
  • 电脑如何录屏
  • 华为OD机试 - 仿LISP运算 - 逻辑分析(Java 2023 B卷 200分)
  • C语言之 循环语句:程序运行的核心动力(上)
  • 一键批量txt转DWG,DWG转txt——插件实现 CAD c#二次开发
  • 消失的密文
  • 消息队列,阻塞队列的实现
  • 免训练指标(Zero-Cost Proxies)
  • JavaScript字符串处理
  • Spring 编程式事务管理实现
  • Redis 服务器:核心功能与优化实践
  • 深入解析Java面向对象三大特征之多态、final、抽象类与接口
  • 【芯片验证】面试题·对深度为60的数组进行复杂约束的技巧
  • “11+2”复式票,宝山购彩者领走大乐透1170万头奖
  • 睡觉总做梦是睡眠质量差?梦到这些事,才要小心
  • 技术派|更强的带刀侍卫:从054B型战舰谈谈世界护卫舰发展
  • 工人日报评规范隐藏式车门把手:科技美学须将安全置顶
  • 新华时评:中美经贸会谈为全球经济纾压增信
  • 央行:中国政府债务扩张仍有可持续性