FreeRTOS实时操作系统信号量基础

yizhihongxing

下面我将通过以下几个方面,来详细讲解“FreeRTOS实时操作系统信号量基础”的完整攻略:

  1. 信号量是什么
  2. FreeRTOS的信号量及其基础API
  3. 信号量的使用示例说明
  4. 进一步扩展: 二值信号量和计数信号量

1. 信号量是什么

信号量是一种基本的同步机制,在多任务并发执行、共享资源时起到重要作用。它可以控制多个任务对共享资源的访问顺序,保证每个任务能够按照一定的顺序获取共享资源而不会冲突,从而保证系统的正确运行。

2. FreeRTOS的信号量及其基础API

FreeRTOS提供了两种类型的信号量:二值信号量和计数信号量。

二值信号量的取值范围只有两个:0和1。该类型的信号量通常用于同步任务之间的行为,比如某个任务执行完了一个关键操作后通知其他任务开始执行某个操作。

计数信号量的取值范围可以是任意正整数。该类型的信号量通常用于控制资源访问的数量,比如限制同时只有两个任务可以对某个资源进行访问。

以下是FreeRTOS提供的信号量API:

  • xSemaphoreCreateBinary():创建一个二值信号量
  • xSemaphoreCreateCounting(uxMaxCount, uxInitialCount):创建一个计数信号量,uxMaxCount表示允许的最大值,uxInitialCount表示初始值
  • xSemaphoreTake(xSemaphore, xBlockTime):指定一个信号量,该函数会尝试获取该信号量。如果信号量的取值为0,取值操作将会阻塞(如果指定了阻塞时间xBlockTime则会阻塞一段时间),直到信号量的取值为1或其他任务释放该信号量
  • xSemaphoreGive(xSemaphore):将一个信号量的值加1,相当于释放该信号量
  • xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken):和xSemaphoreGive的差不多,只是该函数可以在中断里面使用。如果该函数使得某个任务的优先级变得比当前任务高,那么参数pxHigherPriorityTaskWoken将被设置为非零值

3. 信号量的使用示例说明

我们先看一个简单的二值信号量的使用示例:

#include "FreeRTOS.h"
#include "semphr.h"

SemaphoreHandle_t s_binary;

void task_A(void* params) {
    while (1) {
        // 尝试获取二值信号量
        if (xSemaphoreTake(s_binary, portMAX_DELAY) == pdTRUE) {
            // 用打印语句替代具体的任务处理
            printf("Task A Acquire Binary Semaphore.\r\n");
            vTaskDelay(pdMS_TO_TICKS(1000));
            // 释放二值信号量
            xSemaphoreGive(s_binary);
        }
    }
}

void task_B(void* params) {
    while (1) {
        // 尝试获取二值信号量
        if (xSemaphoreTake(s_binary, portMAX_DELAY) == pdTRUE) {
            // 用打印语句替代具体的任务处理
            printf("Task B Acquire Binary Semaphore.\r\n");
            vTaskDelay(pdMS_TO_TICKS(1000));
            // 释放二值信号量
            xSemaphoreGive(s_binary);
        }
    }
}

int main() {
    // 创建一个二值信号量
    s_binary = xSemaphoreCreateBinary();

    xTaskCreate(task_A, "Task A", 512, NULL, 1, NULL);
    xTaskCreate(task_B, "Task B", 512, NULL, 2, NULL);
    // 启动调度器
    vTaskStartScheduler();

    return 0;
}

在这个示例中,我们创建了一个二值信号量s_binary,两个任务(task_Atask_B)将会通过该信号量进行同步。每个任务的执行方式类似,大致的流程如下:

  1. 尝试获取二值信号量s_binary
  2. 如果获取成功,说明该任务可以开始执行,用打印语句替代具体的任务处理,等待1秒;
  3. 释放二值信号量s_binary

从示例中我们可以看出,只要二值信号量被某个任务获取,其他任务就无法获取该信号量,直到该任务将其释放。

