OpenHarmony源码分析之分布式软总线:os_adapter模块解析

一、概述

os_adapter模块是操作系统适配层。HarmonyOS的操作系统底层可以是:HarmonyOS micro kernel,Linux kernel,且 Lite OS将成为一个完整的鸿蒙微内核架构。鸿蒙系统内部各个模块内部使用的函数需要支持针对不同版本平台的适配,体现各部分解耦的模块化设计思想,针对不同的硬件设备,组合成最适合该设备的OS。当前版本的鸿蒙系统的os_adapter模块针对Lite OS内核和Linux内核实现了互斥锁消息队列的适配。下面分别对两种内核的适配源码进行分析。

二、源码分析

  1. 基于LiteOS内核的os_adapter.c文件解析。
arduino 复制代码
/*
 * Copyright (c) 2020 Huawei Device 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.
 */
#include "os_adapter.h"
#include "lwip/sockets.h"
/*创建并初始化互斥锁*/
MutexId MutexInit(void)
{
    return (MutexId)osMutexNew(NULL);//创建并初始化一个新的互斥对象,并在出现错误时返回指向互斥对象标识符的指针或NULL。CMSIS-RTOS2标准
}
/*申请互斥锁*/
void MutexLock(MutexId mutex)
{
    if (mutex == NULL) {
        return;
    }
    osMutexAcquire(mutex, osWaitForever);//等待直到参数mutex指定的互斥对象变为可用。如果没有其他线程获得互斥锁,该函数会立即返回并阻塞互斥锁对象。CMSIS-RTOS2标准
}
/*释放互斥锁*/
void MutexUnlock(MutexId mutex)
{
    if (mutex == NULL) {
        return;
    }
    osMutexRelease(mutex);//释放由参数mutex指定的互斥锁。当前等待此互斥锁的其他线程将被置于READY状态。CMSIS-RTOS2标准
}
/*关闭套接字fd*/
void CloseSocket(int *fd)
{
    if (fd == NULL) {
        return;
    }
    if (*fd >= 0) {
        closesocket(*fd);
        *fd = -1;
    }
}
/*
函数功能:向消息队列中写入一条消息
函数参数:
    queueID:消息队列id
    bufferAddr:要写入的消息体的首地址
    bufferSize:要写入的消息体大小
函数返回值:
    成功:返回0
    失败:返回-1
*/
int WriteMsgQue(unsigned int queueID, const void *bufferAddr, unsigned int bufferSize)
{
    if (bufferAddr == NULL) {//健壮性检查
        return -1;
    }
    (void)bufferSize;//此处未使用到这个参数,但为了避免编译器发出警告,做此处理
    return osMessageQueuePut((osMessageQueueId_t)queueID, (VOID*)bufferAddr, 0, 0);//将bufferAddr指向的消息放入参数queueID指定的消息队列中。CMSIS-RTOS2的消息队列写入方法
}
/*
函数功能:创建并初始化消息队列
函数参数:
    queueName:消息队列名称,传入参数
    len:消息队列的最大消息数
    queueID:消息队列id,传出参数
    flags:标志
    maxMsgSize:消息队列中每个消息的最大字节数
函数返回值:
    成功:返回0
    失败:返回-1
*/
int CreateMsgQue(const char *queueName,
    unsigned short len, unsigned int *queueID,
    unsigned int flags, unsigned short maxMsgSize)
{
    osMessageQueueId_t id;//定义消息队列id
    if (queueID == NULL) {
        return -1;
    }
    (void)queueName;//此处未使用到这个参数,但为了避免编译器发出警告,做此处理
    (void)flags;//此处未使用到这个参数,但为了避免编译器发出警告,做此处理
    id = osMessageQueueNew(len, maxMsgSize, NULL);//创建并初始化一个消息队列对象。如果出现错误,该函数将返回消息队列对象标识符或NULL。CMSIS-RTOS2标准
    if (NULL == id) {
        return -1;
    }
    *queueID = (unsigned int)id;//赋值给传出参数
    return 0;
}
/*删除queueID指定的消息队列*/
int DeleteMsgQue(unsigned int queueID)
{
    return osMessageQueueDelete((osMessageQueueId_t)queueID);//删除由参数queueID指定的消息队列对象。它释放为消息队列处理获得的内部内存。CMSIS-RTOS2标准
}
/*
函数功能:从消息队列中读取消息
函数参数:
    queueID:消息队列id
    bufferAddr:用于保存消息体的缓冲区首地址
    bufferSize:用于保存消息体的缓冲区大小
函数返回值:
    成功:返回0
    失败:返回-1
*/
int ReadMsgQue(unsigned int queueID,
    void *bufferAddr, unsigned int *bufferSize)
{
    if (bufferAddr == NULL || bufferSize == NULL) {//健壮性检查
        return -1;
    }
    return osMessageQueueGet((osMessageQueueId_t)queueID, bufferAddr, NULL, osWaitForever);//从参数queueID指定的消息队列中检索消息,并将其保存到参数bufferAddr指向的缓冲区中。CMSIS-RTOS2标准
}
/*软总线权限检查*/
int SoftBusCheckPermission(const char* permissionName)
{
    if (permissionName == NULL) {
        return -1;
    }
    return 0;
}

DD一下: 欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。

erlang 复制代码
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
  1. 基于Linux内核的os_adapter.c文件解析。
arduino 复制代码
/*
 * Copyright (c) 2020 Huawei Device 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.
 */
