小熊派华为物联网操作系统 LiteOS内核教程04-信号量

本文介绍了华为物联网操作系统LiteOS中的信号量机制,用于任务同步和资源管理。信号量分为互斥锁、任务同步和资源计数等应用场景,并详细解析了创建、删除、申请和释放信号量的API接口。通过动手实验展示了信号量如何在任务间实现同步,以低优先级任务和高优先级任务为例,演示了信号量在实际操作中的效果。
摘要由CSDN通过智能技术生成

1. LiteOS内核的信号量

1.1.信号量

在多任务操作系统中,不同的任务之间需要同步运行,信号量功能可以为用户提供这方面的支持。信号量(Semaphore)是一种实现任务间通信的机制,实现任务之间同步或临界资源的互斥访问。

1.2. 信号量的使用方式

信号量可以被任务获取或者申请,不同的信号量通过信号量索引号来唯一确定,每个信号量都有一个计数值和任务队列。

通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数,其值的含义分两种情况:

  • 0:表示没有积累下来的 Post 操作,且有可能有在此信号量上阻塞的任务;
  • 正值:表示有一个或多个 Post 下来的释放操作;

当任务申请(Pend)信号量时,如果申请成功,则信号量的计数值递减,如若申请失败,则挂起在该信号量的等待任务队列上,一旦有任务释放该信号量,则等待任务队列中的任务被唤醒开始执行。

1.3. 信号量的使用场景

信号量是一种非常灵活的同步方式,可以运用在多种场合中,实现锁、同步、资源计数等功能,也能方便的用于任务与任务,中断与任务的同步中。

  • 互斥锁

用作互斥时,信号量创建后记数是满的,在需要使用临界资源时,先申请信号量,使其变空,这样其他任务需要使用临界资源时就会因为无法申请到信号量而阻塞,从而保证了临界资源的安全。

  • 任务间同步

用作同步时,信号量在创建后被置为空,任务1申请信号量而阻塞,任务2在某种条件发生后,释放信号量,于是任务1得以进入 READY 或 RUNNING 态,从而达到了两个任务间的同步。

  • 资源计数

用作资源计数时,信号量的作用是一个特殊的计数器,可以递增或者递减,但是值永远不能为负值,典型的应用场景是生产者与消费者的场景。

  • 中断与任务的同步

用作中断与任务的同步时,可以在中断未触发时将信号量的值置为0,从而堵塞断服务处理任务,一旦中断被触发,则唤醒堵塞的中断服务处理任务进行中断处理。

2. 信号量API

Huawei LiteOS 系统中的信号量模块为用户提供创建/删除信号量、申请/释放信号量的功能。

Huawei LiteOS 系统中提供的信号量 API 都是以 LOS 开头,但是这些 API 使用起来比较复杂,所以本文中我们使用 Huawei IoT Link SDK 提供的统一API接口进行实验,这些接口底层已经使用 LiteOS 提供的API实现,对用户而言更为简洁,API列表如下:

osal的api接口声明在 中,使用相关的接口需要包含该头文件,关于函数的详细参数请参考该头文件的声明。

相关的接口定义在osal.c中,基于LiteOS的接口实现在 liteos_imp.c文件中:

接口名
功能描述
osalsempcreate
信号量创建
osalsempdel
信号量删除
osalsemppend
信号量申
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将小熊wifi8266连接到华为云的示例代码: ```c++ #include <ESP8266WiFi.h> #include <PubSubClient.h> // 替换为自己的WiFi信息和华为云信息 const char* ssid = "your_SSID"; // WiFi SSID const char* password = "your_PASSWORD"; // WiFi password const char* mqttServer = "your_MQTT_SERVER"; // 华为云MQTT服务器地址 const int mqttPort = 1883; // 华为云MQTT服务器端口 const char* mqttUsername = "your_MQTT_USERNAME"; // 华为云MQTT用户名 const char* mqttPassword = "your_MQTT_PASSWORD"; // 华为云MQTT密码 const char* deviceId = "your_DEVICE_ID"; // 设备ID const char* topic = "your_TOPIC"; // 主题名称 WiFiClient wifiClient; PubSubClient mqttClient(wifiClient); void setup() { Serial.begin(9600); delay(10); // 连接WiFi Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); // 连接华为云MQTT服务器 mqttClient.setServer(mqttServer, mqttPort); while (!mqttClient.connected()) { Serial.print("Connecting to MQTT server..."); if (mqttClient.connect(deviceId, mqttUsername, mqttPassword)) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(mqttClient.state()); Serial.println(" try again in 5 seconds"); delay(5000); } } } void loop() { // 发布消息 mqttClient.publish(topic, "Hello from ESP8266"); delay(5000); } ``` 在实际使用时,需要将代码中的 `your_SSID`、`your_PASSWORD`、`your_MQTT_SERVER`、`your_MQTT_USERNAME`、`your_MQTT_PASSWORD`、`your_DEVICE_ID`、`your_TOPIC` 替换为自己的实际信息。同时,需要将 `PubSubClient.h` 和 `ESP8266WiFi.h` 这两个库添加到项目中。 该示例代码中,通过 `WiFi.begin` 函数连接WiFi,通过 `mqttClient.connect` 函数连接华为云的MQTT服务器。在 `loop` 函数中,通过 `mqttClient.publish` 函数发布消息到指定的主题。您可以根据自己的需求修改代码来实现更多功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值