2140|1

73

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【小熊派BearPi-HM Micro】基于E53接口的智能路灯模块开发 [复制链接]

本帖最后由 symic 于 2022-8-27 07:47 编辑

学习了一段时间后,准备试用将E53接口的模块与 小熊派BearPi-HM Micro进行联试。手头正好由一款ES53-SC1智能灯模块,可实现光线感应及智能灯光的功能。

E53接口是适用于小熊派系列的外界模块接口,

 

由于需要与驱动打交道,这里还是参考南向的开发方法。

1、首先是驱动的开发,在device\st\driver下创建一个名叫e53_driver\E53_SC1文件夹,新建2个文件:驱动文件E53_SC1_hdf.c和编译构建文件BUILD.gn 。

E53_SC1_hdf.c负责驱动源码的编制,按照linux的标准模板,添加相应的内容。如:

static int32_t Hdf_E53_SC1_DriverInit(struct HdfDeviceObject *device)    //实现初始化

static int32_t Hdf_E53_SC1_DriverBind(struct HdfDeviceObject *deviceObject)  //实现将相关的服务接口绑定到HDF框架

void HdfE53sc1DriverRelease(struct HdfDeviceObject *deviceObject)// 驱动资源释放的接口
int32_t E53sc1DriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)// 处理用户态发下来的消息

其中最主要的是E53sc1DriverDispatch,该函数通过cmdCode命令来判断不同的用户命令参数。包括    E53_SC1_Start,E53_SC1_Stop, E53_SC1_Read, E53_SC1_SetLight。

nt32_t E53sc1DriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
    int ret = -1;
    char *replay_buf;

    HDF_LOGE("E53sc1 driver dispatch");
    if (client == NULL || NULL == client->device)
    {
        HDF_LOGE("E53sc1 driver device is NULL");
        return HDF_ERR_INVALID_OBJECT;
    }
    switch (cmdCode)
    {
    case E53_SC1_Start:
        ret = E53_SC1Init();
        if (ret != 0)
        {
            HDF_LOGE("E53sc1 Init err");
            return HDF_FAILURE;
        }
        ret = HdfSbufWriteString(reply, "ES3_SC1 Init sucessful");
        if (ret == 0)
        {
            HDF_LOGE("Reply failed\r\n");
            return HDF_FAILURE;
        }
        break;
    case E53_SC1_Stop:
        ret = E53_SC1Init();
        if (ret != 0)
        {
            HDF_LOGE("E53sc1 Init err");
            return HDF_FAILURE;
        }
        ret = HdfSbufWriteString(reply, "ES3_SC1 Init sucessful");
        if (ret == 0)
        {
            HDF_LOGE("Reply failed\r\n");
            return HDF_FAILURE;
        }
        break;
    case E53_SC1_Read:
        ret = E53_SC1ReadData(&lux_data);

        if (ret != 0)
        {
            HDF_LOGE("E53sc1 Read data err");
            return HDF_FAILURE;
        }
        replay_buf = OsalMemAlloc(100);
        (void)memset(replay_buf, 100, 0, 100);
        sprintf(replay_buf, {\"Lux\":%.2f,\"LED\":\"%s\"}", lux_data, LightStatus ? "ON" : "OFF")
        //把传感器数据写入reply, 可被带至用户程序
        if(!HdfSbufWriteString(reply, rreply_buf))
            {
                HDF_LOGE("Reply failed\r\n");
                return HDF_FAILURE;
            }
            osalMemFree(replay_buf);
            break;
        case E53_SC1_SetLight:
            const char *readdata = HdfSbufReadString(data);
            if (strcmp(readdata, "ON") == 0)
            {
                E53_SC1LightStatusSet(ON);
                LightStaus = 1;
            }
            else if (strcmp(readdata, "OFF"))
            {
                E53_SC1LightStatusSet(OFF);
                LightStaus = 0;
            }
            else
            {
                HDF_LOGE("Command wrong\r\n");
                return HDF_FAILURE;
            }
            replay_buf  = OsalMemAlloc(100);
            (void) memset_s(replay_buf, 100, 0, 100);
            sprintf(replay_buf, "{\"Lux\":%.2f,\"LED\":\"%s\"}",  lux_data, LightStatus ? "ON" : "OFF");
            /* 把传感器数据写入reply, 可被带至用户程序 */
            if(!HdfSbufWriteString(reply, replay_buf))
            {
                             HDF_LOGE("replay is fail");
                return HDF_FAILURE;
            }
            osalMemFree(replay_buf);
            brek;
            default:
            return HDF_FAILURE;
          }
          return HDF_SUCCESS;
    }

最后再调用驱动注册函数

    struct HdfDriverEntry g_ledDriverEntry = {
        .moduleVersion = 1,
        .moduleName = "HDF_ES53_SC1",
        .Bind = HdfE53sc1DriverBind,
        .Init = HdfE53sc1DriverInit,
        .Release = HdfE53sc1DriverRelease,
    };

    // 调用HDF_INIT将驱动入口注册到HDF框架中
    HDF_INIT(g_E53sc1DriverEntry);

2、接下来需要再HDF框架中添加新建的设备驱动描述,具体是在device\st\bearpi_hm_micro\liteos_a\hdf_config\device_info\device_info.hcs,新增一项

device_e53 :: device {  
        priority = 30;                
        device_sc1 :: deviceNode {             
            policy = 2;                     
            priority = 130; 
            preload = 1;                               
            permission = 0777;              
            moduleName = "HDF_E53_SC1";        
            serviceName = "hdf_e53_sc1";    
        }
}

