HarmonyOS小熊派 | HarmonyOS内核编程开发—信号量

举报
Yuchuan 发表于 2021/06/29 22:51:40 2021/06/29
【摘要】 HarmonyOS内核编程开发——信号量

BearPi-HM_Nano开发板HarmonyOS内核编程开发——信号量

本示例将演示如何在BearPi-HM_Nano开发板上使用cmsis 2.0 接口通过信号量同时从不同的线程访问共享资源

BearPi-HM_Nano

Semaphore API分析

osSemaphoreNew()

osSemaphoreId_t osSemaphoreNew(uint32_t max_count,uint32_t initial_count,const osSemaphoreAttr_t *attr)

描述:

函数osMessageQueueNew创建并初始化一个消息队列对象。该函数返回消息队列对象标识符,如果出现错误则返回NULL,可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,也可以在内核初始化 (调用 osKernelInitialize)之前调用该函数。

注意 :不能在中断服务调用该函数

参数:

名字 描述
max_count 可用令牌的最大数量.
initial_count 可用令牌的初始数量.
attr 信号量的属性;空:默认值.

osSemaphoreRelease()

osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)

描述: 函数osSemaphoreRelease释放由参数semaphore_id指定的信号量对象的标记

注意 :该函数可以在中断服务例程调用

参数:

名字 描述
semaphore_id 由osSemaphoreNew获得的信号量ID.

osSemaphoreAcquire()

osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id,uint32_t timeout)

描述: 阻塞函数osSemaphoreAcquire一直等待,直到由参数semaphore_id指定的信号量对象的标记可用为止。如果一个令牌可用,该函数立即返回并递减令牌计数。

注意 :如果参数timeout设置为0,可以从中断服务例程调用。

参数:

名字 描述
semaphore_id 由osSemaphoreNew获得的信号量ID.
timeout 超时值.

软件设计

主要代码分析

在Semaphore_example函数中,通过osSemaphoreNew()函数创建了sem1信号量,Thread_Semaphore1()函数中通过osSemaphoreRelease()函数释放两个信号量,Thread_Semaphore2()和Thread_Semaphore3()函数中,先开始阻塞等待sem1信号量。只有当Thread_Semaphore1()函数中增加两次信号量,Thread_Semaphore2()和Thread_Semaphore3()才能继续同步运行。若Thread_Semaphore1()函数中只增加一次信号量,那Thread_Semaphore2()和Thread_Semaphore3()只能轮流执行。

semaphore_yuchuan_example.c

#include <stdio.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"

#define GPIO_LED 2

osSemaphoreId_t semaphoreId;

void yuchuanThreadSemaphore(void)
{
    osStatus_t status;

    while (1)
    {
        //释放两次信号量,使huayingThread和meiliThread两个任务同步
        status = osSemaphoreRelease(semaphoreId);
        //osSemaphoreRelease(semaphoreId);
        if (status != osOK)
        {
            /* code */
            printf("YuchuanThread Semaphore Release Falied!!!\n");
        }
        else
        {
            printf("YuchuanThread Semaphore Release Success!!!\n");
        }

        osDelay(100);
    }
    
}

void huayingThreadSemaphore(void)
{
    osStatus_t status;

    while (1)
    {
        //阻塞信号量
        //osSemaphoreAcquire(semaphoreId,osWaitForever);
        status = osSemaphoreAcquire(semaphoreId,50U);
        if (status != osOK)
        {
            /* code */
            printf("HuayingThread get Semaphore Falied!!!\n");
        }
        else
        {
            printf("HuayingThread get Semaphore Success!!!\n");
            //设置GPIO输出高电平点亮LED灯
            IoTGpioSetOutputVal(GPIO_LED,IOT_GPIO_VALUE1);
            //osSemaphoreDelete(semaphoreId);
        }

        //osDelay(1);
    }
    
}

void meiLiThreadSeamphore(void)
{
    osStatus_t status;

    while (1)
    {
        //阻塞信号量
        status = osSemaphoreAcquire(semaphoreId,osWaitForever);
        if (status != osOK)
        {
            /* code */
            printf("MeiliThread get Semaphore Falied!!!\n");
        }
        else
        {
            printf("MeiliThread get Semaphore Success!!!\n");
            //设置GPIO输出低电平熄灭LED灯
            IoTGpioSetOutputVal(GPIO_LED,IOT_GPIO_VALUE0);
        }
        
        osDelay(500);
    }
    
}

static void yuchuanSemaphoreExample(void)
{
    //初始化GPIO
    IoTGpioInit(GPIO_LED);
    //设置GPIO为输出方向
    IoTGpioSetDir(GPIO_LED,IOT_GPIO_DIR_OUT);

    osThreadAttr_t attr;
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 1024 * 4;
    attr.priority = 25;

    attr.name = "YuchuanThread";
    if (osThreadNew((osThreadFunc_t)yuchuanThreadSemaphore,NULL,&attr) == NULL)
    {
        /* code */
        printf("Falied to Create YuchuanThread!!!\n");
    }

    attr.name = "HuayingThread";
    if (osThreadNew((osThreadFunc_t)huayingThreadSemaphore,NULL,&attr) == NULL)
    {
        /* code */
        printf("Falied to Create HuayingThread!!!\n");
    }
    
    attr.name = "MeiliThread";
    if (osThreadNew((osThreadFunc_t)meiLiThreadSeamphore,NULL,&attr) == NULL)
    {
        /* code */
        printf("Falied to Create MeiliThread!!!\n");
    }
    
    semaphoreId = osSemaphoreNew(4,0,NULL);
    if (semaphoreId == NULL)
    {
        /* code */
        printf("Falied to Create Semaphore!!!\n");
    }
    
}