我们再来看一个计数信号量的使用示例:

#include "FreeRTOS.h"
#include "semphr.h"

SemaphoreHandle_t s_counting;

void task_C(void* params) {
    while (1) {
        // 尝试获取计数信号量
        if (xSemaphoreTake(s_counting, portMAX_DELAY) == pdTRUE) {
            // 用打印语句替代具体的任务处理
            printf("Task C Acquire Counting Semaphore.\r\n");
            vTaskDelay(pdMS_TO_TICKS(1000));
            // 释放计数信号量
            xSemaphoreGive(s_counting);
        }
    }
}

void task_D(void* params) {
    while (1) {
        // 尝试获取计数信号量
        if (xSemaphoreTake(s_counting, portMAX_DELAY) == pdTRUE) {
            // 用打印语句替代具体的任务处理
            printf("Task D Acquire Counting Semaphore.\r\n");
            vTaskDelay(pdMS_TO_TICKS(1000));
            // 释放计数信号量
            xSemaphoreGive(s_counting);
        }
    }
}

int main() {
    // 创建一个计数信号量,允许的最大值为3,初始值为2
    s_counting = xSemaphoreCreateCounting(3, 2);

    xTaskCreate(task_C, "Task C", 512, NULL, 1, NULL);
    xTaskCreate(task_D, "Task D", 512, NULL, 2, NULL);
    // 启动调度器
    vTaskStartScheduler();

    return 0;
}

在这个示例中,我们创建了一个计数信号量s_counting,两个任务(task_Ctask_D)将会通过该信号量进行同步。s_counting的最大值为3,初始值为2,从而保证同时最多只有两个任务可以获取该信号量。每个任务的执行方式类似,大致的流程如下:

  1. 尝试获取计数信号量s_counting
  2. 如果获取成功,说明该任务可以开始执行,用打印语句替代具体的任务处理,等待1秒;
  3. 释放计数信号量s_counting

从示例中我们可以看出,只要计数信号量$s_counting$还没有达到最大值,就可以任意多个任务获取该信号量,而达到最大值后,其他任务就无法获取该信号量,直到某个任务释放该信号量。

4. 进一步扩展: 二值信号量和计数信号量

在FreeRTOS中,二值信号量和计数信号量只是信号量的两种常见类型。如果我们需要更复杂的同步机制,可以通过扩展信号量来实现。以下是常见的信号量扩展方法:

  1. 二进制资源信号量(Binary Resource Semaphore):可以用于共享的硬件资源或软件资源等。在一些嵌入式系统中,CPU的某个时钟信号可能需要被多个模块共享,因此需要使用二进制资源信号量来管理共享。
  2. 优先级继承信号量(Priority Inheritance Semaphore):可以解决“优先级反转”(Priority Inversion)的问题。比如,如果高优先级任务需要等待低优先级任务占用的共享资源,而低优先级任务又正在等待其他资源,这时候就需要使用优先级继承信号量来提高高优先级任务的优先级,并且防止低优先级任务“抢占”共享资源而导致高优先级任务无限等待的问题。
  3. 读写信号量(Read-Write Semaphore):可以实现读者-写者问题。在一些多线程程序中,可能需要实现读操作和写操作的互斥,写者优先于读者、读者与读者之间不互斥等。这种情况下,可以使用读写信号量来解决问题。

扩展信号量需要根据具体情况,选择不同的实现方法。但基本的原则是要保证信号量的安全操作,避免死锁、优先级反转等问题的产生。

