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

100 篇文章 1 订阅
100 篇文章 0 订阅

往期知识点记录:

一、概述

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

二、源码分析

  1. 基于LiteOS内核的os_adapter.c文件解析。
/*
 * 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;
}
  1. 基于Linux内核的os_adapter.c文件解析。
/*
 * 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;
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值