APP_FEATURE_INIT(yuchuanSemaphoreExample);

编译调试

applications/sample/BearPi/BearPi-HM_Nano/sample/A5_YuchuanSemaphore/BUILD.gn

static_library("yuchuanSemaphore"){
    sources = [
        "semaphore_yuchuan_example.c",
    ]
    include_dirs = [
        "//base/iot_hardware/peripheral/interfaces/kits",
    ]                                                                                                                                                                                                                                                                       
}

修改 BUILD.gn 文件

修改 applications\BearPi\BearPi-HM_Nano\sample路径下 BUILD.gn 文件,指定 semp_example 参与编译。

# Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import("//build/lite/config/component/lite_component.gni")

lite_component("sample") {
    features = [
        #"A1_kernal_thread:thread_example",
        #"A2_kernel_timer:timer_example",
        #"A3_kernel_event:event_example",
        #"A4_kernel_mutex:mutex_example",
        #"A5_kernel_semaphore:semaphore_example",
        #"A6_kernel_message:message_example",

        #"B1_basic_led_blink:led_example",
        #"B2_basic_button:button_example",
        #"B3_basic_pwm_led:pwm_example",
        #"B4_basic_adc:adc_example", 
        #"B5_basic_i2c_nfc:i2c_example",
        #"B6_basic_uart:uart_example",
        
        #"C1_e53_sf1_mq2:e53_sf1_example",
        #"C2_e53_ia1_temp_humi_pls:e53_ia1_example",
        #"C3_e53_sc1_pls:e53_sc1_example",
        #"C4_e53_sc2_axis:e53_sc2_example",
        #"C5_e53_is1_infrared:e53_is1_example",

        #"D1_iot_wifi_ap:wifi_ap",
        #"D2_iot_wifi_sta_connect:wifi_sta_connect",        
        #"D3_iot_udp_client:udp_client",
        #"D4_iot_tcp_server:tcp_server",
        #"D5_iot_mqtt:iot_mqtt",        
        #"D6_iot_cloud_oc:oc_mqtt",
        #"D7_iot_cloud_onenet:onenet_mqtt",
        #"D8_iot_cloud_oc_smoke:cloud_oc_smoke",
        #"D9_iot_cloud_oc_light:cloud_oc_light",
        #"D10_iot_cloud_oc_manhole_cover:cloud_oc_manhole_cover",
        #"D11_iot_cloud_oc_infrared:cloud_oc_infrared",
        #"D12_iot_cloud_oc_agriculture:cloud_oc_agriculture",
        #"D13_iot_cloud_oc_gps:cloud_oc_gps",
        #"A1_YuchuanThread:yuchuanThread",
        #"A2_YuchuanTimer:yuchuanTimer",
        #"A4_YuchuanMutex:yuchuanMutex",
        "A5_YuchuanSemaphore:yuchuanSemaphore",
    ]
}

运行结果

示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,Thread_Semaphore1一次释放两个信号量,Thread_Semaphore2和Thread_Semaphore3同步执行。

hiview init success.YuchuanThread Semaphore Release Success!!!
HuayingThread get Semaphore Success!!!
00 00:00:00 0 132 D 0/HIVIEW: log limit init success.
00 00:00:00 0 132 I 1/SAMGR: Bootstrap core services(count:3).
00 00:00:00 0 132 I 1/SAMGR: Init service:0x4b0368 TaskPool:0xe4b3c
00 00:00:00 0 132 I 1/SAMGR: Init service:0x4b0374 TaskPool:0xe4b5c
00 00:00:00 0 132 I 1/SAMGR: Init service:0x4b0840 TaskPool:0xe4b7c
00 00:00:00 0 164 I 1/SAMGR: Init service 0x4b0374 <time: 0ms> success!
00 00:00:00 0 64 I 1/SAMGR: Init service 0x4b0368 <time: 0ms> success!
00 00:00:00 0 8 I 1/SAMGR: Init service 0x4b0840 <time: 10ms> success!
00 00:00:00 0 8 I 1/SAMGR: Initialized all core system services!
00 00:00:00 0 64 I 1/SAMGR: Bootstrap system and application services(count:0).
00 00:00:00 0 64 I 1/SAMGR: Initialized all system and application services!
00 00:00:00 0 64 I 1/SAMGR: Bootstrap dynamic registered services(count:0).
HuayingThread get Semaphore Falied!!!
YuchuanThread Semaphore Release Success!!!
HuayingThread get Semaphore Falied!!!
MeiliThread get Semaphore Success!!!
HuayingThread get Semaphore Falied!!!
YuchuanThread Semaphore Release Success!!!
HuayingThread get Semaphore Falied!!!
HuayingThread get Semaphore Success!!!
HuayingThread get Semaphore Falied!!!
YuchuanThread Semaphore Release Success!!!
HuayingThread get Semaphore Falied!!!
HuayingThread get Semaphore Success!!!
HuayingThread get Semaphore Falied!!!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。