#include "os_adapter.h"
#include <errno.h>
#include <mqueue.h>
#include <pthread.h>
#include <unistd.h>
/*创建并初始化互斥锁*/
MutexId MutexInit(void)
{
    pthread_mutex_t *mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));//定义一个互斥锁对象
    if (mutex == NULL) {
        return NULL;
    }
    (void)pthread_mutex_init(mutex, NULL);//初始化该互斥锁。POSIX标准
    return (MutexId)mutex;
}
/*申请互斥锁资源*/
void MutexLock(MutexId mutex)
{
    if (mutex == NULL) {
        return;
    }
    pthread_mutex_lock((pthread_mutex_t *)mutex);//申请互斥锁资源。POSIX标准
}
/*释放互斥锁资源*/
void MutexUnlock(MutexId mutex)
{
    if (mutex == NULL) {
        return;
    }
    pthread_mutex_unlock((pthread_mutex_t *)mutex);//释放互斥锁资源。POSIX标准
}
/*关闭套接字fd,即关闭连接*/
void CloseSocket(int *fd)
{
    if (fd == NULL) {
        return;
    }
    if (*fd >= 0) {
        close(*fd);
        *fd = -1;
    }
}
/*
函数功能:创建并初始化消息队列
函数参数:
    queueName:消息队列名称,传入参数
    len:消息队列的最大消息数
    queueID:消息队列id,传出参数
    flags:标志,0或O_NONBLOCK,用来表示是否阻塞
    maxMsgSize:消息队列中每个消息的最大字节数
函数返回值:
    成功:返回0
    失败:返回-1
*/
int CreateMsgQue(const char *queueName,
    unsigned short len, unsigned int *queueID,
    unsigned int flags, unsigned short maxMsgSize)
{
    if (queueName == NULL || queueID == NULL) {//健壮性检查
        return -1;
    }
    //定义并初始化一个消息队列属性对象
    struct mq_attr newAttr = {0};
    newAttr.mq_flags = flags;
    newAttr.mq_maxmsg = len;
    newAttr.mq_msgsize = maxMsgSize;
    int mqd = mq_open(queueName, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR, &newAttr);//打开或创建一个消息队列。POSIX标准
    if (mqd < 0) {
        return -1;
    }
    *queueID = mqd;
    return 0;
}
/*
函数功能:向消息队列中写入一条消息
函数参数:
    queueID:消息队列id
    bufferAddr:要写入的消息体的首地址
    bufferSize:要写入的消息体大小
函数返回值:
    成功:返回0
    失败:返回-1
*/
int WriteMsgQue(unsigned int queueID,
    const void *bufferAddr, unsigned int bufferSize)
{
    if (bufferAddr == NULL) {
        return -1;
    }
    int ret = mq_send(queueID, bufferAddr, bufferSize, 0);//向消息队列中写入一条消息。POSIX标准
    if (ret != 0) {
        return -1;
    }
    return 0;
}
/*删除消息队列*/
int DeleteMsgQue(unsigned int queueID)
{
    return mq_close(queueID);
}
/*
函数功能:从消息队列中读取消息
函数参数:
    queueID:消息队列id
    bufferAddr:用于保存消息体的缓冲区首地址
    bufferSize:用于保存消息体的缓冲区大小
函数返回值:
    成功:返回0
    失败:返回-1
*/
int ReadMsgQue(unsigned int queueID,
    void *bufferAddr, unsigned int *bufferSize)
{
    if (bufferAddr == NULL || bufferSize == NULL) {
        return -1;
    }
    unsigned int readSize = *bufferSize;
    unsigned int receiveSize = mq_receive(queueID, bufferAddr, readSize, 0);//从消息队列中读取消息。POSIX标准
    if (receiveSize != readSize) {
        return -1;
    }
    *bufferSize = receiveSize;
    return 0;
}
/*软总线权限检查:成功返回0,失败返回-1*/
int SoftBusCheckPermission(const char* permissionName)
{
    if (permissionName == NULL) {
        return -1;
    }
    if (CheckSelfPermission(permissionName) != GRANTED) {
        SOFTBUS_PRINT("[SOFTBUS] CheckSelfPermission fail\n");
        return -1;
    }
    return 0;
}
相关推荐
松☆5 小时前
OpenHarmony 特有挑战:如何让 Flutter 应用支持分布式软总线
分布式·flutter
Surpass余sheng军13 小时前
AI 时代下的网关技术选型
人工智能·经验分享·分布式·后端·学习·架构
遇到困难睡大觉哈哈15 小时前
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
笔记·华为·harmonyos
遇到困难睡大觉哈哈16 小时前
HarmonyOS —— Remote Communication Kit 定制处理行为(ProcessingConfiguration)速记笔记
笔记·华为·harmonyos
氤氲息17 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
遇到困难睡大觉哈哈17 小时前
HarmonyOS支付接入证书准备与生成指南
华为·harmonyos
赵浩生17 小时前
鸿蒙技术干货10:鸿蒙图形渲染基础,Canvas绘图与自定义组件实战
harmonyos
赵浩生17 小时前
鸿蒙技术干货9:deviceInfo 设备信息获取与位置提醒 APP 整合
harmonyos
哈哈哈笑什么17 小时前
企业级高并发分布式SpringCloud系统下,订单动态超时自动取消(最终成熟方案),使用spring-cloud-starter-stream-rabbit
分布式·spring cloud·rabbitmq