Bearpi开发板之HarmonyOS互斥锁

news/2024/5/19 7:16:50 标签: harmonyos, Bearpi开发板, Mutex

互斥锁的概念

1、互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对共享资源的独占式处理。
2、任意时刻互斥锁的状态只有两种:开锁或闭锁。
3、当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。
4、当该任务释放时,该互斥锁被开锁,任务失去该互斥锁的所有权。
5、当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。
6、多任务环境下往往存在多个任务竞争同一共享资源的应用场景,互斥锁可被用于对共享资源的保护从而实现独占式访问。
另外,互斥锁可以解决信号量存在的优先级翻转问题。

运作原理

  • 多任务环境下会存在多个任务访问同一公共资源的场景,而有些公共资源是非共享的,需要任务进行独占式处理。互斥锁怎样来避免这种冲突呢?
  • 用互斥锁处理非共享资源的同步访问时,如果有任务访问该资源,则互斥锁为加锁状态。此时其他任务如果想访问这个公共资源则会被阻塞,直到互斥锁被持有该锁的任务释放后,其他任务才能重新访问该公共资源,此时互斥锁再次上锁,如此确保同一时刻只有一个任务正在访问这个公共资源,保证了公共资源操作的完整性。

cmsis_os2的API互斥锁接口简介

  • 创建互斥锁:osMutexId_t osMutexNew (const osMutexAttr_t *attr);
  • 获取互斥锁:osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);
  • 释放互斥锁:osStatus_t osMutexRelease (osMutexId_t mutex_id);
  • 删除互斥锁:osStatus_t osMutexDelete (osMutexId_t mutex_id);

创建高中低优先级共3个任务和一个互斥对象

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include <string.h>
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"




void hi_thread(void *p)
{
 
  osDelay(100);
  while(1)
  {
    osMutexAcquire(p,osWaitForever);
     printf("hi thread\n");
    osDelay(300);
    osMutexRelease(p);
  }
}

void mid_thread(void *p)
{
   (void)p;
  osDelay(100);
  while(1)
  {
    printf("mid thread\n");
    osDelay(100);
  }
}


void low_thread(void *p)
{
  
  while(1)
  {
    osMutexAcquire(p,osWaitForever);
    printf("low thread\n");
    osDelay(300);
    osMutexRelease(p);
  }
}




void my_led_example(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);
    
    osThreadAttr_t attr;
    attr.attr_bits = 0;
    attr.cb_mem = NULL;
    attr.cb_size = 0;
    attr.stack_mem = NULL;
    attr.stack_size = 1024;
    attr.priority = 25;

    static osMutexId_t mutex;
    mutex = osMutexNew(NULL);
    if (mutex == NULL)
    {
       printf("Falied to create mutex!\n");
    }

   osThreadId_t id = osThreadNew(hi_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create hi_thread!\n");
   }
      attr.priority = 24;

    id = osThreadNew(mid_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create mid_thread!\n");
   }

    attr.priority = 23;

    id = osThreadNew(low_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create low_thread!\n");
   }
}
SYS_RUN(my_led_example);
  • 编译烧录运行
    在这里插入图片描述

扩展实验代码

#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include <string.h>
#include "cmsis_os2.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"




void hi_thread(void *p)
{
 
    osDelay(100U);
    osStatus_t status;
    while (1)
    {
        // try to acquire mutex
      
        status = osMutexAcquire(p, osWaitForever);
        printf("hi_thread is runing.\r\n");
        if(status != osOK)
        {
           printf("hi thread acquire mutex failed\r\n");
        }
        else
        {
            printf("hi thread acquire mutex success\r\n");
        }
        
        printf("hi thread block 3s\n");
        osDelay(300U);
        printf("hi thread osMutexRelease is called\n");
        status = osMutexRelease(p);
        if(status != osOK)
        {
            printf("hi thread release mutex failed\r\n");
        }
        else
        {
           printf("hi thread release mutex success\r\n");
        }
    }
}

void mid_thread(void *p)
{
   (void)p;
  osDelay(100);
  while(1)
  {
    printf("mid thread\n");
    osDelay(100);
  }
}


void low_thread(void *p)
{
  osStatus_t status;
  while (1)
  {
    status = osMutexAcquire(p, osWaitForever);
    printf("low_thread is runing.\r\n");
    if(status != osOK)
    {
        printf("lo tread acquire mutex failed\r\n");
    }
    else
    {
       printf("lo thread acquire mutex success\r\n");
    }
    // block mutex for 3s
    printf("lo thread block 3s\n");
    osDelay(300U);
    printf("lo thread osMutexRelease is called\n");
    status = osMutexRelease(p);
    if(status != osOK)
    {
      printf("lo thread release mutex failed\r\n");
    }
    else
    {
      printf("lo thread release mutex success\r\n");
    }
  }

}