以上就是关于“FreeRTOS实时操作系统信号量基础”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:FreeRTOS实时操作系统信号量基础 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 魔兽世界达萨罗之战BOSS打法攻略 达萨罗之战全BOSS打法要点详解

    魔兽世界达萨罗之战BOSS打法攻略 BOSS介绍 达萨罗之战共有九个BOSS,分别是: 丰灵 国王的试炼(全明星赛) 低语者沃尔兹斯 大厅哨兵 天空队长热炮 纳特拉·血怒 玉火大师 拆解者米斯拉克斯 格洛恩,还有他的三个尖牙战士 每个BOSS都有独特的机制和技能,需要团队成员相互配合才能成功击败。 达萨罗之战全BOSS打法要点详解 丰灵 丰灵是达萨罗之战的第…

    other 2023年6月27日
    00
  • vue父组件监听子组件数据更新方式(hook)

    当一个Vue组件被渲染后,可能需要在组件外部监听组件内部的数据变化,这时候就需要使用Vue提供的特殊钩子函数来实现了,下面是实现“vue父组件监听子组件数据更新”功能的完整攻略: 1.使用Vue提供的$refs属性 在子组件中定义一个方法,用于在数据更新时触发父组件的方法,并将数据通过参数形式传递给父组件,示例代码如下所示: //子组件中数据更新时触发父组件…

    other 2023年6月27日
    00
  • Android 应用启动欢迎界面广告的实现实例

    Android 应用启动欢迎界面广告的实现实例攻略 在 Android 应用中实现启动欢迎界面广告可以提供更好的用户体验和增加广告收入。下面是一个详细的攻略,包含了两个示例说明。 步骤一:准备工作 在项目的 build.gradle 文件中添加以下依赖项: dependencies { implementation ‘com.google.android.g…

    other 2023年9月6日
    00
  • css绝对定位如何居中?css绝对定位居中的四种实现方法

    以下是关于“CSS绝对定位如何居中?CSS绝对定位居中的四种实现方法”的完整攻略,包含两个示例说明。 CSS绝对定位如何居中? 在CSS中,绝对定位元素默认相对于其最近的已定位祖先元素进行定位的。如果没有已定位的祖先元素,则相对于文档的初始含块进行定位。在本攻略中,我们将介绍如何将绝对定位元素居中。 1. 使用transform和负margin 我们可以使用…

    other 2023年5月9日
    00
  • JavaScript创建对象方法实例小结

    JavaScript创建对象方法实例小结 在JavaScript中,我们可以使用不同的方法来创建对象。下面是一些常见的方法: 1. 使用对象字面量 对象字面量是一种简单直接的方式来创建对象。我们可以使用花括号 {} 来定义一个对象,并在其中添加属性和方法。 let person = { name: \"John\", age: 30, s…

    other 2023年8月6日
    00
  • 详解微信小程序入门五: wxml文件引用、模版、生命周期

    “详解微信小程序入门五: wxml文件引用、模版、生命周期”是介绍微信小程序的三个重要概念,以及生命周期的使用方法,以下是完整攻略: wxml文件引用 在微信小程序中,我们经常需要使用到其他wxml文件里的组件或内容,这时候,我们可以通过以下两种方式进行引用: 1. 使用import进行引用 在需要使用的wxml文件中使用<import src=”路径…

    other 2023年6月27日
    00
  • asm入网小助手卸载

    以下是“asm入网小助手卸载的完整攻略”的详细讲解,过程中包含两个示例说明的标准Markdown格式文本: asm入网小助手卸载的完整攻略 asm入网小助手是一款方便快捷的网络工具,但有时候我们需要卸载它。本文将介绍如何彻底卸asm入网小助手。 1. Windows系统下的卸载 1.1 控制面板卸载 我们可以通过以下步骤在Windows系统下使用控制面板卸载…

    other 2023年5月10日
    00
  • Android Studio应用开发集成百度语音合成使用方法实例讲解

    Android Studio应用开发集成百度语音合成使用方法实例讲解 简介 百度语音合成是一种人工智能技术,可以将文本转换为语音,并且可以自定义声音和语调等参数。在移动应用中集成百度语音合成可以为用户提供更好的语音体验,例如语音导航、语音搜索等功能。 本文将介绍如何在Android Studio应用开发中集成百度语音合成,并提供两个示例来帮助理解如何使用百度…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部