From 515635a5cc4271ac8c0f5498788c229f2ad84c6d Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Fri, 28 Jan 2022 16:26:50 +0800 Subject: [PATCH 01/10] add Light file Signed-off-by: zhouyanxu --- .../driver/driver-peripherals-light-des.md | 429 ++++++++++++++++++ ...0\346\250\241\345\236\213\345\233\276.png" | Bin 0 -> 9991 bytes ...0\350\277\220\350\241\214\345\233\276.png" | Bin 0 -> 25064 bytes 3 files changed, 429 insertions(+) create mode 100644 zh-cn/device-dev/driver/driver-peripherals-light-des.md create mode 100644 "zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" create mode 100644 "zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\350\277\220\350\241\214\345\233\276.png" diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md new file mode 100644 index 00000000000..3ace49b94c0 --- /dev/null +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -0,0 +1,429 @@ +# LIGHT + +- [概述](##概述) + - [功能简介](###功能简介) + - [运作机制](###运作机制) + +- [开发指导](##开发指导) + - [接口说明](#section188213414114) + - [开发步骤](#section7893102915819) + - [开发实例](#section257750691) + - [调测验证](#section106021256121219) + + +## 概述 + +### 功能简介 + +​ 灯(light)驱动模型为上层灯硬件服务层提供稳定的灯控制能力接口,包括获取灯类型,灯常亮,灯闪烁效果配置,灯停止的能力。基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的灯(light)驱动模型,实现跨操作系统迁移,器件差异配置等功能。实现Light驱动“一次开发,多系统部署”的目标。Light驱动模型如[图1](#fig10451455446)所示: + +**图 1** Light驱动模型图 + +![Light驱动模型图](figures\Light驱动模型图.png) + +### 运作机制 + +通过介绍Light驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如[图2](#Sensor驱动模型图)所示: + +**图 2** 灯驱动模型图 + +![Light驱动运行图](figures\Light驱动运行图.png) + +灯驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及运行流程: + +1. 从device info HCS 的Light Host里读取Light设备管理配置信息。 +2. 从light_config HCS读取Light数据配置信息。 +3. 解析Light设备管理配置信息,并关联对应设备驱动。 +4. 客户端下发Light Stub控制到服务端。 +5. 服务端调用Light Stub控制。 +6. 启动灯抽象驱动接口。 + +## 开发指导 + +### 接口说明 + + 灯驱动模型支持系统中所有灯的信息和动态配置闪烁模式和闪烁时间配置能力。灯硬件服务调用GetLightInfo获取灯设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。灯驱动模型对HDI开放的API接口能力,参考[表1](#table203963834718) 。 + +[表1](#table203963834718) 灯驱动模型对外API接口能力介绍 + +| 接口名 | 功能描述 | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| int32_t (*GetLightInfo)(struct LightInfo **lightInfo, uint32_t *count) | 获取系统中所有灯的信息,lightInfo表示灯设备的基本信息,count表示获取灯的个数。 | +| int32_t (*TurnOnLight)(uint32_t type, struct LightEffect *effect) | 根据指定的灯类型打开灯列表中可用的灯,type表示灯类型,effect表示要设置的效果信息。 | +| int32_t (*TurnOffLight)(uint32_t type) | 根据指定的灯类型关闭灯列表中可用的灯。 | + +### 开发步骤 +1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成灯抽象驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现,配置资源和HCS解析。完成加速度传感器驱动的设备信息配置。 +3. 调用配置解析接口,完成器件属性信息解析,器件寄存器解析,并注册到Light设备管理中。 +3. 完成灯获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 + +### 开发实例 + +1. 灯驱动的初始化和去初始化 + + - 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 灯驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)介绍。其中Driver Entry入口函数定义如下: + + ```c + /*注册灯入口数据结构体对象*/ + struct HdfDriverEntry g_lightDriverEntry = { + .moduleVersion = 1, /*灯模块版本号*/ + .moduleName = "HDF_LIGHT", /*灯模块名,要与device_info.hcs文件里灯moduleName字段值一样*/ + .Bind = BindLightDriver, /*灯绑定函数*/ + .Init = InitLightDriver, /*灯初始化函数*/ + .Release = ReleaseLightDriver, /*灯资源释放函数*/ + }; + /* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ + HDF_INIT(g_lightDriverEntry); + ``` + + - 基于HDF驱动框架,按照驱动Driver Entry程序,完成灯抽象驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现。 + + ```c + /* 灯驱动对外发布的能力 */ + static int32_t DispatchLight(struct HdfDeviceIoClient *client, + int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) + { + ..... + if (cmd == LIGHT_IO_CMD_GET_INFO_LIST) { + CHECK_LIGHT_NULL_PTR_RETURN_VALUE(reply, HDF_ERR_INVALID_PARAM); + return GetAllLightInfo(data, reply); + } + + CHECK_LIGHT_NULL_PTR_RETURN_VALUE(data, HDF_ERR_INVALID_PARAM); + (void)OsalMutexLock(&drvData->mutex); + if (!HdfSbufReadInt32(data, &lightType)) { + HDF_LOGE("%s: sbuf read lightType failed", __func__); + (void)OsalMutexUnlock(&drvData->mutex); + return HDF_ERR_INVALID_PARAM; + } + ..... + ret = DispatchCmdHandle(lightType, data, reply); + (void)OsalMutexUnlock(&drvData->mutex); + return ret; + } + + /* 灯驱动对外提供的服务绑定到HDF框架 */ + int32_t BindLightDriver(struct HdfDeviceObject *device) + { + struct LightDriverData *drvData = NULL; + + CHECK_LIGHT_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); + // 私有接口分配资源 + drvData = (struct LightDriverData *)OsalMemCalloc(sizeof(*drvData)); + CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL); + // 需要发布的接口函数 + drvData->ioService.Dispatch = DispatchLight; + drvData->device = device; + device->service = &drvData->ioService; + g_lightDrvData = drvData; + return HDF_SUCCESS; + } + + /* 灯驱动初始化入口函数*/ + int32_t InitLightDriver(struct HdfDeviceObject *device) + { + ..... + // 工作队列初始化 + if (HdfWorkQueueInit(&drvData->workQueue, LIGHT_WORK_QUEUE_NAME) != HDF_SUCCESS) { + HDF_LOGE("%s: init workQueue fail!", __func__); + return HDF_FAILURE; + } + // 工作项初始化 + if (HdfWorkInit(&drvData->work, LightWorkEntry, (void*)drvData) != HDF_SUCCESS) { + HDF_LOGE("%s: init workQueue fail!", __func__); + return HDF_FAILURE; + } + // 解析HCS配置文件 + if (GetLightConfigData(device->property) != HDF_SUCCESS) { + HDF_LOGE("%s: get light config fail!", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; + } + + /* 释放灯驱动初始化时分配的资源 */ + void ReleaseLightDriver(struct HdfDeviceObject *device) + { + ..... + // 释放已分配资源 + for (i = LIGHT_TYPE_NONE; i < LIGHT_TYPE_BUTT; ++i) { + + if (drvData->info[i] != NULL) { + OsalMemFree(drvData->info[i]); + drvData->info[i] = NULL; + } + } + // 销毁工作队列资源 + HdfWorkDestroy(&drvData->work); + HdfWorkQueueDestroy(&drvData->workQueue); + (void)OsalMutexDestroy(&drvData->mutex); + (void)OsalMemFree(drvData); + g_lightDrvData = NULL; + } + + ``` + + - 灯设备管理模块负责系统中灯器件接口发布,在系统启动过程中,HDF框架机制通过灯 Host里设备HCS配置信息,加载设备管理驱动。 + + ```hcs + /* 灯设备HCS配置 */ + device_light :: device { + device0 :: deviceNode { + policy = 2; /* policy字段是驱动服务发布的策略 */ + priority = 100; /* 灯驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ + preload = 0; /* 驱动按需加载字段,0表示加载,2表示不加载 */ + permission = 0664; /* 驱动创建设备节点权限 */ + moduleName = "HDF_LIGHT"; /* 灯驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ + serviceName = "hdf_light"; /* 灯驱动对外发布服务的名称,必须唯一 */ + deviceMatchAttr = "hdf_light_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ + } + } + ``` + +2. 分配资源,解析灯hcs配置。 + + - 解析hcs配置文件。 + + ```c + /* 分配资源,解析灯HCS配置 */ + static int32_t ParseLightInfo(const struct DeviceResourceNode *node) + { + ..... + // 从hcs获取支持灯的类型个数 + drvData->lightNum = parser->GetElemNum(light, "lightType"); + .... + for (i = 0; i < drvData->lightNum; ++i) { + // 获取类型 + ret = parser->GetUint32ArrayElem(light, "lightType", i, &temp, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "lightType"); + } + + for (i = 0; i < drvData->lightNum; ++i) { + ..... + // 类型作为下标开辟空间 + drvData->info[temp] = (struct LightDeviceInfo *)OsalMemCalloc(sizeof(struct LightDeviceInfo)); + ..... + // 将Light设备信息进行填充 + ret = parser->GetUint32(light, "busRNum", &drvData->info[temp]->busRNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busRNum"); + ret = parser->GetUint32(light, "busGNum", &drvData->info[temp]->busGNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busGNum"); + ret = parser->GetUint32(light, "busBNum", &drvData->info[temp]->busBNum, 0); + CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busBNum"); + ..... + return HDF_SUCCESS; + + } + ``` + + - 灯效果模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)介绍。 + + ```hcs + 灯数据配置模板(light_config.hcs) + root { + lightConfig { + boardConfig { + match_attr = "hdf_light_driver"; + lightAttr { + light01 { + lightType = [1, 2]; // 灯类型组,一个物理灯对应多个逻辑灯 + busRNum = 31; // 红色对映的GPIO管脚 + busGNum = 30; // 绿色对映的GPIO管脚 + busBNum = 29; // 蓝色对映的GPIO管脚 + lightBrightness = 0X80000000;// RGB: R:16-31bit、G:8-15bit、 // B:0-7bit + onTime = 50; // 最小闪烁时间(ms) + offTime = 50; + } + } + } + } + } + ``` + +3. 完成获取灯类型,闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 + + ```c + /* 灯驱动服务调用GetAllLightInfo获取灯类型,Enable接口启动闪烁模式, + 调用Disable接口停止闪烁 */ + static int32_t GetAllLightInfo(struct HdfSBuf *data, struct HdfSBuf *reply) + { + ..... + // 获取light类型个数 + if (!HdfSbufWriteUint32(reply, drvData->lightNum)) { + HDF_LOGE("%s: write sbuf failed", __func__); + return HDF_FAILURE; + } + for (i = 0; i < LIGHT_TYPE_BUTT; ++i) { + if (drvData->info[i] == NULL) { + continue; + } + lightInfo.lightType = i; + lightInfo.reserved = NULL; + // 将Light设备信息填充进reply + if (!HdfSbufWriteBuffer(reply, &lightInfo, sizeof(lightInfo))) { + HDF_LOGE("%s: write sbuf failed", __func__); + return HDF_FAILURE; + } + } + + return HDF_SUCCESS; + } + + /* 按照指定的类型和用户传入的参数使能灯 */ + static int32_t Enable(uint32_t lightType, struct HdfSBuf *data, struct HdfSBuf *reply) + { + ..... + // 根据用户传的亮度值设置灯的颜色 RGB: R:16-31bit、G:8-15bit、B:0-7bit + if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_R_BIT) != 0) { + drvData->info[lightType]->busNum = drvData->info[lightType]->busRNum; + } else if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_G_BIT) != 0) { + drvData->info[lightType]->busNum = drvData->info[lightType]->busGNum; + } else if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_B_BIT) != 0) { + drvData->info[lightType]->busNum = drvData->info[lightType]->busBNum; + } + // 常亮模式 + if (buf->flashEffect.flashMode == LIGHT_FLASH_NONE) { + + if (GpioWrite(drvData->info[lightType]->busNum, GPIO_VAL_HIGH) != HDF_SUCCESS) { + return HDF_FAILURE; + } + } + // 闪烁模式 + if (buf->flashEffect.flashMode == LIGHT_FLASH_TIMED) { + drvData->info[lightType]->lightState = LIGHT_STATE_START; + // 用户设置的闪烁时间小于系统支持的最短时间,采用系统配置的时间(HCS配置) + drvData->info[lightType]->onTime = buf->flashEffect.onTime < drvData->info[lightType]->onTime ? + drvData->info[lightType]->onTime : buf->flashEffect.onTime; + drvData->info[lightType]->offTime = buf->flashEffect.offTime < drvData->info[lightType]->offTime ? + drvData->info[lightType]->offTime : buf->flashEffect.offTime; + // 创建定时器 + if (OsalTimerCreate(&drvData->timer, drvData->info[lightType]->onTime, + LightTimerEntry, (uintptr_t)lightType) != HDF_SUCCESS) { + HDF_LOGE("%s: create light timer fail!", __func__); + return HDF_FAILURE; + } + // 启动周期定时器 + if (OsalTimerStartLoop(&drvData->timer) != HDF_SUCCESS) { + HDF_LOGE("%s: start light timer fail!", __func__); + return HDF_FAILURE; + } + } + return HDF_SUCCESS; + } + + /* 按照指定的类型关闭灯 */ + static int32_t Disable(uint32_t lightType, struct HdfSBuf *data, struct HdfSBuf *reply) + { + // 删除定时器 + if (drvData->timer.realTimer != NULL) { + + if (OsalTimerDelete(&drvData->timer) != HDF_SUCCESS) { + HDF_LOGE("%s: delete haptic timer fail!", __func__); + } + } + // 对应的GPIO下电 + if (GpioWrite(drvData->info[lightType]->busRNum, GPIO_VAL_LOW) != HDF_SUCCESS){ + HDF_LOGE("%s: gpio write failed", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; + } + ``` + +### 调测验证 + +驱动开发完成后,在灯单元测试里面开发自测试用例,验证驱动基本功能。测试环境采用开发者自测试平台。 + +```c++ +/* 用例执行前,初始化灯接口实例 */ +void HdfLightTest::SetUpTestCase() +{ + g_lightDev = NewLightInterfaceInstance(); + if (g_lightDev == nullptr) { + printf("test light get Module instance failed\n\r"); + } + int32_t ret = g_lightDev->GetLightInfo(&g_lightInfo, &g_count); + if (ret == -1) { + printf("get light informations failed\n\r"); + } +} + +/* 用例执行后,释放用例资源 */ +void HdfLightTest::TearDownTestCase() +{ + if(g_lightDev != nullptr){ + FreeLightInterfaceInstance(); + g_lightDev = nullptr; + } +} + +/* 测试灯获取类型 */ +HWTEST_F(HdfLightTest, GetLightList001, TestSize.Level1) +{ + struct LightInfo *info = nullptr; + + if (g_lightInfo == nullptr) { + EXPECT_NE(nullptr, g_lightInfo); + return; + } + + printf("get light list num[%d]\n\r", g_count); + info = g_lightInfo; + + for (int i = 0; i < g_count; ++i) { + printf("get lightId[%d]\n\r", info->lightType); + EXPECT_GE(info->lightType, g_minLightType); + EXPECT_LE(info->lightType, g_maxLightType); + info++; + } +} + +/* 测试灯常亮模式 */ +HWTEST_F(HdfLightTest, EnableLight001, TestSize.Level1) +{ + int32_t i; + int32_t ret; + struct LightEffect effect; + effect->lightBrightness = 0x80000000; + effect->flashEffect.flashMode = LIGHT_FLASH_NONE; + effect->flashEffect.onTime = 0; + effect->flashEffect.offTime = 0; + + for (i = 0; i < g_count; ++i) { + + ret = g_lightDev->TurnOnLight(g_lightInfo[i]->lightType, effect); + EXPECT_EQ(0, ret); + + OsalSleep(LIGHT_WAIT_TIME); + + ret = g_lightDev->TurnOffLight(type); + EXPECT_EQ(0, ret); + } +} + +/* 测试灯闪烁模式 */ +HWTEST_F(HdfLightTest, EnableLight002, TestSize.Level1) +{ + int32_t i; + int32_t ret; + struct LightEffect effect; + effect->lightBrightness = 0x80000000; + effect->flashEffect.flashMode = LIGHT_FLASH_TIMED; + effect->flashEffect.onTime = g_onTime; + effect->flashEffect.offTime = g_offTime; + + for (i = 0; i < g_count; ++i) { + + ret = g_lightDev->TurnOnLight(g_lightInfo[i]->lightType, effect); + EXPECT_EQ(0, ret); + + OsalSleep(LIGHT_WAIT_TIME); + + ret = g_lightDev->TurnOffLight(type); + EXPECT_EQ(0, ret); + } +} +``` + diff --git "a/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" "b/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\346\250\241\345\236\213\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..77f9bb9f1643e7338043f85c74eee706a0f3561b GIT binary patch literal 9991 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 R;A9(twz|GrnaYju{|2T5SO@?B literal 0 HcmV?d00001 diff --git "a/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\350\277\220\350\241\214\345\233\276.png" "b/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\350\277\220\350\241\214\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..a48f73c18f7338ef1e18084733f72471b129f4e6 GIT binary patch literal 25064 zcmce;XIPU>*ZxcBiVzhQ={7_~Km_RoyCMRL1&|UE5Ty42fe=KoAfPB9Qepv7>Ai+T z5s(_1p+hJk^n{iK5@1ib@8@~n|Ngf3aqRuU!vsjKYi8EWtn;_dxnA5bz9PI`VmlWX zm$1Rri>6#$5H|SdBFGPZqNbuV3I2olm|i*0mD4IU1>W#Fo-;bf#g!i;#J1%F@3(ng zweaEM5~<<*gVcL`v*+Tn4KcWQ?skC9TnYoZ=MHNVvq@fEK!(8d+fF`@;XAqK(z$m> zjm~~Rzr0Gt9$6kjQuRK`t3jr$r%uFQS?}pzZ<%>*@vz3Vz~JiX$|V%Mn{|zTy|;HT zaY>s3V+~yEgtbQ^sWT94UzN}ZQer%m8R!?6d==URrL&R9FxOI9`Ka|Cq z$;A!$4zus`k%=4#U^EUJ^Gzkf-(4mRuL{Wjd z{!$OiTpR3c3SuaKi9(vn~6Z6IJKxq9oN( z>;M*XEM{(^C25uF30FG=e(5NSVtz`|LlUvnmwOdvqcn!{z~}pah6`ld)kmubGd&r- z`kQQ@rsn3Nd&SP>)E{1Bb@TxrLiw1a%7Z7u;-`Oy&=oC9%o+28b8Vk4+?1rkmF&ybmx@wUu4ne=D>xa*)mTzH*#YfooMNyMdI-x z1&{yP#efCNoHbI`5zIPCXlU@Fr9<+Z|DGt7J$v1R-Sz#Jy7%~1m-f$3S!~sZ&7Sou z&8md56&=56du8l$>=~yvd^Td_7ayZq?LdUELT#<}mncfOWX><*z~og=*)p$Q_7ly$e!ZCo^c^+(soZD z?ZP>=AIh{W&B1Q0&8WK&Pj>4tB59gvz8}jS5Ixo>$4xNUI{STeXK{{%)Do9&CB$_; zzSor26c>-`)vsrqyZ)@v=UhN{`PNUIIVz#<>ZDxF{H*g3*7@%EEvws*Z=zZxJ?v%v zC{dWlGZE=5qa=0r;n|q(i@f|$nUf?#(6i*Pr-i3@h#(AfobLX(-LMid9Kx^`7&Ul% zRO?R=p77_7=hN{5TGAWR&VCR%*3ArLsY;SfJ5Hz z0Q0rl<;V_c?Jj8@Er_eh1^cnOsChqs{}L7q`?^}=B5f)IQ^D9vlQW1-E4Z7;jY;9T zbbjiU<6CBlZ4Ez?9A`F)HsRswDa-{^pj<}Z!0*Y-)N!7ci*`)B($VS!#bx7w-wGxDk!!cZ<;zuVImH!gZA+QgWP+Tg`cK6MpzT*sFi;NCn@Eg#NE zckP;y(e%Vey%FQxh?drodes}IwWHh1oJjkmz5!4a)DQKDIJ11z5HmWXK)z^ASDS1 ztz7Z7F2DQVF`xEtAI%7kl)_z*1CM`t6^71VehsEhT7hXIw`^JG*jF>dhuS;&zHY7( zLS@8hyY!rXO)XDOsl2@|Py7S}^9Sk|+ONo#x9MULbrTksJ(B0*m8_=^ z?G85f<_>@_@}OZCpgY9d+74{TGhuoN*ixK=*?{AN&ES1>Bc8BizUBbfO>UU-aHJWC zMXE9Ame|H?>D;hw{(pbm@%frzST+O=_83@OsFyAMaVN7PKe%pr%1d4-_-s$Qp%}wv zHvA+C2Lh8)!03&>%%{cuiqhGCR1Douo;>&Vk;!M7v5Dm(@lHqGlsfMIw>!jlfbJLW)vpoZ!aUK7*u@kHfWl-kkoQaCTKu1d)r_5XE~MDPgrdZ%MJ4!b zv@n(O4a-u4KIqGB0V-V%BN=n1)Q$O;t3#Ggw}RmVD=9$Yo-NqXgX z;3^?0Pouwm>?m7g&#t$9o;s4$3pF1oLHHyi zIz^C|c664o;Irc_Mi8RsTP?KtTL(-RPip;6t{RA%l+*K_Pye*E_%%5lp>=N#9og8` zL17*69)VxBJK*%-AZL9J+H*pk7I|1gU^xqmoP`|4A6^iC-dPy3=W~L|S6!@69bxs< zz}Nbj#}kDRJDk(0*Eda0%QW~($tNylfmhshQmVpxC8VD)uo1$-d(Rq;MIaZo_R)W) z@beApzj<*q4~yn(cX3Y}_b_L}`v(MTMNdGP)>j=&WABjr=pWAx%^a6J^=O>rW{y+WSfj@X6!tujBi})Hh>YMi1Bk84$ zJD8OSYKg6#{JqUx;sqz4b&VapUIH=%-OV3yM~y9KN8fI2TT(tn)gu1F1f)#Od_7#5YX5fsqQ|g zB8l4&P5R)cMX&BG$T7b>q!JAeZT>o6vE1fgknFsVCU^Ya4^I*!DSv3=){-1@ZjK&^ zhlwc&{IGszQc8gb)ecE&w;ZKv%9dKcu8jHM_7{U9Y6~atFOv$0Y2u-iR{IrwIy1te zo*xwQ?=#HBI`~Oq-M*Mj{3d=HSqO?mWVcGTxb=+AJ}Xg(ex#d+`y_a9o<58J(2!Ib|zN-f(d5d5(@NH*G%^lJ%U?P0_7dB{>R``TY;`rS%~w5yQ%k(Wa3 z5kr5=Zrjd5q@Scp=VhgSG0Qp?XmX)k2|HY6>7-rFHr6qp7g%Njrn}plrXItn&LtdTe`=PU}D5CYi>#%P8{Sc2;pTPdYteZ)U2lePMSUF^4>@~Td z1O#`xX(JbilM8{KA>BXjBAbU+oy=`|Z!;wB@8jJtTp9M&b0&T{ch)0i!TUs+SyGV~ z%c<{s#!6y=wk>oRYLC++iJsw_uab@84q|v9<`B4_?IVXJi$^~euibyGcPq0*Xc!@@ z)pTjkX^oU3o400V>z=MHIt+hdfkS)#kDHL)sn2>Kotf0_Ll_7+?XgO(lG*e|PCV6y zLU8Rm)`N>Gncj18b=lee;a}B#+m*!BJ=(KzcaZFcL-jNlV#wgR3PRW4R@qmHF3Pwe zP5xja@{Mwc}&u21!B52L_Qf5~!!Oz-_5nKLcg zBSX>(O4(B|V=oauUJ?NFBflv~ejGX=F7FX5(12h?7iVCQ2ccOZ z0~fXJ7v81}e;U>-_1HarHJRtz;RGteK?*9&T^b`ITOP6&<9N}AkRqdfkm2PLQwL)G zvjYP%FT!=6@h-3}R4X?O?}h72E1sDveAT<5y-fIHNz|m5mqoQ9F*g;U6^xHnZn-z- z&9M#zRx*_$qLh+~rro>J-Rqf6P!I-D#q=pVbV zSa4F_@jricvMGiL_OnZd+|?(qbp5}4^@$(WNnZ5TvWO3Fxg{5#lVbl*P&tzr%~lVn z)x-5`I|#2G%F&XgQ?oKV_xjEqvD>OpthNyTqp zZ7osfq3lbM`^eOru}5(CO5H*D#J(#6BL3PA7@H;$-(c^G`5>21!|T>Azr zBgapG_i3Y7@d;^r;=p@TuOlGzUS0#L>$~P|u&rE@1K)L93VhAG&)~hmiD+K-o-UwT z2dT?I5Kkn$Uk907d{UCjl^B^~Ai&Sy)XZ_48_v=Q`nOnDkdEA$8_e>b%|0vd6DLa;RAXNvEqi9j^8^vCzXLsCRXD<=d zy+$wU0Cj8iFy!J={%y5B z-(KF}plNu>N?geLN;kb59!gH&&pbvFmAk(RQrJa989`F#xAz(zsV??3n`BkpCA5R- zs=>b%h*>XgqTVGLwFeKoFV6ZQZbWTz?ATI>8)*tBSB(+DeM(M<9cuq;-hZ%u%6knt7>vic#X}+93Mu)FJ-o5zSMb8G|gZ*lSQQ zZd>DY{G0vxH8j?tDL&^k<;HDECpLzqfTa3DB0=y%92@ARY!)mh^?WBV^M8{*8Rp_8-Sc zoss_5@1@eh+V`i3sD5DySZYE~-%Lv|cd%~gMP-?w;q zTCW&I^v%n{~ce7^rux&lr7 z#HjJE=GD;`&tIDvS3if}zW;8x%`IZn*=6q3xx zsHLTrzMA&>G`TH`8;JzDy)>i&8iW6o_1*YbY2UV(yGiu8HnjdH|kW>mRp>g#$91(1_XP=Tyb zHu%k8e}v0NwcWH^H@GkhfgcUakbqezskqZ;dqqAB)iz}N6h3V6w)OkimtlfQLla6a z3SOJLZFD?M4C2iI|xtr_|{bB(mta2-2xK;!K3oM8H>mKRyFP`$3C z+*bp7WR)zR8!VwfXl!}e|8TU~ASZaJAkd3EgUE_;^I2&EDf(D~@$W{2Y_Djk(L~X< zoZz1?`Mk(3rP)z#OTFEg+Qyg^{e23Cso8=a61 z-)HI1s@KV1443zLKz_DJpNSi0Q(Mee8;uk|QyM;pk(d+BIrn8V4g#8GWki}s$N-W>MO)YV|7@z(*fZ&h|)HHHq_Igf@hX5j8Gj2 zC9W{8@5~N3i&`9SD06daINeH>R?gLmD0C#;yL&g@ET>2GpAvIi6$}Z(?1Xhjz7ANy|@3(A|Rx3^1^hMJFCFzm=|Dai{Wz9D-+5Wi=Po|<2*D=R7#9mvj@xr>9qo^zCe`O zfVyEJmFhA$vI1f%8rEYrKX)O2F-xd7f6-d30F2wbRCHXfe!;=J(SdV{c6zzN-K$yV zfyCNbb1g8xe57o&CNz&z%GSv`gt?b)H3&-Fl3oB=GREy?e*`sV(V;S-K5nT$u%DI` zL}tVCL&)py8*WVN!RkenW2hG8wkzCBW_AW26`t?iD!-|o=|e2@Zq*N6rFTN(3;;_NJa}VyxGAq$kZ>#GBk& zVC@?97_P?pO}706Kz85E;4=#;*)i6@=|62x^-a#bOh79)wHKh3<@Pkl9C`bi_m_Fl z&z-^hYj^S_vXWo(`S5bq-U2CU!k{i;-${#|36thlTlvGaE2OuQu_}6FpYk0nqAN0T zk{^nGy&f<*AN5ZHaz~qcv(rSs_@?M(y?5hBn{F~@g?(IGA8UD)UIMYl$zeKnF$Z>Q zBd1*ZmkomX3r{vl)Fh<+xn>8hr|V)1$EicYCVA z`*sT5V$C~1*K0;R^Y-`Hzi!L^ByX)1smmk7VyLNqcn5%kz;90!icOj;N#h2OzvUjb80kR-jdmoML?bD9OxSWyU)^?~K!n*8K zD^bcPdtbVTPati54m5;sh6yp87_eSHYf*MZFsKA;z+@>U#o{D1uk=qFCzAb zg@Uq8|C`Fr0wsF^&gC6AmlqQQ1&4XQgQ-yek8n?RwW0M>dJXBeNuQ4Q*f(ih@IW+N z_s!jnBUDxC@<273YEwJVy$O**d?=ZLu}{XwHc^u>LFSQ_y|4KHkg2x?Hu4EEy&D7T zCH`~wECCg~7qGsz;!pYm(Fs~NCppG{0iXh0l%M^Wi}8#Rj^6a-IhP}t!9y!#IQ0K| zD&#glQ2uB{&M>|wHCd0ln*EyM{=socjDSECyaNey^1HY5Bgn)xzFC2)Am)fCXw^is zxTL;f4N>NvnEBKy7}J{t1YJ`1BNTyw(#<6dy!x6I7(s{?~_WrnbMa@!&QNucipTV`i(uHS<7s2nPV1U zmLvvsl=$4Gw#47nI*xz!M4pkSncfE^MapyWM~KBW-haaAx~dlfz825vK1JL6?dq zU>Q%A3?_x{nHfui!MrXR#AMs{Bi-Ql(mC88Qx8AUsKV*;8M?1H4;?}TTocPca z;%TyGT(vaPvr2a_O;rzA<}H6bi1>3X(*|4d7rAmqQtiZHPwDdD!EdWNIX9)ihsREF zgMultWT{Q5sp7r#zp?CdPkzpC5@VZ~nCQPUeW(0!$W(`1f1Yi)gM$N~QbN-9_6me4 zcqvWjRqLKm{NSj+!L-|mGY$UFK7oOS^wk+jQ&V?<LLc(9Eb@hoU{=7upJ5Jw$JYW+RP*0}lx? zRL@&q_L-G>43~gHY6Z@85p2H-hPabxjP1%8x^+hPkJ*%aW|f~+_{VC8 z-z5gF|7jDvEa2VbV?H6*-U0_Ym@eZ9A6RoRHtm9r@8k`X!Gn;^bp{=Xe)%Vg2W%>Q zzw1~CO*bjyioV~<=mVANIri$3|NMYfDeR!U@yTe#M1HPLx@oUXGQt>z*u1F}%FIJf|Q%ftn4SwMh6@^IpYn7RZ=x)JErx4KK6Nk zEoS;lbHj!47!|vS%reU&C);A@zXhoEwYU?$d-;w(GQlf%1m1^UZ#3izj$M1uj^l~L*=f9^ZfNbx zz3M^BP69Vd#Pv~C!V+r7_}TG_mVF@O9^~_6GrhW1^}R-)RB}y?@JxSvHqn+OKQR31 zf?SsI1#SS^f~#I6-&saD1uW0@7T)f>`n3{Fx#Z4gtX?O$WZxk;n#@v(GX_95xVD#1j%Kd-gXX+waI>5y(^c*?hf zKyn4H50T49xR=DfsXP&UUnMgKOemC+!`xS|pg-04%@E5g>U8#%eDS%Ea{kJbb-owJ zlMU34zHBJbEo$hGaFXly3QmskeGcdlc`-HsK7BnpoKfdW@w>hKEgJrWkNqod2MrKG zNsXg~s_v|sZH68n@);f6vhPLf7(+=yr63sR9~>8CXJws~)b#v_G$B%cjhyr0Xih#<_&rg0*8l_vK z4eU~{9mT$v^t4NEhnOkursGYq_QSGgoZn@3aw$rSM?k(ilJ?ECqn-Lo zvNJ^~ElG}`_D#@_4Y*l)16lx=5bUx9($9azm^y@YTU{iJWSvbtNC3t13K3z}myusc zQ{{(%P}yCZ*f-h1jgh}P-_V=+0`d6-nsBM>tC1w)oR_}ta5r$j489k|3*@lnwuyZ6 zJ|82g(VCJ6Vo3B!h)SJF5nlOz>!m*i1SC{Ox5s)1R}xV*xBS>t3qUJ15j(_3mHZpa z+Qdbd(E1O43!23zCQg+cu16b~r~L*Crq9NlcCv$oSm8g*wY@bB#^y?B4`He;Lk_L% zSlRYQCnprj?2=X!L@QwJJ$7I!BD9}thb_Gw(v#+I+`o2M`zkNKpWmFv4&M))KMdH@ z259hN+z_BxVk#f2b-l-*yF6)2Jjl(}gSCA7=yl#JJJK2HJ>F@|9hdx!%|SRmHODJk zB_}`mS^iDeXVJ&Y^L&ulkr&9Shg$lYuP2ZWdi0;QKeYwTc^psJ82dLi{E{EP%u}PR zr2et_(w}M{Z|?^O14?+7tu79f)YqQfAGP#2WI?~lU{9Ju>m?)cnL=d=Mbi<}4jbRF zP}15tOFz$I;pY8Ls@<(c>lj%d>sm!`B+4#TZgpF zgIPht^g^fidIwGV-e|SfA28~|A`xN@!Hhw~;AWSdubR`2Jz1IC8==9Uug&%gZTjf# ze8Ke+MY?6SXrXy@+Sp`=K-=*XFB7*`D???aBgR*icrWIr?xO?s`QUYe=`C(l5ju3T z)wVwnl@Nu|AL{dcWS6TJT$_rTcqFME_-&5mx_Mznpj?;Ikum@2nK5%va_npOj&VJb zkGzO9|NVPAnXZJM%@1c>tZKrdw@dHV-tna8h1Kq8M&0a`?hV4OhLh9rI{LJ!9gqNR zt#7ADV4)k7#+534M$HZ5Lf@=>-hU zA;if75n2Dd56XXw99>{8Ae+m-7I#96hrN#3+g=m;#CRXGOZiokPm|)okh;`{ZO%hg zfu?vzhG8fs{YL$}e431`B{J#OqMUy@|&)Px@YJYo*gbLS*9cX!f1g<;SKs(kTdlPdpLC zjgvY73m>z!^ZJ6KCLNT!P(Ph@Z`GVI`z{q;H5`6)N6D;VrS*H9uC7CEmoCZi=$Q!U z_|>W{n;O`N+}TOpTpwgqUidwk)g!5<8s|XYT>XuF&BOK9N$rM5zR54z&=KpQLDJG)z{3h~(?dL|<|7^RDVVnGtc@W|)uz!hyRl#o9$3_|o1v^X` znm&n(#>aTa!|ZChusj0LqRUZ|7AqM)EaOf?VsmdRN-Am-eRS zEqC?uSdOoBF{!d*Ib<&QMwR7- z*rKMVGGOH9){ZUe%fpZTP$ zZ2f#ZIl!m>DH>CaXN2C3(EOV9{sHzfy=1~I$ueql0J;iNAPc<7uDE^7@#0xnUgho5 zThAnzvL;sUbNZ8xvQTk(vpjtX&AvWF;IKA!xG6|PMzSp0s@lD;y3)Z_Qzl?5ciy0jY8cn$}`H~A(TBCw^jxii~ zOUMei9y;^vKrekj7(e^jp4q9%U!tj@(cQAW@pQpV)2(zqRG;IN$v{wD-T2D=@t2Ie zOTEAWAaR$P9iL++UKDM$ks9x(^$#|wp6D>y5sZTl!e$TPR>${=tr4&x$2_qGo|m{} zZ}?QEB4(sUVJP(S-TxI0ImbwpS13Qv z$j~5q&@tOo)??8~l}FH~GNH$Q3J*r}!S;6~+fZGc2@`r#~c zDm@_?OD3pJLmC! zQ8-p#x=J^9v=*bZkFuvVG|YtaWc=;8(0h z{8m!}ACFfLgrrv#o&|&8J;H%c56)6TL!r2QKU?YU1AjK*B2Q}sgHsJs{f_h(D9?** zfdqxRy^!FbNqi$zN9Maw9s#2-tDylarDWS+`&Nd^Wij1?Ul#^~8dV5Cl}*6JF*iVZ zmzSN|f>j+zVVWp9#C{Afh_+JsNA73j@&;=;B=2M{4~!kK5u_~*r01Mx+2(_Q0t3nc zZQ}C0D4Se8*l}f88vK-POj@--J6HK3MH0X*sI?zOcnsDyy2av@e0+fUZVuNo=4GFU z%-78cElU0>gTUszn~FgL0e?DRkbfiP zv81|Ru1Xa8d!>@tpAN=+C5~D)R8_G24@>&a#oo)h+gJ3rle{}fRFldemH2ev)*d1*MgAKYZv~x!8cqfVM|(UTtsS42xQ0a=*L3JA`Rl06H>*n?`y?_heEA;&zhv}pEji3+gjf%#e=yYd16`%cH@#@oIJe9LVxRCo>nZ84CnwGK_Qz@&4%+f3f1}D4`)Qw z2(p0{yHjbn@Dr&w*Z%$>7Tq#Q%3JN^Aga8r83$Kt z1~)R{-d6DCPL8P@KU*Gys;k(MC{>oj;j;hq2iUXcrn57Zw%;`c0rqAipkq;>cP&oA zGDYJMs4w>Sh9TpW=nyji-LTMcOmw3f;h*zY%yOx`Y{^kReCho(TskR!9J&g1H z{}Qhk9L_xPRT_Ekuk&9iW@SvWbXj!rz5iU@?^$>M#s$_KD5SUG?!C;t!4tat!)it^ zFkOnfbWZD++>9RZ1tC2qyYPMh0zW#W2pGA^o+emHf0P;j9gY_B?n)*aAO|lu7l}|q z?jNoAq-%dr!vmabe0L8 z^^3s!->`QU6xe@>NNbOu&pFpbUPJ(Mfc2h}li=_F!Glk==E8s#{4-nc+TQP>8>{s# zv}ML{C?(;4VX0k&zEk}V2^cqh_6_ezz^LAR1_A)1?bmqOMCwbL9-zmhB0`7QzbK~> zydvKx^y?1qQ?hp2;#YtFhhM=f{af~B-MgP;;=1i0)cMWAj)T1(?SSJGzBmAObqH85 z{?C_Ve+9aGazZTVfToPYkJo}ii^1_9zPua2D(%)==TNfJRr22vOa}%>P#l9>tO1VZ z3egw#B{%L(0`>*gjFEHAFvk?1X7H8+L~>5P2~b~rbNGrY5b|=>*5TXyzyT0vP>3(; zwn4T40q$HME$u_zD+lWawqrN&hJ$^2szX=<<*T3|L(T=BNe-=}Vk-#lD8J0xD+Ory zPi-VUD@s;>Xnloeb9t&$9nhgludxUP!z1_090@X(dH2JR@d4*l6hv{r&7iYnI9iKT zgjWw#AgJ>vP$+~kKT7{=r{Z_b9N=*81(JP`=jKa=5;!0$oOK%otRo1U9P|9ow;3P5 zCIKmb`=MENwR3qX^nYd&c8}RkT4Ei&bQo30ISvvAU0CC=D9ciJEi^Z57J@kjX?iX= zfJJueoqw}_GZ8AO-VCV3Y{?hOtXMk)|Fc?jii6ldsl0N%Q;=l7llA%Bx!fd%y;lA2 z1yTReQotP306}Y&hBh2kyJlX8;?g1yQAT?Ll}nVj16#b^uV9nlyCq}hnqR>gl)gl} zG+k+shF&4Z6N!8IfD;R(~rHVT5%?f~(@|&BlH~smO2Tog5x}BOa zN!DzSE0oT~&b@R2k=D$OdZ};|ifNlbLwKxqi{hJFTT6g@-8^!iqHFVe6?NNRyaHbM zKL{i7I5RL{bJ?Xs-g-eKP4@v!PJWRE()OIwi;R*$%%je)`#aHZ$SW1)Ug zYp1_I;y7STT1fcuFEq5xf}eIuSfW~90-8lYT=0F;m{^BK%g%n|!T1!1u;@fk&(|#T zY4OB*ZqR~&K|&n}Y(zA`z}?Q>IdeGzt*WhL0CW12JgTP}lg_wINR)4^@2v+p%pah* z=NelSpniS8v4ndJ2nRTCGmUQ5R6meLS(~q<)}f&T!{A6%snle)MPXew^j(-THU`9W zSqSTriL^QQ*a5ExkQ=0J_F6gMh)!jQEI@O@8dU%&x^JG$NFaE5&Yled+$U$3H>ggP z>L1!AEUE5`c{VmNg|y-2YVV||7RuD`;|-SJ0WJ9v-xKJEVqJZ&5!C@X0D22~_=Q(@v*D!6QMtW9=2X;22qp78( zMfru;h}VhY)5`b6(hz!7d3+EF}e7vAVNO+z2t`ZM2gbCnlABRj_5&|eBcv&utWLLFI%A2CR~^yJ>kcX@$$>9`R#2V zy9tZ-XoC0oSsB{*@$KB0y6d2Ev0uf=Q3O{XmdAjlZAWu#a(o z_i-vB>&MW9GTrXo-S}s+sL269Ml;QFQ!S0hV!MX|Q0F>HQozs^jsmu&EO3%2XJf}b z4RNr;*@DgVrBK^j!7H^j@H%{$vi>WL2vBum3n~Cc-urYn#O^enQCBt`NRcj;HgH8j zuGi5X`L-F3?7w>B^P8U~Std`X6=%R{6lrjpWCg!9#<{)9Gj{0f$^$&G38vGY8wLf` z82ybNEdO|L&H+;4s~w?1j9|0zoi_}E5Kuv8gQWrT(z9i8rO|;5dFn9H<0C;`FKF3w zTVZmOnr}E!v2m+F$lfDHO8dq4;eE3oi7&6rNVwB`C@7@s-)$EM&|8p4WO{_d`M|*aA4zB=3PY> zK(jN`u&D)mjM6WXc*=6jZtYto+W zw$z~bZ%TURe@ac>MI0mOMNVnyf4}stnkG5-mm|yu6gzA0OokB@Rdl5;13Z8Or`a9} z1V=keMS!HBb1TWMg}}sDb-6Nbe!1K_Kx`~(KR0tX4P>-$I$?%5Lf0AMM$I{52!1~( z1{MEm9Qs$#v1T0^5P)$9pcgn>x<1Xgx{LF0WZWQ60cyy z6~c+R$2g4z^~j9bDko8OOzZ^`NT4nLI>%UIH7t3R5)|q>3v&5wbQ(0B@s6jZkNzH! z37pS&?2!KIM;{J{w*#ecaR}*#8LU9)sP{V=>~SVFjV%1mcFY2{`n&(ic8+*;@Lx%C ziAS<-0NssvgeLH$2OJYo9b3>9+z6%jI%WeH&T$}?iV#93iP=fWSeY7mwVm%%Vm^gs zU{HNV1vSa5SxvLS*Pqvp>nMYBhRBa1!rMM?(}g9x2nq;&I4PtJ+p3HI*IVK9E|$)< zp^#fOnu@xzAM+YE##~+wJ5@LaaU$~cG?xg_0>AAooNqsS|DN^3iJGoACn@J{jSCb# z>a1%itJfaq&-0KF0M#DfD4x_LSzjwYuxM=+jcb7()N;mW2yo6CT5^n|V8_iD7-%yT zSVMo1zuj@_<4vx%Fdb;?Cl&My!BccXklJ=G-BTGi+cM3ROQ91)${FgE;umAZfa~Wt z9oSm&+6^Sd{w8vY-+@d$4iqT`h{-2uJQ*TAsR~FAsy3A9U?ixD!D5Q#d@wupmdM@T zZr148NRUK_7&6h}f!E}0QN)aPycFv!)_<;#-sh5AJI{UK6;<)@HN5`@!^obaxQa~r z-qwKP_PW&HG`&!*PeH#HmRqN?Mf)g_JLm9@TDCzF+t`F27@^wHnyRi}w`9?ZLhIVC z0{6tRE%h+U6?!$}8a+33U7>YzzDUQ@x_tB`iQwlaJ+^ve6oTT~0M1@{pbLnH17nWp zrrH>o%3R>SxGlh_oWTo&z)|mPLhZw)b-mkAz_iQGOlR(cq8#Y1ht5~m|agUxp$eCzhTHH8VWlXIkoeo+Zz(9*2dSgp?nX9Vt zCJ!*BO2Yi9;e?7KUsD-c>Aq_)o@|^M8;sj14La~I`SxRwt4M7