3、以上操作后底层的驱动工作基本完成,接上来需要开展JS接口层的开发,主要涉及需要修改的文件为app_module.h和app_module.c,文件路径在foundation\ace\ace_engine_lite\frameworks\src\core\modules\,内容是添加一个JS APIE53SC1Service

在app_module.h中添加声明

static JSIValue E53SC1Service(const JSIValue thisVal, const JSIValue* args, uint8_t argsNum);

并在void InitAppModule(JSIValue exports)中添加

JSI::SetModuleAPI(exports, "e53sc1service", AppModule::E53SC1Service);

在app_module.c中添加定义

static int E53SC1Control(struct HdfIoService *serv, int32_t cmd, const char* buf, char **val)
{
    int ret = HDF_FAILURE;
    struct HdfSBuf *data = HdfSBufObtainDefaultSize();
    struct HdfSBuf *reply = HdfSBufObtainDefaultSize();

    if (data == NULL || reply == NULL) {
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to obtain sbuf data\n");
        return ret;
    }

    if (!HdfSbufWriteString(data, buf))
    {
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to write sbuf\n");
        HdfSBufRecycle(data);
        HdfSBufRecycle(reply);
        return ret;
    }

    ret = serv->dispatcher->Dispatch(&serv->object, cmd, data, reply);
    if (ret != HDF_SUCCESS)
    {
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to send service call\n");
        HdfSBufRecycle(data);
        HdfSBufRecycle(reply);
        return ret;
    }

    *val = (char *)(HdfSbufReadString(reply));
    if(val ==NULL){
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service call reply\n");
        ret = HDF_ERR_INVALID_OBJECT;
        HdfSBufRecycle(data);
        HdfSBufRecycle(reply);
        return ret;

    }

    HILOG_ERROR(HILOG_MODULE_ACE,"Get reply is: %s\n", *val);

    HdfSBufRecycle(data);
    HdfSBufRecycle(reply);
    return ret;
}

JSIValue AppModule::E53SC1Service(const JSIValue thisVal, const JSIValue *args, uint8_t argsNum)
{
    struct HdfIoService *serv = HdfIoServiceBind(E53_SC1_SERVICE);
    if (serv == NULL)
    {
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to get service %s\n", E53_SC1_SERVICE);
        return JSI::CreateUndefined();
    }

    if ((args == nullptr) || (argsNum == 0) || (JSI::ValueIsUndefined(args[0]))) {
        return JSI::CreateUndefined();
    }

    JSIValue success = JSI::GetNamedProperty(args[0], CB_SUCCESS);
    JSIValue fail = JSI::GetNamedProperty(args[0], CB_FAIL);
    JSIValue complete = JSI::GetNamedProperty(args[0], CB_COMPLETE);

    int32_t cmd = (int32_t)JSI::GetNumberProperty(args[0], "cmd");  
    char *data = (char *)JSI::GetStringProperty(args[0], "data");
    HILOG_ERROR(HILOG_MODULE_ACE, "cmd is: %d\n", cmd);
    HILOG_ERROR(HILOG_MODULE_ACE,"data is: %s\n", data);
    char *replyData;

    if (E53SC1Control(serv, cmd, data, &replyData))
    {
        HILOG_ERROR(HILOG_MODULE_ACE,"fail to send event\n");
        JSI::CallFunction(fail, thisVal, nullptr, 0);
        JSI::CallFunction(complete, thisVal, nullptr, 0);
        JSI::ReleaseValueList(success, fail, complete);
        return JSI::CreateUndefined();
    }

    JSIValue result = JSI::CreateObject();

    JSI::SetStringProperty(result, "e53_sc1", replyData);
    JSIValue argv[ARGC_ONE] = {result};
    JSI::CallFunction(success, thisVal, argv, ARGC_ONE);
    JSI::CallFunction(complete, thisVal, nullptr, 0);
    JSI::ReleaseValueList(success, fail, complete, result);

    HdfIoServiceRecycle(serv);

    return JSI::CreateUndefined();
}

4、最后配置编译依赖

foundation\ace\ace_engine_lite\ace_lite.gni中添加HDF头文件路径。

ace_lite_include_dirs += [
    "//drivers/framework/ability/sbuf/include",
    "//drivers/framework/include/core",
    "//drivers/framework/include/utils",
    "//drivers/adapter/uhdf/posix/include",
]

修改foundation\ace\ace_engine_lite\frameworks\BUILD.gn,在public_deps中添加以下代码

"//drivers/adapter/uhdf/manager:hdf_core",

修改foundation\ace\ace_engine_lite\test\ace_test_config.gni,在extra_deps中添加以下代码

"//drivers/adapter/uhdf/manager:hdf_core",

到此为止,驱动代码编写工作完成,通过编译完成后,使用STM32CubeProgrammer下载完成,具体参考之前的试用帖子

接下来是北向的JS应用的编写,这里可以先使用教程中原有的HAP文件:MicroE53.HAP,通过SD卡拷贝安装,

但是遇到的问题

在想试试使用SD卡安装HAP程序时,发现通过mount 加载时出现以下问题

目前还没解决。

此帖出自Linux开发论坛

最新回复

使用SD卡安装HAP程序时的mount 加载问题属于设备忙或无响应,这个该怎么处理   详情 回复 发表于 2022-8-27 19:08
点赞 关注

回复
举报

6828

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

使用SD卡安装HAP程序时的mount 加载问题属于设备忙或无响应,这个该怎么处理

此帖出自Linux开发论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表