网站建设客户说没用,wordpress服务器版,英文网站优化,餐饮系统的网站应该怎么做I3C#xff08;Improved Inter Integrated Circuit#xff09;总线是由MIPI Alliance开发的一种简单、低成本的双向二线制同步串行总线。
I3C是两线双向串行总线#xff0c;针对多个传感器从设备进行了优化#xff0c;并且一次只能由一个I3C主设备控制。相比于I2C#xf…I3CImproved Inter Integrated Circuit总线是由MIPI Alliance开发的一种简单、低成本的双向二线制同步串行总线。
I3C是两线双向串行总线针对多个传感器从设备进行了优化并且一次只能由一个I3C主设备控制。相比于I2CI3C总线拥有更高的速度、更低的功耗支持带内中断、从设备热接入以及切换当前主设备同时向后兼容I2C从设备。
I3C增加了带内中断In-Bind Interrupt功能支持I3C设备进行热接入操作弥补了I2C总线需要额外增加中断线来完成中断的不足。I3C总线上允许同时存在I2C设备、I3C从设备和I3C次级主设备。
基本概念 IBIIn-Band Interrupt带内中断。 在SCL线没有启动信号时I3C从设备可以通过拉低SDA线使主设备发出SCL启动信号从而发出带内中断请求。若有多个从设备同时发出中断请求I3C主设备则通过从设备地址进行仲裁低地址优先相应。 DAADynamic Address Assignment动态地址分配。 I3C支持对从设备地址进行动态分配从而避免地址冲突。在分配动态地址之前连接到I3C总线上的每个I3C/I2C设备都应以两种方式之一来唯一标识 设备可能有一个符合I2C规范的静态地址主机可以使用此静态地址。 在任何情况下I3C设备均应具有48位的临时ID。除非设备具有静态地址且主机使用静态地址否则主机应使用此48位临时ID。 CCCCommon Command Code通用命令代码。 所有I3C设备均支持CCC可以直接将其传输到特定的I3C从设备也可以同时传输到所有I3C从设备。 BCRBus Characteristic Register总线特性寄存器。 每个连接到I3C总线的I3C设备都应具有相关的只读总线特性寄存器BCR该寄存器描述了I3C兼容设备在动态地址分配和通用命令代码中的作用和功能。 DCRDevice Characteristic Register设备特性寄存器。 连接到I3C总线的每个I3C设备都应具有相关的只读设备特性寄存器DCR该寄存器描述了用于动态地址分配和通用命令代码的I3C兼容设备类型例如加速度计、陀螺仪等。
运作机制
在HDF框架中同类型控制器对象较多时可能同时存在十几个同类型控制器如果采用独立服务模式则需要配置更多的设备节点且相关服务会占据更多的内存资源。相反采用统一服务模式可以使用一个设备服务作为管理器统一处理所有同类型对象的外部访问这会在配置文件中有所体现实现便捷管理和节约资源的目的。I3C模块采用统一服务模式如图1。
I3C模块各分层的作用为 接口层提供打开设备写入数据关闭设备的能力。 核心层主要负责服务绑定、初始化以及释放管理器并提供添加、删除以及获取控制器的能力。由于框架需要统一管理I3C总线上挂载的所有设备因此还提供了添加、删除以及获取设备的能力以及中断回调函数。 适配层由驱动适配者实现与硬件相关的具体功能如控制器的初始化等。
在统一模式下所有的控制器都被核心层统一管理并由核心层统一发布一个服务供接口层因此这种模式下驱动无需再为每个控制器发布服务。
图 1 I3C统一服务模式结构图 约束与限制
I3C模块当前仅支持轻量和小型系统内核LiteOS-A 。
开发指导
场景介绍
I3C可连接单个或多个I3C、I2C从器件它主要用于 与传感器通信如陀螺仪、气压计或支持I3C协议的图像传感器等。 通过软件或硬件协议转换与其他通信接口如UART串口等的设备进行通信。
当驱动开发者需要将I3C设备适配到OpenHarmony时需要进行I3C驱动适配下文将介绍如何进行I3C驱动适配。
接口说明
为了保证上层在调用I3C接口时能够正确的操作硬件核心层在//drivers/hdf_core/framework/support/platform/include/i3c/i3c_core.h中定义了以下钩子函数。驱动适配者需要在适配层实现这些函数的具体功能并与这些钩子函数挂接从而完成接口层与核心层的交互。
I3cMethod定义
struct I3cMethod {int32_t (*sendCccCmd)(struct I3cCntlr *cntlr, struct I3cCccCmd *ccc);int32_t (*transfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);int32_t (*i2cTransfer)(struct I3cCntlr *cntlr, struct I3cMsg *msgs, int16_t count);int32_t (*setConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);int32_t (*getConfig)(struct I3cCntlr *cntlr, struct I3cConfig *config);int32_t (*requestIbi)(struct I3cDevice *dev);void (*freeIbi)(struct I3cDevice *dev);
};
表 1 I3cMethod结构体成员的钩子函数功能说明
函数成员入参出参返回值功能sendCccCmdcntlr结构体指针核心层I3C控制器ccc传入的通用命令代码结构体指针ccc传出的通用命令代码结构体指针HDF_STATUS相关状态发送CCCCommon command Code即通用命令代码Transfercntlr结构体指针核心层I3C控制器msgs结构体指针用户消息countint16_t消息数量msgs结构体指针用户消息HDF_STATUS相关状态使用I3C模式传递用户消息i2cTransfercntlr结构体指针核心层I3C控制器msgs结构体指针用户消息countint16_t消息数量msgs结构体指针用户消息HDF_STATUS相关状态使用I2C模式传递用户消息setConfigcntlr结构体指针核心层I3C控制器config控制器配置参数无HDF_STATUS相关状态设置I3C控制器配置参数getConfigcntlr结构体指针核心层I3C控制器config控制器配置参数HDF_STATUS相关状态获取I3C控制器配置参数requestIbidevice结构体指针核心层I3C设备无HDF_STATUS相关状态为I3C设备请求IBIIn-Bind Interrupt即带内中断freeIbidevice结构体指针核心层I3C设备无HDF_STATUS相关状态释放IBI
开发步骤
I3C模块适配包含以下五个步骤 实例化驱动入口 实例化HdfDriverEntry结构体成员。 调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。 配置属性文件 在device_info.hcs文件中添加deviceNode描述。 【可选】添加i3c_config.hcs器件属性文件。 实例化I3C控制器对象 初始化I3cCntlr成员。 实例化I3cCntlr成员I3cMethod方法集合其定义和成员函数说明见下文。 注册中断处理子程序 为控制器注册中断处理程序实现设备热接入和IBI带内中断功能。 驱动调试 【可选】针对新增驱动程序建议验证驱动基本功能例如挂载后的测试用例是否成功数据能否传输等。
开发实例
下方将以Hi3516DV300的虚拟驱动//drivers/hdf_core/framework/test/unittest/platform/virtual/i3c_virtual.c为示例展示需要驱动适配者提供哪些内容来完整实现设备功能。 实例化驱动入口 驱动入口必须为HdfDriverEntry在//drivers/hdf_core/framework/include/core/hdf_device_desc.h中定义类型的全局变量且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总形成一个类似数组的段地址空间方便上层调用。 一般在加载驱动时HDF会先调用Bind函数再调用Init函数加载该驱动。当Init调用异常时HDF框架会调用Release释放驱动资源并退出。 I3C驱动入口参考 说明 I3C控制器会出现很多个控制器挂接的情况因而在HDF框架中首先会为此类型的控制器创建一个管理器对象并同时对外发布一个管理器服务来统一处理外部访问。这样用户需要打开某个控制器时会先获取到管理器服务然后管理器服务根据用户指定参数查找到指定控制器。 I3C管理器服务的驱动由核心层实现驱动适配者不需要关注这部分内容的实现但在实现Init函数的时候需要调用核心层的I3cCntlrAdd函数它会实现相应功能。 static struct HdfDriverEntry g_virtualI3cDriverEntry {.moduleVersion 1,.Init VirtualI3cInit,.Release VirtualI3cRelease,.moduleName virtual_i3c_driver, // 【必要且与hcs文件中的名字匹配】
};
HDF_INIT(g_virtualI3cDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中// 核心层i3c_core.c管理器服务的驱动入口
struct HdfDriverEntry g_i3cManagerEntry {.moduleVersion 1,.Init I3cManagerInit,.Release I3cManagerRelease,.moduleName HDF_PLATFORM_I3C_MANAGER, // 这与device_info.hcs文件中device0对应
};
HDF_INIT(g_i3cManagerEntry); 配置属性文件 完成驱动入口注册之后下一步请在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode信息并在i3c_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关器件属性值对于驱动适配者的驱动实现以及核心层I3cCntlr相关成员的默认值或限制范围有密切关系。 统一服务模式的特点是device_info.hcs文件中第一个设备节点必须为I3C管理器其各项参数必须如表2设置 表 2 device_info.hcs节点参数说明 成员名值policy驱动服务发布的策略I3C管理器具体配置为0表示驱动不需要发布服务priority驱动启动优先级0-200值越大优先级越低。I3C管理器具体配置为52permission驱动创建设备节点权限I3C管理器具体配置为0664moduleName驱动名称I3C管理器固定为HDF_PLATFORM_I3C_MANAGERserviceName驱动对外发布服务的名称I3C管理器服务名设置为HDF_PLATFORM_I3C_MANAGERdeviceMatchAttr驱动私有数据匹配的关键字I3C管理器没有使用可忽略从第二个节点开始配置具体I3C控制器信息此节点并不表示某一路I3C控制器而是代表一个资源性质设备用于描述一类I3C控制器的信息。本例只有一个I3C控制器如有多个控制器则需要在device_info.hcs文件增加deviceNode信息以及在i3c_config文件中增加对应的器件属性。 device_info.hcs配置参考 root {device_i3c :: device {device0 :: deviceNode {policy 0;priority 52;permission 0644;serviceName HDF_PLATFORM_I3C_MANAGER;moduleName HDF_PLATFORM_I3C_MANAGER;}}i3c_virtual :: deviceNode {policy 0; // 等于0不需要发布服务。priority 56; // 驱动启动优先级。permission 0644; // 驱动创建设备节点权限。moduleName virtual_i3c_driver; // 【必要】用于指定驱动名称需要与期望的驱动Entry中的moduleName一致。serviceName VIRTUAL_I3C_DRIVER; // 【必要】驱动对外发布服务的名称必须唯一。deviceMatchAttr virtual_i3c; // 【必要】用于配置控制器私有数据要与i3c_config.hcs中对应控制器保持一致。} // 具体的控制器信息在i3c_config.hcs中。
} i3c_config.hcs 配置参考 root {platform {i3c_config {match_attr virtual_i3c; // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致template i3c_controller { // 模板公共参数继承该模板的节点如果使用模板中的默认值则节点字段可以缺省。busId 0; // 【必要】i3c总线号busMode 0x0; // 总线模式0x0纯净0x1混合高速0x2混合受限0x3混合低速。regBasePhy 0x120b0000; // 【必要】物理基地址regSize 0xd1; // 【必要】寄存器位宽IrqNum 20; // 【必要】中断号i3cMaxRate 12900000; // 【可选】i3c模式最大时钟速率i3cRate 12500000; // 【可选】i3c模式时钟速率i2cFmRate 1000000; // 【可选】i2c FM模式时钟速率i2cFmPlusRate 400000; // 【可选】i2c FM模式时钟速率}controller_0 :: i3c_controller {busId 18;IrqNum 20;}}}
} 需要注意的是新增i3c_config.hcs配置文件后必须在对应的hdf.hcs文件中包含i3c_config.hcs所在路径信息否则配置文件无法生效。 实例化I3C控制器对象 配置属性文件完成后要以核心层I3cCntlr对象的初始化为核心包括驱动适配者自定义结构体传递参数和数据实例化I3cCntlr成员I3cMethod让用户可以通过接口来调用驱动底层函数。 此步骤需要通过实现HdfDriverEntry成员函数BindInitRelease来完成。 I3cCntlr成员钩子函数结构体I3cMethod的实例化I3cLockMethod钩子函数结构体本例未实现若要实例化可参考I2C驱动开发。 自定义结构体参考 说明 从驱动的角度看自定义结构体是参数和数据的载体而且i3c_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员其中一些重要数值也会传递给核心层I3cCntlr对象例如设备号、总线号等。 struct VirtualI3cCntlr {struct I3cCntlr cntlr; // 【必要】是核心层控制对象具体描述见下面。volatile unsigned char *regBase; // 【必要】寄存器基地址uint32_t regBasePhy; // 【必要】寄存器物理基地址uint32_t regSize; // 【必要】寄存器位宽uint16_t busId; // 【必要】设备号uint16_t busMode;uint16_t IrqNum;uint32_t i3cMaxRate;uint32_t i3cRate;uint32_t i2cFmRate;uint32_t i2cFmPlusRate;
};// I3cCntlr是核心层控制器结构体其中的成员在Init函数中被赋值。
struct I3cCntlr {OsalSpinlock lock;void *owner;int16_t busId;struct I3cConfig config;uint16_t addrSlot[(I3C_ADDR_MAX 1) / ADDRS_PER_UINT16];struct I3cIbiInfo *ibiSlot[I3C_IBI_MAX];const struct I3cMethod *ops;const struct I3cLockMethod *lockOps;void *priv;
}; Init函数开发参考 入参 HdfDeviceObject是整个驱动对外提供的接口参数具备HCS配置文件的信息。 返回值 HDF_STATUS相关状态表3为部分展示如需使用其他状态可参考//drivers/hdf_core/interfaces/inner_api/utils/hdf_base.h中HDF_STATUS定义。 表 3 HDF_STATUS相关状态说明 状态(值)问题描述HDF_ERR_INVALID_OBJECT控制器对象非法HDF_ERR_INVALID_PARAM参数非法HDF_ERR_MALLOC_FAIL内存分配失败HDF_ERR_IOI/O错误HDF_SUCCESS传输成功HDF_FAILURE传输失败函数说明 初始化自定义结构体对象初始化I3cCntlr成员调用核心层I3cCntlrAdd函数。 static int32_t VirtualI3cParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node)
{int32_t ret;struct VirtualI3cCntlr *virtual NULL; // 【必要】自定义结构体对象(void)device;virtual (struct VirtualI3cCntlr *)OsalMemCalloc(sizeof(*virtual)); // 【必要】内存分配if (virtual NULL) {HDF_LOGE(%s: Malloc virtual fail!, __func__);return HDF_ERR_MALLOC_FAIL;}ret VirtualI3cReadDrs(virtual, node); // 【必要】将i3c_config文件的默认值填充到结构体中函数定义见下方if (ret ! HDF_SUCCESS) {HDF_LOGE(%s: Read drs fail! ret:%d, __func__, ret);goto __ERR__;}......virtual-regBase OsalIoRemap(virtual-regBasePhy, virtual-regSize); // 【必要】地址映射ret OsalRegisterIrq(hi35xx-softIrqNum, OSAL_IRQF_TRIGGER_NONE, I3cIbiHandle, I3C, virtual); //【必要】注册中断程序if (ret ! HDF_SUCCESS) {HDF_LOGE(%s: register irq failed!, __func__);return ret;}......VirtualI3cCntlrInit(virtual); // 【必要】I3C设备的初始化virtual-cntlr.priv (void *)node; // 【必要】存储设备属性virtual-cntlr.busId virtual-busId; // 【必要】初始化I3cCntlr成员virtual-cntlr.ops g_method; // 【必要】I3cMethod的实例化对象的挂载(void)OsalSpinInit(virtual-spin);ret I3cCntlrAdd(virtual-cntlr); // 【必要且重要】调用此函数将控制器添加至核心返回成功信号后驱动才完全接入平台核心层。if (ret ! HDF_SUCCESS) {HDF_LOGE(%s: add i3c controller failed! ret %d, __func__, ret);(void)OsalSpinDestroy(virtual-spin);goto __ERR__;}return HDF_SUCCESS;
__ERR__: // 若控制器添加失败需要执行去初始化相关函数。if (virtual ! NULL) {OsalMemFree(virtual);virtual NULL;}return ret;
}static int32_t VirtualI3cInit(struct HdfDeviceObject *device)
{int32_t ret;const struct DeviceResourceNode *childNode NULL;if (device NULL || device-property NULL) {HDF_LOGE(%s: device or property is NULL, __func__);return HDF_ERR_INVALID_OBJECT;}DEV_RES_NODE_FOR_EACH_CHILD_NODE(device-property, childNode) {ret VirtualI3cParseAndInit(device, childNode);if (ret ! HDF_SUCCESS) {break;}}return ret;
}static int32_t VirtualI3cReadDrs(struct VirtualI3cCntlr *virtual, const struct DeviceResourceNode *node)
{struct DeviceResourceIface *drsOps NULL;// 获取drsOps方法drsOps DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if (drsOps NULL || drsOps-GetUint32 NULL || drsOps-GetUint16 NULL) {HDF_LOGE(%s: Invalid drs ops fail!, __func__);return HDF_FAILURE;}// 将配置参数依次读出并填充至结构体中if (drsOps-GetUint16(node, busId, virtual-busId, 0) ! HDF_SUCCESS) {HDF_LOGE(%s: Read busId fail!, __func__);return HDF_ERR_IO;}if (drsOps-GetUint16(node, busMode, virtual-busMode, 0) ! HDF_SUCCESS) {HDF_LOGE(%s: Read busMode fail!, __func__);return HDF_ERR_IO;}if (drsOps-GetUint16(node, IrqNum, virtual-IrqNum, 0) ! HDF_SUCCESS) {HDF_LOGE(%s: Read IrqNum fail!, __func__);return HDF_ERR_IO;}......return HDF_SUCCESS;
} Release函数开发参考 入参 HdfDeviceObject是整个驱动对外提供的接口参数具备HCS配置文件的信息。 返回值 无。 函数说明 释放内存和删除控制器该函数需要在驱动入口结构体中赋值给Release接口当HDF框架调用Init函数初始化驱动失败时可以调用Release释放驱动资源。 说明 所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。 static void VirtualI3cRemoveByNode(const struct DeviceResourceNode *node)
{int32_t ret;int16_t busId;struct I3cCntlr *cntlr NULL;struct VirtualI3cCntlr *virtual NULL;struct DeviceResourceIface *drsOps NULL;drsOps DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if (drsOps NULL || drsOps-GetUint32 NULL) {HDF_LOGE(%s: invalid drs ops fail!, __func__);return;}ret drsOps-GetUint16(node, busId, (uint16_t *)busId, 0);if (ret ! HDF_SUCCESS) {HDF_LOGE(%s: read busId fail!, __func__);return;}......// 可以调用I3cCntlrGet函数通过设备的cntlrNum获取I3cCntlr对象以及调用I3cCntlrRemove函数来释放I3cCntlr对象的内容。cntlr I3cCntlrGet(busId);if (cntlr ! NULL cntlr-priv node) {I3cCntlrPut(cntlr);I3cCntlrRemove(cntlr); // 【必要】主要是从管理器驱动那边移除I3cCntlr对象virtual (struct VirtualI3cCntlr *)cntlr; // 【必要】通过强制转换获取自定义的对象并进行release操作(void)OsalSpinDestroy(virtual-spin);OsalMemFree(virtual);}return;
}static void VirtualI3cRelease(struct HdfDeviceObject *device)
{const struct DeviceResourceNode *childNode NULL;HDF_LOGI(%s: enter, __func__);if (device NULL || device-property NULL) {HDF_LOGE(%s: device or property is NULL, __func__);return;}......// 遍历、解析i3c_config.hcs中的所有配置节点并分别进行release操作DEV_RES_NODE_FOR_EACH_CHILD_NODE(device-property, childNode) {VirtualI3cRemoveByNode(childNode); //函数定义如上}
} 注册中断处理子程序 在中断处理程序中通过判断中断产生的地址实现热接入、IBI等操作。 static int32_t VirtualI3cReservedAddrWorker(struct VirtualI3cCntlr *virtual, uint16_t addr)
{(void)virtual;switch (addr) {case I3C_HOT_JOIN_ADDR:VirtualI3cHotJoin(virtual);break;case I3C_RESERVED_ADDR_7H3E:case I3C_RESERVED_ADDR_7H5E:case I3C_RESERVED_ADDR_7H6E:case I3C_RESERVED_ADDR_7H76:case I3C_RESERVED_ADDR_7H7A:case I3C_RESERVED_ADDR_7H7C:case I3C_RESERVED_ADDR_7H7F:// 广播地址单比特错误的所有情形HDF_LOGW(%s: broadcast Address single bit error!, __func__);break;default:HDF_LOGD(%s: Reserved address which is not supported!, __func__);break;}return HDF_SUCCESS;
}static int32_t I3cIbiHandle(uint32_t irq, void *data)
{struct VirtualI3cCntlr *virtual NULL;struct I3cDevice *device NULL;uint16_t ibiAddr;char *testStr Hello I3C!;(void)irq;if (data NULL) {HDF_LOGW(%s: data is NULL!, __func__);return HDF_ERR_INVALID_PARAM;}virtual (struct VirtualI3cCntlr *)data;// 【必要】获取产生中断的地址使用CHECK_RESERVED_ADDR宏判断该地址是否为I3C保留地址。ibiAddr VirtualI3cGetIbiAddr();if (CHECK_RESERVED_ADDR(ibiAddr) I3C_ADDR_RESERVED) {HDF_LOGD(%s: Calling VirtualI3cResAddrWorker..., __func__);return VirtualI3cReservedAddrWorker(virtual, ibiAddr);} else {HDF_LOGD(%s: Calling I3cCntlrIbiCallback..., __func__);device GetDeviceByAddr(virtual-cntlr, ibiAddr);if (device NULL) {HDF_LOGE(func:%s device is NULL!,__func__);return HDF_ERR_MALLOC_FAIL;}if (device-ibi-payload VIRTUAL_I3C_TEST_STR_LEN) {// 将字符串Hello I3C!放入IBI缓冲区内*device-ibi-data *testStr;}// 根据产生IBI的I3C设备调用IBI回调函数return I3cCntlrIbiCallback(device);}return HDF_SUCCESS;
} 驱动调试 【可选】针对新增驱动程序建议验证驱动基本功能例如挂载后的测试用例是否成功数据能否传输等。
最后
有很多小伙伴不知道学习哪些鸿蒙开发技术不知道需要重点掌握哪些鸿蒙应用开发知识点而且学习时频繁踩坑最终浪费大量时间。所以有一份实用的鸿蒙HarmonyOS NEXT资料用来跟着学习是非常有必要的。
这份鸿蒙HarmonyOS NEXT资料包含了鸿蒙开发必掌握的核心知识要点内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等鸿蒙HarmonyOS NEXT技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助有需要的小伙伴自行领取限时开源先到先得~无套路领取
获取这份完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料
鸿蒙HarmonyOS NEXT最新学习路线 HarmonOS基础技能 HarmonOS就业必备技能 HarmonOS多媒体技术 鸿蒙NaPi组件进阶 HarmonOS高级技能 初识HarmonOS内核 实战就业级设备开发 有了路线图怎么能没有学习资料呢小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙OpenHarmony 学习手册共计1236页与鸿蒙OpenHarmony 开发入门教学视频内容包含ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线请点击→纯血版全套鸿蒙HarmonyOS学习资料
《鸿蒙 (OpenHarmony)开发入门教学视频》 《鸿蒙生态应用开发V2.0白皮书》 《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建 《鸿蒙开发基础》
ArkTS语言安装DevEco Studio运用你的第一个ArkTS应用ArkUI声明式UI开发.…… 《鸿蒙开发进阶》
Stage模型入门网络管理数据管理电话服务分布式应用开发通知与窗口管理多媒体技术安全技能任务管理WebGL国际化开发应用测试DFX面向未来设计鸿蒙系统移植和裁剪定制…… 《鸿蒙进阶实战》
ArkTS实践UIAbility应用网络案例…… 获取以上完整鸿蒙HarmonyOS学习资料请点击→纯血版全套鸿蒙HarmonyOS学习资料
总结
总的来说华为鸿蒙不再兼容安卓对中年程序员来说是一个挑战也是一个机会。只有积极应对变化不断学习和提升自己他们才能在这个变革的时代中立于不败之地。