(TR{3lyS@Y}Z>39*hjNe-%%<|0|tF)fZPJubGL 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 R(;2vQ&g-AcK6Cxf{{X`jgLeP` literal 0 HcmV?d00001 -- Gitee From a3324a5b3e728001d7d02553e10f5fc19c49dca9 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 7 Feb 2022 12:45:06 +0800 Subject: [PATCH 02/10] add light file Signed-off-by: zhouyanxu --- .../driver/driver-peripherals-light-des.md | 140 +++++++++--------- 1 file changed, 71 insertions(+), 69 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 3ace49b94c0..4669d341c82 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -5,17 +5,17 @@ - [运作机制](###运作机制) - [开发指导](##开发指导) - - [接口说明](#section188213414114) - - [开发步骤](#section7893102915819) - - [开发实例](#section257750691) - - [调测验证](#section106021256121219) + - [接口说明](###接口说明) + - [开发步骤](###开发步骤) + - [开发实例](###开发实例) + - [调测验证](###调测验证) ## 概述 ### 功能简介 -​ 灯(light)驱动模型为上层灯硬件服务层提供稳定的灯控制能力接口,包括获取灯类型,灯常亮,灯闪烁效果配置,灯停止的能力。基于HDF(**H**ardware **D**river **F**oundation)驱动框架开发的灯(light)驱动模型,实现跨操作系统迁移,器件差异配置等功能。实现Light驱动“一次开发,多系统部署”的目标。Light驱动模型如[图1](#fig10451455446)所示: +​ Light驱动模型为上层Light硬件服务层提供稳定的灯控制能力接口,包括获取灯类型、配置点灯模式、配置灯闪烁效果、点灯、熄灯等。基于HDF(Hardware Driver Foundation)驱动框架开发的Light驱动模型,实现跨操作系统迁移,器件差异配置等功能。实现Light驱动“一次开发,多系统部署”的目标。Light驱动模型如[图1](#Light驱动模型图)所示: **图 1** Light驱动模型图 @@ -23,28 +23,28 @@ ### 运作机制 -通过介绍Light驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如[图2](#Sensor驱动模型图)所示: +通过介绍Light驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如[图2](#Lihgt驱动运行图)所示: -**图 2** 灯驱动模型图 +**图 2** Lihgt驱动运行图 ![Light驱动运行图](figures\Light驱动运行图.png) -灯驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及运行流程: +Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及运行流程: 1. 从device info HCS 的Light Host里读取Light设备管理配置信息。 2. 从light_config HCS读取Light数据配置信息。 3. 解析Light设备管理配置信息,并关联对应设备驱动。 4. 客户端下发Light Stub控制到服务端。 5. 服务端调用Light Stub控制。 -6. 启动灯抽象驱动接口。 +6. 启动Light抽象驱动接口。 ## 开发指导 ### 接口说明 - 灯驱动模型支持系统中所有灯的信息和动态配置闪烁模式和闪烁时间配置能力。灯硬件服务调用GetLightInfo获取灯设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。灯驱动模型对HDI开放的API接口能力,参考[表1](#table203963834718) 。 +Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模式和闪烁时间的能力。Light硬件服务调用GetLightInfo获取灯设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。Light驱动模型对HDI开放的API接口能力,参考[表1](#Light驱动模型对外API接口能力介绍)。 -[表1](#table203963834718) 灯驱动模型对外API接口能力介绍 +**表1 ** Light驱动模型对外API接口能力介绍 | 接口名 | 功能描述 | | ------------------------------------------------------------ | ------------------------------------------------------------ | @@ -53,33 +53,35 @@ | int32_t (*TurnOffLight)(uint32_t type) | 根据指定的灯类型关闭灯列表中可用的灯。 | ### 开发步骤 -1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成灯抽象驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现,配置资源和HCS解析。完成加速度传感器驱动的设备信息配置。 +1. 基于HDF驱动框架,按照驱动Driver Entry程序,完成Light抽象驱动开发(主要由Bind、Init、Release、Dispatch函数接口实现),资源配置及HCS解析。完成Light驱动的设备信息配置。 3. 调用配置解析接口,完成器件属性信息解析,器件寄存器解析,并注册到Light设备管理中。 -3. 完成灯获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 +3. 完成Light获取类型、闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 ### 开发实例 -1. 灯驱动的初始化和去初始化 - - - 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 灯驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)介绍。其中Driver Entry入口函数定义如下: +1. Light驱动的初始化和去初始化 + - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 + 灯驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍请参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。 + 其Driver Entry入口函数定义如下: + ```c - /*注册灯入口数据结构体对象*/ + /* 注册灯入口数据结构体对象 */ struct HdfDriverEntry g_lightDriverEntry = { - .moduleVersion = 1, /*灯模块版本号*/ - .moduleName = "HDF_LIGHT", /*灯模块名,要与device_info.hcs文件里灯moduleName字段值一样*/ - .Bind = BindLightDriver, /*灯绑定函数*/ - .Init = InitLightDriver, /*灯初始化函数*/ - .Release = ReleaseLightDriver, /*灯资源释放函数*/ + .moduleVersion = 1, // 灯模块版本号 + .moduleName = "HDF_LIGHT", // 灯模块名,要与device_info.hcs文件里灯moduleName字段值一样 + .Bind = BindLightDriver, // 灯绑定函数 + .Init = InitLightDriver, // 灯初始化函数 + .Release = ReleaseLightDriver, // 灯资源释放函数 }; - /* 调用HDF_INIT将驱动入口注册到HDF框架中,在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动,当Init调用异常时,HDF框架会调用Release释放驱动资源并退出 */ + /* 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release函数释放驱动资源并退出 */ HDF_INIT(g_lightDriverEntry); ``` - - - 基于HDF驱动框架,按照驱动Driver Entry程序,完成灯抽象驱动开发,主要有Bind,Init,Release,Dispatch函数接口实现。 + + - 基于HDF驱动框架,按照驱动Driver Entry程序,完成Light抽象驱动开发,主要由Bind、Init、Release、Dispatch函数接口实现。 ```c - /* 灯驱动对外发布的能力 */ + /* Light驱动对外发布的能力 */ static int32_t DispatchLight(struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) { @@ -102,16 +104,16 @@ return ret; } - /* 灯驱动对外提供的服务绑定到HDF框架 */ + /* Light驱动对外提供的服务绑定到HDF框架 */ int32_t BindLightDriver(struct HdfDeviceObject *device) { struct LightDriverData *drvData = NULL; CHECK_LIGHT_NULL_PTR_RETURN_VALUE(device, HDF_FAILURE); - // 私有接口分配资源 + /* 私有接口分配资源 */ drvData = (struct LightDriverData *)OsalMemCalloc(sizeof(*drvData)); CHECK_LIGHT_NULL_PTR_RETURN_VALUE(drvData, HDF_ERR_MALLOC_FAIL); - // 需要发布的接口函数 + /* 需要发布的接口函数 */ drvData->ioService.Dispatch = DispatchLight; drvData->device = device; device->service = &drvData->ioService; @@ -119,21 +121,21 @@ return HDF_SUCCESS; } - /* 灯驱动初始化入口函数*/ + /* Light驱动初始化入口函数*/ int32_t InitLightDriver(struct HdfDeviceObject *device) { ..... - // 工作队列初始化 + /* 工作队列初始化 */ if (HdfWorkQueueInit(&drvData->workQueue, LIGHT_WORK_QUEUE_NAME) != HDF_SUCCESS) { HDF_LOGE("%s: init workQueue fail!", __func__); return HDF_FAILURE; } - // 工作项初始化 + /* 工作项初始化 */ if (HdfWorkInit(&drvData->work, LightWorkEntry, (void*)drvData) != HDF_SUCCESS) { HDF_LOGE("%s: init workQueue fail!", __func__); return HDF_FAILURE; } - // 解析HCS配置文件 + /* 解析HCS配置文件 */ if (GetLightConfigData(device->property) != HDF_SUCCESS) { HDF_LOGE("%s: get light config fail!", __func__); return HDF_FAILURE; @@ -142,11 +144,11 @@ return HDF_SUCCESS; } - /* 释放灯驱动初始化时分配的资源 */ + /* 释放Light驱动初始化时分配的资源 */ void ReleaseLightDriver(struct HdfDeviceObject *device) { ..... - // 释放已分配资源 + /* 释放已分配资源 */ for (i = LIGHT_TYPE_NONE; i < LIGHT_TYPE_BUTT; ++i) { if (drvData->info[i] != NULL) { @@ -154,7 +156,7 @@ drvData->info[i] = NULL; } } - // 销毁工作队列资源 + /* 销毁工作队列资源 */ HdfWorkDestroy(&drvData->work); HdfWorkQueueDestroy(&drvData->workQueue); (void)OsalMutexDestroy(&drvData->mutex); @@ -164,47 +166,47 @@ ``` - - 灯设备管理模块负责系统中灯器件接口发布,在系统启动过程中,HDF框架机制通过灯 Host里设备HCS配置信息,加载设备管理驱动。 + - Light设备管理模块负责系统中灯器件接口发布,在系统启动过程中,HDF框架机制通过灯Host里设备HCS配置信息,加载设备管理驱动。 ```hcs /* 灯设备HCS配置 */ device_light :: device { device0 :: deviceNode { - policy = 2; /* policy字段是驱动服务发布的策略 */ - priority = 100; /* 灯驱动启动优先级(0-200),值越大优先级越低,建议默认配100,优先级相同则不保证device的加载顺序 */ - preload = 0; /* 驱动按需加载字段,0表示加载,2表示不加载 */ - permission = 0664; /* 驱动创建设备节点权限 */ - moduleName = "HDF_LIGHT"; /* 灯驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 */ - serviceName = "hdf_light"; /* 灯驱动对外发布服务的名称,必须唯一 */ - deviceMatchAttr = "hdf_light_driver"; /* 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 */ + policy = 2; // 驱动服务发布的策略 + priority = 100; // Light驱动启动优先级(0-200),值越大优先级越低,建议配置为100,优先级相同则不保证device的加载顺序 + preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载 + permission = 0664; // 驱动创建设备节点权限 + moduleName = "HDF_LIGHT"; // Light驱动名称,该字段的值必须和驱动入口结构的moduleName值一致 + serviceName = "hdf_light"; // Light驱动对外发布服务的名称,必须唯一 + deviceMatchAttr = "hdf_light_driver"; // 驱动私有数据匹配的关键字,必须和驱动私有数据配置表中的match_attr值相等 } } ``` -2. 分配资源,解析灯hcs配置。 +2. 分配资源,解析灯HCS配置。 - - 解析hcs配置文件。 + - 解析HCS配置文件。 ```c /* 分配资源,解析灯HCS配置 */ static int32_t ParseLightInfo(const struct DeviceResourceNode *node) { ..... - // 从hcs获取支持灯的类型个数 + /* 从HCS获取支持灯的类型个数 */ drvData->lightNum = parser->GetElemNum(light, "lightType"); .... for (i = 0; i < drvData->lightNum; ++i) { - // 获取类型 + /* 获取类型 */ ret = parser->GetUint32ArrayElem(light, "lightType", i, &temp, 0); CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "lightType"); } for (i = 0; i < drvData->lightNum; ++i) { ..... - // 类型作为下标开辟空间 + /* 类型作为下标开辟空间 */ drvData->info[temp] = (struct LightDeviceInfo *)OsalMemCalloc(sizeof(struct LightDeviceInfo)); ..... - // 将Light设备信息进行填充 + /* 将Light设备信息进行填充 */ ret = parser->GetUint32(light, "busRNum", &drvData->info[temp]->busRNum, 0); CHECK_LIGHT_PARSER_RESULT_RETURN_VALUE(ret, "busRNum"); ret = parser->GetUint32(light, "busGNum", &drvData->info[temp]->busGNum, 0); @@ -220,20 +222,20 @@ - 灯效果模型使用HCS作为配置描述源码,HCS配置字段详细介绍参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)介绍。 ```hcs - 灯数据配置模板(light_config.hcs) + /* 灯数据配置模板(light_config.hcs) */ root { lightConfig { boardConfig { match_attr = "hdf_light_driver"; lightAttr { light01 { - lightType = [1, 2]; // 灯类型组,一个物理灯对应多个逻辑灯 - busRNum = 31; // 红色对映的GPIO管脚 - busGNum = 30; // 绿色对映的GPIO管脚 - busBNum = 29; // 蓝色对映的GPIO管脚 - lightBrightness = 0X80000000;// RGB: R:16-31bit、G:8-15bit、 // B:0-7bit - onTime = 50; // 最小闪烁时间(ms) - offTime = 50; + lightType = [1, 2]; // 灯类型 + busRNum = 31; // 红色对应的GPIO管脚 + busGNum = 30; // 绿色对应的GPIO管脚 + busBNum = 29; // 蓝色对应的GPIO管脚 + lightBrightness = 0X80000000;// RGB: R:16-31bit、G:8-15bit、B:0-7bit + onTime = 50; // 一个闪烁周期内亮灯时长 + offTime = 50; // 一个闪烁周期内熄灯时长 } } } @@ -244,12 +246,12 @@ 3. 完成获取灯类型,闪烁和停止接口开发,会根据闪烁模式创建和销毁定时器。 ```c - /* 灯驱动服务调用GetAllLightInfo获取灯类型,Enable接口启动闪烁模式, + /* Light驱动服务调用GetAllLightInfo获取灯类型,Enable接口启动闪烁模式, 调用Disable接口停止闪烁 */ static int32_t GetAllLightInfo(struct HdfSBuf *data, struct HdfSBuf *reply) { ..... - // 获取light类型个数 + /* 获取Light类型个数 */ if (!HdfSbufWriteUint32(reply, drvData->lightNum)) { HDF_LOGE("%s: write sbuf failed", __func__); return HDF_FAILURE; @@ -260,7 +262,7 @@ } lightInfo.lightType = i; lightInfo.reserved = NULL; - // 将Light设备信息填充进reply + /* 将Light设备信息填充进reply */ if (!HdfSbufWriteBuffer(reply, &lightInfo, sizeof(lightInfo))) { HDF_LOGE("%s: write sbuf failed", __func__); return HDF_FAILURE; @@ -274,7 +276,7 @@ static int32_t Enable(uint32_t lightType, struct HdfSBuf *data, struct HdfSBuf *reply) { ..... - // 根据用户传的亮度值设置灯的颜色 RGB: R:16-31bit、G:8-15bit、B:0-7bit + /* 根据用户传的亮度值设置灯的颜色 RGB: R:16-31bit、G:8-15bit、B:0-7bit */ if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_R_BIT) != 0) { drvData->info[lightType]->busNum = drvData->info[lightType]->busRNum; } else if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_G_BIT) != 0) { @@ -282,28 +284,28 @@ } else if ((drvData->info[lightType]->lightBrightness & LIGHT_MAKE_B_BIT) != 0) { drvData->info[lightType]->busNum = drvData->info[lightType]->busBNum; } - // 常亮模式 + /* 常亮模式 */ if (buf->flashEffect.flashMode == LIGHT_FLASH_NONE) { if (GpioWrite(drvData->info[lightType]->busNum, GPIO_VAL_HIGH) != HDF_SUCCESS) { return HDF_FAILURE; } } - // 闪烁模式 + /* 闪烁模式 */ if (buf->flashEffect.flashMode == LIGHT_FLASH_TIMED) { drvData->info[lightType]->lightState = LIGHT_STATE_START; - // 用户设置的闪烁时间小于系统支持的最短时间,采用系统配置的时间(HCS配置) + /* 用户设置的闪烁时间小于系统支持的最短时间,采用系统配置的时间(HCS配置) */ drvData->info[lightType]->onTime = buf->flashEffect.onTime < drvData->info[lightType]->onTime ? drvData->info[lightType]->onTime : buf->flashEffect.onTime; drvData->info[lightType]->offTime = buf->flashEffect.offTime < drvData->info[lightType]->offTime ? drvData->info[lightType]->offTime : buf->flashEffect.offTime; - // 创建定时器 + /* 创建定时器 */ if (OsalTimerCreate(&drvData->timer, drvData->info[lightType]->onTime, LightTimerEntry, (uintptr_t)lightType) != HDF_SUCCESS) { HDF_LOGE("%s: create light timer fail!", __func__); return HDF_FAILURE; } - // 启动周期定时器 + /* 启动周期定时器 */ if (OsalTimerStartLoop(&drvData->timer) != HDF_SUCCESS) { HDF_LOGE("%s: start light timer fail!", __func__); return HDF_FAILURE; @@ -315,14 +317,14 @@ /* 按照指定的类型关闭灯 */ static int32_t Disable(uint32_t lightType, struct HdfSBuf *data, struct HdfSBuf *reply) { - // 删除定时器 + /* 删除定时器 */ if (drvData->timer.realTimer != NULL) { if (OsalTimerDelete(&drvData->timer) != HDF_SUCCESS) { HDF_LOGE("%s: delete haptic timer fail!", __func__); } } - // 对应的GPIO下电 + /* 对应的GPIO下电 */ if (GpioWrite(drvData->info[lightType]->busRNum, GPIO_VAL_LOW) != HDF_SUCCESS){ HDF_LOGE("%s: gpio write failed", __func__); return HDF_FAILURE; -- Gitee From 5448529f1d5ca89f98c797fa2e213b180e96eefc Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 7 Feb 2022 12:50:02 +0800 Subject: [PATCH 03/10] add light file Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 4669d341c82..25bc60dec71 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -42,7 +42,7 @@ Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及 ### 接口说明 -Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模式和闪烁时间的能力。Light硬件服务调用GetLightInfo获取灯设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。Light驱动模型对HDI开放的API接口能力,参考[表1](#Light驱动模型对外API接口能力介绍)。 +Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模式和闪烁时间的能力。Light硬件服务调用GetLightInfo获取Light设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。Light驱动模型对HDI开放的API接口能力,参考[表1](#Light驱动模型对外API接口能力介绍)。 **表1 ** Light驱动模型对外API接口能力介绍 @@ -62,7 +62,7 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 1. Light驱动的初始化和去初始化 - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 - 灯驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍请参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。 + Light驱动模型使用HCS作为配置描述源码,HCS配置字段详细介绍请参考[配置管理](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/driver-hdf-manage.md)。 其Driver Entry入口函数定义如下: ```c @@ -166,7 +166,7 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 ``` - - Light设备管理模块负责系统中灯器件接口发布,在系统启动过程中,HDF框架机制通过灯Host里设备HCS配置信息,加载设备管理驱动。 + - Light设备管理模块负责系统中Light器件接口发布,在系统启动过程中,HDF框架机制通过灯Host里设备HCS配置信息,加载设备管理驱动。 ```hcs /* 灯设备HCS配置 */ -- Gitee From be4620dd2d37b6b0435b5a5c9273bd550b928821 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 7 Feb 2022 15:16:59 +0800 Subject: [PATCH 04/10] add light file Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 25bc60dec71..02a2d20cd4e 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -19,7 +19,7 @@ **图 1** Light驱动模型图 -![Light驱动模型图](figures\Light驱动模型图.png) +![Light驱动模型图](figures/Light%E9%A9%B1%E5%8A%A8%E8%BF%90%E8%A1%8C%E5%9B%BE.png) ### 运作机制 @@ -27,7 +27,7 @@ **图 2** Lihgt驱动运行图 -![Light驱动运行图](figures\Light驱动运行图.png) +![Light驱动运行图](figures/Light%E9%A9%B1%E5%8A%A8%E8%BF%90%E8%A1%8C%E5%9B%BE.png) Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及运行流程: -- Gitee From 7de3657b8ba76da8b25713760b2a60835816130d Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 7 Feb 2022 15:25:01 +0800 Subject: [PATCH 05/10] add light file Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 02a2d20cd4e..36d535b29f6 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -19,7 +19,7 @@ **图 1** Light驱动模型图 -![Light驱动模型图](figures/Light%E9%A9%B1%E5%8A%A8%E8%BF%90%E8%A1%8C%E5%9B%BE.png) +![Light驱动模型图](figures/Light%E9%A9%B1%E5%8A%A8%E6%A8%A1%E5%9E%8B%E5%9B%BE.png) ### 运作机制 -- Gitee From 8f047660adf19d6f4578b56e3c591dc5796c5709 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Wed, 9 Feb 2022 16:59:22 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E4=BC=98=E5=8C=96Light=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyanxu --- .../driver/driver-peripherals-light-des.md | 2 +- ...0\350\277\220\350\241\214\345\233\276.png" | Bin 25064 -> 33408 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 36d535b29f6..3dd95f1280f 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -25,7 +25,7 @@ 通过介绍Light驱动模型的加载以及运行流程,对模型内部关键组件以及关联组件之间的关系进行了划分,整体加载流程如[图2](#Lihgt驱动运行图)所示: -**图 2** Lihgt驱动运行图 +**图 2** Light驱动运行图 ![Light驱动运行图](figures/Light%E9%A9%B1%E5%8A%A8%E8%BF%90%E8%A1%8C%E5%9B%BE.png) diff --git "a/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\350\277\220\350\241\214\345\233\276.png" "b/zh-cn/device-dev/driver/figures/Light\351\251\261\345\212\250\350\277\220\350\241\214\345\233\276.png" index a48f73c18f7338ef1e18084733f72471b129f4e6..e845adca92ab627fc669e7d39c40a97f4352faec 100644 GIT binary patch literal 33408 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%0A+$R6=4rhmJp|HRi8kgnx?cXXrLR}@} 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 literal 25064 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

(TR{3lyS@Y}Z>39*hjNe-%%<|0|tF)fZPJubGL zt&3+Nmy{mmx{nDQT;J>_L@|X-?S|7zG+bNc+0KWn4SzlnkZrZ>2y^a~H*(L(49L!t&A#9J`@x_6r!HGZ;(tMb z#cBe*KP8vi13bzpp~ZXPAd_wDM8J!?Ka>_W-ua=+%dVFR?HH0&SM*463F~hh0p2LE z)Xnu1X4~9aio})^$xdLi_D-x|O={8Yqc-<&p&T*?^S%qGQsibEzB_G^#DCp9fFP{) z<<>!P;Jg#D%FrXJjOTR(RfIO z;OYv`WcNQ8{|_Rlq*fQM%QO1tn~>c9Sd6aS1!qH)=5<0+^Z>hM;d8Ber?I`iE}tBf z{J%4TQG@>0URC8Te|+w}ITaUTxtVK(o|d1rDGA;Xy!feK3DaB^i!1WoP2&I-$!PbY z@rt;F}N+!f~+lc)Cz8M`s_Bw7pl8CJo!b`G`mX zb~dq9z&BJ`pI8YduYaIRyfL5%^0aPg8xPTaChuh5B+OaJF!jVHiuh3p2XAFvpyb4> zc)hgxDRV}>CN*$E+=Y4hu%y1NH|J~D;<_dK-k*8KvAtMH0fHFXmOt#A==GYhGFw_A z^oncG6>gMfnEu07^O=F-LZc6-4V2Q6D^m`#!gJ#PUgX(^xVp!XE+dbt{J}cssRTe( z%>rEnp!Fi6DPGZS`NsffCzclu{+KE_3c;>r&s~%0+XO;&c4-sk{%qc9H02|~>J10f zx1{Rn(5&7?QlxeK&AVaNJUGh5)N=QDBaB`RcvQf68&r=brg-li?utPy+ZiB$RWAM9 zZktobspqb4+Lje&rKJRexRPW7nMBx3PwQ|3_3B!F4#Vd_5OXpg0GBqW(qgzJ1RJj5 z#b{qX#&U&j5cx{%Yhz9G!JJInbLSGBCOi4k0X8K&tZWU%ymV^st1Tg?$;3!5Cn|Js zZ+y9BfR5=zao|VV{WwXQQ1pmL%ks+PSRv!)qdMA~Sh|cf%}jW0xMy%r>ZW7cG~O?= z0KGYRgd_kKwzS_TG)R==FvCq$?hwyaD=MHK>5GSXP{s(BEDG~b9IDvlR7a)bhgkaIA`^fs_lGFLEVFS6JUwLGX)skWt$yV}A-Z>!GT+@)w! z`nx3fhYI^6A^8;~c)fNtSFAgfhI0}8tt|AC>j>xmZ|~+9K0$8y8Lc143Y^if!=9O2 z&d0L*EQxt{C}m{O(bYN3hrLTy9a-$hrtzrbVI~B>x4i<{ZiHR*Ukbw6bw0&e({?e#p^YP!iep5@Lp`dEv>SO3l$i^V zu3q);6B8fluP@))kZ1rsG`!ghsbsZSvjA0GVsL=h@gv4RI0tSx1|`%oAW(g;#8n5L z-s!6K+F%E2AV&bbS~8S*4sruPbU0?g!A;b{8aQi0Ec3EMZmd$W?`Gd?1ya0F8OQFx zdi-?TNzlM(dVNl^_@QPJ7%Q_6FIzl{HX8C8s>{`XXdPi(oUjtg3Sv!lzA3=TF~nIG&o%8zu~ zPh%}l|7|+M&#oVz0$qpLdpi4p($1;&=hWiBr3qqS+eMe2A8+sQEG~}=ogJbkz&&Q` z7W8oX&e0)Vh}WPDJ)C2Mm5`9t^lJltQ?s;EnLg)!gqs*`U4%Q}P!FYCH;4&jchY3J z&wPj0$7<$8l800hN%1u?yu;RF`bm7t0dYe8f;-J(h~3 zVkw89U6?L-SB$D-YY}*WNrfGF{!UV6=Qr8!p)+0I?ZC4^iosJrD*wm{bLIYgopp_y zokBtM))JKBe{6`-Ze4wWCKz0IO7XsL5));E;8>*$bQ~J@B)*#QwiZb$S*KE*B9s;*L+g>mGO9_dnW9uAyma&bQ znox$umTfE}%h>lA`}3VT{eI_<=fCIq%e=fSGxvSZeO=e*dVk)di<`f%el69>aDn}8 zw~Bw@NE|B*O1;+E3wFA=?}Z`RXZp-H+(l_wIfunsSo~ zt0qgH#QuSk{Oj17Mq!AjQW|RP(^LuYM(nGq0+`^qe!!{K-&dQVyVshZt_0}fbA;cY zk(#5Id$_DecB>zSPL~(Sb3|uk*Ss$J!?gNNpy|A&cNguL61_kPn!Cu)PI!>eUtr@%!an2afkt8_ z0rNOI_l4NJ1msZ)5P5O)8}OLcCtNUpASF73=y|NU^#=2fCDaJZ9<(R&BdoFK_Brr+ z4>wjy%b(>jXIs)N{dWh&tTkuSj^7-XS@!5$(O?VbsSCxoTVt-?Mz4GG1vbB%)3NCc z@QbK}hR0IGsJm-fQK8sqxx-m`;lhB{`Rbe`WQ{QO67Do5J@B=W&?Qmsr0**_I9Q7@ zau50Fcmkr5=#U<3BejzWrJ4q;*5^ZpGx>z1Gw^!mUJlna-QgcfkTUm3$d#E|)xo9m zX^QPcdlucm>F*2K$aM@Vl&0zCZ=Ym&_C9shwIT2$a?@?=P@k4M4Ng(-UyQU7KVbQu zIAD?g(2U+zf4^)DR03J&iGdt2-TaIdfZKg7LcoSv&A;lLq;LRZ>HW+c&EhJ4yV-v1VIvIDuSvNzh6l}3Yoev5N^EK53YJQ3DrBhy{a2Ol+7<}>;>ucNAY>Ej=e7h- z1J7wL?z2H|X%WcSGXE&`85nOS*uTjOAIPLsU+j1s2}!HgzAT%`HN%*IsrLe&dsemi z@JfOq{KbdvKj0qS&WCU5y>rtz`0)dN;2*uhvC1wO>ivL*Z#$>%LU)y%ZflWOTR!SO z^rxcO5>g{byK_c`2kGe4wM^-`_w(^(?W$)NN;HRuhjQn>X6-sdDR9aUU3Tg^%vg&-~!ASVThW< z-hCU|_B%y6n0G~6S(pvQ)_i^;2{o@^l`VsyqFpqmFZH zB2;;WYW(mu?x*XNVhIw9mX~h&}Rc&*TYG;B^hB!J#8QqhDMv z^5RDhjc|_$O0Wq@r96?~xB0R=0TV#2m!X-&k|}XMA~~dRL7L8daww+62(wsus~L54 z_fX1Zc|RdU4Qld0x(G9@H6I!Nbm9BF4oL^`k%3&la>9?ctES%RTPsmO~7}C|aZ4$$0*c^DC1UZyOOi1lXqmFIgmMEl=d9$aU+SU^Z>F zznL|HF(f*D{d>noKXS&k45(f#7Ne*8MQxqJVd^EktyR7C0(C4oz@vn1{{jz z_&jQUs^2jx%bFN|Ej>^=V>(IVT4k5d(_L$a)C&sUM}@RaIm*^FXQ>zY+fcOUmc*Sh zt;iK+#8;R7bv~k~q`5Jw7s#&6-7Xu$KZW`2#_hd_k8}gN-1}knQm$-j67R~K47F!z z__(C1eP&@TLj9rtSLds@37Epe_~9GTyzEUyhYC_NVqzZE{i=0IJ(h`B_K4A>pP4*S zlyuCQ(K&MLE$a+hhRwIq991=i;6$Vxr2FZ+InkcbqyRr+UAGEj>B)$-G|syqL{GA# zt)$Oooz;NQEV-aTy?gRrxzxUoyEJtw`j!1|TI_vgv#3f%E+U@q!G>PAmX^S{^DxpM zb-{K&=T!e-w2+6G%dc?Dkr4U2>b{HVSdx`g1oVgLAJKRNp=sSNCEODy;C}88No%$S zj*6?x3hp%EWxUXd@Cv~#I!bvMiAHgGri<#_?Hn|E={aNbYw@yeDj6swkApl(Cqs&> z1DoF(xbetLx*`47=lV+uh1*nxlu7;*GR&PfCiWiGg`=~1)P>eDxGn#mMaVEGl{xP$ z#)yf6>}9ET$M6h~=2p9xjBJat(gW|~_+z&QoEDTv;E#OgR)4c}hd7UA$k6;MwEgI_ z2HTk0dv%k<+kGEBQ>0A~I{FRs17M;p$)5WZHy*`u^^K^pOS^1GRPbF#F_TvyRVf1S z-55H#3325aFf*TMv8iImc|T!wi*2W{R$oXYl*L_-337{k_nd%auBo0dEsF>-P1j8B z-#A}}4mG9Pxn_FCe`(2U{q!SQ9$gRsRZJ2m73M?}$(!*x)pbwe=f3#q(Yuxd?h-Jl z@|#5(c8yfZEBh`4-fq&`B~cqI@Ni)_mU6WWd{|i3Co{%f@2=?(FgFLqdIAjozW3oW zVtvi~wb8&<-w!cYCU(9q4eQ=wu4MGQFP(NMoD*X)>149Z=eT)~=3wE>P{5a~8c0W~ zm~q-#g6#A6=eW_TyPmzFSKK*=N+Xh?o-Jm;d}C=F_g78|8r3|w!9`~3ZVc_OAMBQa zfadO-c9#h>XaAljEX4RTE@b%ObEk}xP?P8fxF%oG5B6G?D6eHv5vCt<&1_Ys5MtS8 zPLU7j11VdkY%w*}q!{eAG;It4=QQ^AHPauLk6` zGs~~s&J-)ds5|TPp@rJx=N4;GeCy3s`VJAuK4DWX30|ICYzGdXlNgFLU^ZpQCkQ9_ z9r^7IUV=*_q>L%+P=XHoo%{9t*~og0>d*P-G!7Th1KZ@~3?f_!>X=S219}etjPJ9+ zinX1Tfri1B!k^{B4=mWbedsY{fx9gG5wPra{E~MhK{>PoB5V^*thCb8#YXiF-Rsq1 z_Tly{W-Fc@8_0q*pf6AF))4#6AII?j3Z%PfYZ&3S35AWr0s(`My#4OaZRqk^M>q9C z&!V;K?^yj@ZRkFob%lJH(;q^OP$C}v>%b{8wLv8%<@8UyT|Zvvo>P+kp3l%1(2)UW z0{!r_E~VHn8c%bIDM@*DX?m|v<8K(EkHK)EU&DFAI=Ei17r|QoEe@m2sZn}~>LyC5 zS`%F~|IHI3Y_$B3t{zM}0)c2@sX(9WjnDDGz>t*(<@<1s%!Pzcn~IbRY%^k`Irpev zR2@A}(S+Pw6j*vFmjhJACfk90=0_XzR|SegG(F}V&L6B8_GdzRuP)tXC8RGVulHV< zsb@X+`ar8>S*!2L62_$_d=n=LB>w#Iy*X{f#-fRik;FZhIaJSU?VOrIV$Z0xPq%}c zkHm4W*8*%96`te5Mk}U^zQ^Zjdf-qiFqFh;2lT!?57W+;e-R?Fal<7i92y!98fK53 zLiQgt{M$5QdJ}>eOPy5t4>hW#)Pvc1dd@Ifm-ne<1U=!Q|$?59dboix;#!1`rH3G5FFSk z-eoP!t}dpM3Afi_sxoKi3{ghF6FA+fe*~V+`qHR! z*;1V$4d~k34?iy5{$Xdkw&&tk#$d8X|A}ys&#rHVVccL%CiT(wCKQ&|429L~`v=hK zg>GHy;{>=la$9Y=^(z{LE|;=)^(Lb7y8-8G&;L7?L(hYlDjCz>f+7AwbrM>v0U_GA zACM&^r_&S*9q9jc%M(Ajk@3#!F-Q5bXmk-;#h{}(C>q#<^ zXwT*?G8zt`^}uYJH3<)RxljTTHzE2TFp8{ZvJ~o$%#%G4k(RpX5}afbp2>0Lk1MBHI%yQr-co=2nPfqCR1x}2vykRF}ig$n2 ztw*>czKof*HP-_y5`<-~#nuNOs;wmjE`6^1Qx2_uK47y|OtRhn@zh}U4CD;X06smw ztJD`KDz9Ha4Hag^@@|T>v$tn}9i`L7m+w5a7Yr*!AP||@<2&mQo86F6PZswiR8gUr z`2JlAMf{ZNmm&>lttW1RSxShm%6xkUZg5z$u``@`BGM2;?kE z2w%u~x2y$jVE+ZMYD{vUwEgXl5(Sp|zTzJ*^c-a!mMP=FTphkVa~t>}PHFn&t+5xJ zaKNxdW~wBW1+iBV!0f~?u~vb@ABMrZTFB{ZEiFvCL-Ed&?D~#kkDh0ZFMoO}>n5#V z0jWoEUt6JbtmIwWRdA*he=l-n*hwCD@nCJQ#`IM>Q&wOD)Qv%lRW74boQv#zgIhTg z#AN`@%Ho5=CPOCgxpH8QaE@(uVzuoHjtsBtV?e|(FmRe-O1i z=rXOzNVI=}vkD+sRB6>wF8r4q;JCybi*XCtVdAP)-`5uLgd|%|;I-ST1e>~?iC3DZ z=JNJ@)kX&Nhu@u@h}=W!N%GKhR?2m_OZM4m@gL@DI}ZxIa|~jm^hq+`Vw;E zYwq(cZ-`w0ny4`mH(C&BE|5_o1y%qCKUE6);E6KJyqouDIo2N8U{@~9r##9pDQf^) z_4!XE;5p%K&hVSrK(5$cKFg-d#^gW};xI*^AL_38a5hWmAM9Uh1yyuGEBlq|QI$3U znjcbA0Ub~w(84P72N9;Cf&wjIXGJJ@o60^3E({$af{(cc7 zWGwJFf>*asLDk4yS$fyD#@|8nM^P8r?FT@PtgVQ!9u?76RTGeOz?!Y?gKCpT2U1hg#t1!#{ zJVC!ry28&93* zPHHED!*;x4lXAjYx?e|uqbH}*hjwD-2l+Q9s8Hf;If5DV*pnxl#kyH)7mi9nASSI9 zs1bx2oX0rGFlQIpQc`qa7%iv-@v2=;*MAFcJ?d26yKy%r`FdOKjS13Xw!>wWG_*RZ?o!aYSk#DD$VVDu~HQR!*zp8xvE3ZlCfTziwV{s4S`*$?1%&+ksv3+yRA=Oxs|2XhWzY%Z`_0k80Unsc;7;ZqywSeI-T`p=^WpM z8N^ukIcSAZ7N)Bt-HRV^Td!^wnz9gSzh0a4y?jA-FO!56O1UEx?|qe{dKs!|HBwxd ze?!@biAf$A&aiLmAC9s}PlMamm2-2Ji+XRjig2ab>rEOzN_$=)Pix3~Hz&LAOy69Q z&Mm~uz1)(nux?;^eh5gEJM!ADWm=dVJiZBbDLxF|BZ>>#OM!(MeLx+sJyn~0mp&}R z-^uLf#Zm=i@1K7(CMs&vV5B+^&WC?Lss@QnZr#b_WoBvrU6u{{z92gV{~VK|2Hu*Q zEIr$P1JdIBtOhKc`9M!$hzGl1_BWh+nkTIVV&ah)Qi)7{sg5`b8Um?0PU7? zglqn4ZMgB`gf8yp08A?$G32aIrzs#+aW3YI&oWcwtN*a_0Yo>~Bd{D%6Vuzwty?YGE*s$ew+_2mV#!SU|#RMp@zQ zY8JPwlzI>U;Uc;IBoUu(iRvk|TG{zr)hpdfOv(I#E7g7EVNZtwOKR$I$;IDT4IP1p zo&O>Vsp9~tRy5)o`Nf|JSQ)~gn25toGFbj-B8Bj<0s2w@50CzcLj?8Dtj3f~rzq0)cqJXk z0K?m(NYMYThS;kO(cVevM@VRaH!tPE+gbv>v$DOt9mKtzkmJ+HPWyE(+DD6XMBe*! zHb!vVaQk!~5&o}VxAFXMpK1^bpL$@6T9rbq8CeC`!kqNyH-vudxUUQ3HL4~=+q10T R(;2vQ&g-AcK6Cxf{{X`jgLeP` -- Gitee From edca754f52c9088d561527404f4e0494f4045a6e Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Wed, 9 Feb 2022 17:59:41 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=BC=98=E5=8C=96Light=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 3dd95f1280f..343c80ca14d 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -172,7 +172,7 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 /* 灯设备HCS配置 */ device_light :: device { device0 :: deviceNode { - policy = 2; // 驱动服务发布的策略 + policy = 2; // 驱动服务发布的策略(0:不提供服务,1:对内核态发布服务,2:对内核态和用户态都发布服务) priority = 100; // Light驱动启动优先级(0-200),值越大优先级越低,建议配置为100,优先级相同则不保证device的加载顺序 preload = 0; // 驱动按需加载字段,0表示加载,2表示不加载 permission = 0664; // 驱动创建设备节点权限 @@ -234,8 +234,8 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 busGNum = 30; // 绿色对应的GPIO管脚 busBNum = 29; // 蓝色对应的GPIO管脚 lightBrightness = 0X80000000;// RGB: R:16-31bit、G:8-15bit、B:0-7bit - onTime = 50; // 一个闪烁周期内亮灯时长 - offTime = 50; // 一个闪烁周期内熄灯时长 + onTime = 50; // 一个闪烁周期内亮灯时长(ms) + offTime = 50; // 一个闪烁周期内熄灯时长(ms) } } } -- Gitee From 8df3d7e079229671ec9b84e1d68124e2aaff8822 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Sat, 12 Feb 2022 19:13:18 +0800 Subject: [PATCH 08/10] =?UTF-8?q?=E4=BC=98=E5=8C=96Light=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 343c80ca14d..721476a73e3 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -44,7 +44,7 @@ Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及 Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模式和闪烁时间的能力。Light硬件服务调用GetLightInfo获取Light设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。Light驱动模型对HDI开放的API接口能力,参考[表1](#Light驱动模型对外API接口能力介绍)。 -**表1 ** Light驱动模型对外API接口能力介绍 +**表1** Light驱动模型对外API接口能力介绍 | 接口名 | 功能描述 | | ------------------------------------------------------------ | ------------------------------------------------------------ | -- Gitee From 411a463b0df2cb9e7d9566fee3db466b8d3a92e7 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 14 Feb 2022 16:05:03 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E4=BC=98=E5=8C=96Light=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyanxu --- .../driver/driver-peripherals-light-des.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index 721476a73e3..c8455936c63 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -5,11 +5,14 @@ - [运作机制](###运作机制) - [开发指导](##开发指导) + + - [场景介绍](###场景介绍) + - [接口说明](###接口说明) - [开发步骤](###开发步骤) - [开发实例](###开发实例) - [调测验证](###调测验证) - + ## 概述 @@ -40,6 +43,10 @@ Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及 ## 开发指导 +### 场景介绍 + +灯设备的控制,在实际生活中比比皆是,例如短信通知时闪灯、手机电量不足是预警、充电时根据充电进度变换灯的颜色等等。这些动作的实现,都需要使用 Light驱动模型提供的接口,动态配置点灯模式、配置灯闪烁效果、点灯、熄灯等。 + ### 接口说明 Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模式和闪烁时间的能力。Light硬件服务调用GetLightInfo获取Light设备的基本信息;调用TurnOnLight接口启动配置的闪烁效果。Light驱动模型对HDI开放的API接口能力,参考[表1](#Light驱动模型对外API接口能力介绍)。 @@ -59,6 +66,10 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 ### 开发实例 +基于HDF驱动模型,加载启动Light驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。本例中Light驱动通讯接口方式选择GPIO。 + +灯设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 + 1. Light驱动的初始化和去初始化 - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 -- Gitee From 26efc5f9001ceaf6691ee7a634fcb717b3b8a704 Mon Sep 17 00:00:00 2001 From: zhouyanxu Date: Mon, 14 Feb 2022 16:17:57 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BC=98=E5=8C=96Light=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhouyanxu --- zh-cn/device-dev/driver/driver-peripherals-light-des.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-light-des.md b/zh-cn/device-dev/driver/driver-peripherals-light-des.md index c8455936c63..64a5dc58301 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-light-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-light-des.md @@ -45,7 +45,7 @@ Light驱动模型以标准系统Hi3516DV300为例,介绍整个驱动加载及 ### 场景介绍 -灯设备的控制,在实际生活中比比皆是,例如短信通知时闪灯、手机电量不足是预警、充电时根据充电进度变换灯的颜色等等。这些动作的实现,都需要使用 Light驱动模型提供的接口,动态配置点灯模式、配置灯闪烁效果、点灯、熄灯等。 +灯设备的控制,在实际生活中比比皆是,例如短信通知时闪灯、手机电量不足是预警、充电时根据充电进度变换灯的颜色等等。这些动作的实现,都需要使用Light驱动模型提供的接口,动态配置点灯模式、配置灯闪烁效果、点灯、熄灯等。 ### 接口说明 @@ -68,8 +68,6 @@ Light驱动模型支持获取系统中所有灯的信息,动态配置闪烁模 基于HDF驱动模型,加载启动Light驱动,代码形式如下,具体原理可参考[HDF驱动开发指南](driver-hdf-development.md)。本例中Light驱动通讯接口方式选择GPIO。 -灯设备完整的使用示例如下所示,首先打开总线号为1的SDIO控制器,然后独占HOST、使能设备、注册中断,接着进行SDIO通信(读写等),通信完成之后,释放中断、去使能设备、释放HOST,最后关闭SDIO控制器。 - 1. Light驱动的初始化和去初始化 - 调用HDF_INIT将驱动入口注册到HDF框架中。在加载驱动时HDF框架会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 -- Gitee