void my_led_example(void)
{
    GpioInit();
    IoSetFunc(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_IO_FUNC_GPIO_2_GPIO);
    GpioSetDir(WIFI_IOT_IO_NAME_GPIO_2,WIFI_IOT_GPIO_DIR_OUT);
    
    osThreadAttr_t attr;
    attr.attr_bits = 0;
    attr.cb_mem = NULL;
    attr.cb_size = 0;
    attr.stack_mem = NULL;
    attr.stack_size = 1024;
    attr.priority = 25;

    static osMutexId_t mutex;
    mutex = osMutexNew(NULL);
    if (mutex == NULL)
    {
       printf("Falied to create mutex!\n");
    }

   osThreadId_t id = osThreadNew(hi_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create hi_thread!\n");
   }
      attr.priority = 24;

    id = osThreadNew(mid_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create mid_thread!\n");
   }

    attr.priority = 23;

    id = osThreadNew(low_thread,mutex,&attr);
   if(id == NULL)
   {
        printf("Falied to create low_thread!\n");
   }
}
SYS_RUN(my_led_example);
  • 编译烧录运行
    在这里插入图片描述

http://www.niftyadmin.cn/n/1226525.html

相关文章

MicroPython和MQTT云端迷你气象站

我们将实施简化的气象站物联网解决方案。 我们将使用分线板上的小型传感器记录温度&#xff0c;大气压力和湿度。 虽然这三个数据点并非完全是一个完整的&#xff0c;专业的&#xff08;业余爱好者较少&#xff09;等级的天气解决方案&#xff0c;但它可以准确地向您显示从传感…

Bearpi开发板之HarmonyOS消息队列

消息队列的概念 消息队列&#xff0c;是一种常用于任务间通信的数据结构&#xff0c;实现了接收来自任务或中断的不固定长度的消息&#xff0c;并根据不同的接口选择传递消息是否存放在自己空间。任务能够从队列里面读取消息&#xff0c;当队列中的消息是空时&#xff0c;挂起…

ARM Mbed数字信号处理

信号处理对于许多应用而言很重要。 借助现代计算机的强大功能&#xff0c;许多信号处理功能现在都可以通过数字方式完成。 本文&#xff0c;我们将说明如何使用Arm Mbed -DSP库进行数字信号处理和控制。 低通滤波器 在Arm Mbed 网站上&#xff0c;有关于如何设计和实现低通FI…

S132协议栈之Response广播

初时化广播代码 static uint8_t rsp_data[1]; static ble_advdata_manuf_data_t m_rsp_spec_data; /**brief Function for initializing the Advertising functionality.*/ static void advertising_init(void) {uint32_t err_code;ble_advertising_init_t init…

ARM Mbed在线IDE编程意法半导体(ST)开发板

硬件 软件 介绍 STM32F407发现板不直接支持MBED在线IDE。 但是该板上的MCU也用于另一块官方MBED板上&#xff08;Seeed Studio Arch Max v1.1&#xff09;。 因此&#xff0c;可以通过将发现板当作Arch Max板进行编程。 这是使用MBED在线IDE快速进行原型制作的一种简便方法…

Bearpi开发板HarmonyOS之GPIO中断

GPIO 中断API介绍 wifiiot_gpio.h中包含声明GPIO中断相关函数 设置GPIO引脚中断功能 unsigned int GpioRegisterIsrFunc(WifiIotGpioIdx id, WifiIotGpioIntType intType, WifiIotGpioIntPolarity intPolarity, GpioIsrCallbackFunc func, char *arg);取消GPIO引脚中断功能 u…

ARM Mbed网络监控温度

硬件 | 软件 | 介绍 温度测量是最基本&#xff0c;最常执行的测量之一。 它可以是房间的温度&#xff0c;人的温度或设备的温度。 能够通过Internet远程监视温度具有许多潜在的重要应用。 例如&#xff0c;许多老人独自生活。 如果他们生病了&#xff0c;可能要过一段时间才能…

Bearpi开发板HarmonyOS之PWM输出

wifiiot_pwm.h接口简介 初始化PWM unsigned int PwmInit(WifiIotPwmPort port);取消初始化PWM unsigned int PwmDeinit(WifiIotPwmPort port);根据输入参数输出PWM unsigned int PwmStart(WifiIotPwmPort port, unsigned short duty, unsigned short freq);停止PWM输出 unsign…