OpenHarmony平台驱动开发(十五),SDIO
OpenHarmony平台驱动开发(十五)
SDIO
概述
功能简介
SDIO(Secure Digital Input and Output)由SD卡发展而来,与SD卡统称为MMC(MultiMediaCard),二者使用相同的通信协议。SDIO接口兼容以前的SD卡,并且可以连接支持SDIO接口的其他设备。
运作机制
在HDF框架中,SDIO的接口适配模式采用独立服务模式(如图1)。在这种模式下,每一个设备对象会独立发布一个设备服务来处理外部访问,设备管理器收到API的访问请求之后,通过提取该请求的参数,达到调用实际设备对象的相应内部方法的目的。独立服务模式可以直接借助HDFDeviceManager的服务管理能力,但需要为每个设备单独配置设备节点,若设备过多可能增加内存占用。
独立服务模式下,核心层不会统一发布一个服务供上层使用,因此这种模式下驱动要为每个控制器发布一个服务,具体表现为:
-
驱动适配者需要实现HdfDriverEntry的Bind钩子函数以绑定服务。
-
device_info.hcs文件中deviceNode的policy字段为1或2,不能为0。
SDIO模块各分层作用:
-
接口层提供打开SDIO设备、设置块的大小、读取数据、写数据、设置公共信息、获取公共信息、刷新数据、独占HOST、释放Host、使能SDIO功能设备、去使能SDIO功能设备、申请中断、释放中断关闭SDIO设备的接口。
-
核心层主要提供SDIO控制器的添加、移除及管理的能力,通过钩子函数与适配层交互。
-
适配层主要是将钩子函数的功能实例化,实现具体的功能。
约束与限制
SDIO模块API当前仅支持内核态调用。
开发指导
场景介绍
SDIO的应用比较广泛,目前,有许多手机都支持SDIO功能,并且很多SDIO外设也被开发出来,使得手机外接外设更加容易。常见的SDIO外设有WLAN、GPS、CAMERA、蓝牙等。当驱动开发者需要将SDIO设备适配到OpenHarmony时,需要进行SDIO驱动适配,下文将介绍如何进行SDIO驱动适配。
接口说明
为了保证上层在调用SDIO接口时能够正确的操作硬件,核心层在//drivers/hdf_core/framework/model/storage/include/mmc/mmc_sdio.h中定义了以下钩子函数。驱动适配者需要在适配层实现这些函数的具体功能,并与这些钩子函数挂接,从而完成接口层与核心层的交互。
SdioDeviceOps定义:
struct SdioDeviceOps {int32_t (*incrAddrReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);int32_t (*incrAddrWriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);int32_t (*fixedAddrReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);int32_t (*fixedAddrWriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size, uint32_t scatterLen);int32_t (*func0ReadBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);int32_t (*func0WriteBytes)(struct SdioDevice *dev, uint8_t *data, uint32_t addr, uint32_t size);int32_t (*setBlockSize)(struct SdioDevice *dev, uint32_t blockSize);int32_t (*getCommonInfo)(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType);int32_t (*setCommonInfo)(struct SdioDevice *dev, SdioCommonInfo *info, uint32_t infoType);int32_t (*flushData)(struct SdioDevice *dev);int32_t (*enableFunc)(struct SdioDevice *dev);int32_t (*disableFunc)(struct SdioDevice *dev);int32_t (*claimIrq)(struct SdioDevice *dev, SdioIrqHandler *irqHandler);int32_t (*releaseIrq)(struct SdioDevice *dev);int32_t (*findFunc)(struct SdioDevice *dev, struct SdioFunctionConfig *configData);int32_t (*claimHost)(struct SdioDevice *dev);int32_t (*releaseHost)(struct SdioDevice *dev);
};
表 1 SdioDeviceOps结构体成员的钩子函数功能说明
函数 | 入参 | 出参 | 返回值 | 功能 |
---|---|---|---|---|
incrAddrReadBytes | dev:结构体指针,SDIO设备控制器 addr:uint32_t类型,地址值 size:uint32_t类型,大小 | data:uint8_t类型指针,传出值 | HDF_STATUS相关状态 | 从指定的SDIO地址增量读取给定长度的数据 |
incrAddrWriteBytes | dev:结构体指针,SDIO设备控制器 data:uint8_t类型指针,传入值 addr:uint32_t类型,地址值 size:uint32_t类型,大小 | 无 | HDF_STATUS相关状态 | 将给定长度的数据增量写入指定的SDIO地址 |
fixedAddrReadBytes | dev:结构体指针,SDIO设备控制器 addr:uint32_t类型,地址值 size:uint32_t类型,大小 scatterLen:uint32_t类型,数据长度 | data:uint8_t类型指针,传出值 | HDF_STATUS相关状态 | 从固定SDIO地址读取给定长度的数据。 |
fixedAddrWriteBytes | dev:结构体指针,SDIO设备控制器 data:uint8_t类型指针,传入值 addr:uint32_t类型,地址值 size:uint32_t类型,大小 scatterLen:uint32_t类型,数据长度 | 无 | HDF_STATUS相关状态 | 将给定长度的数据写入固定SDIO地址 |
func0ReadBytes | dev:结构体指针,SDIO设备控制器 addr:uint32_t类型,地址值 size:uint32_t类型,大小 | data:uint8_t类型指针,传出值 | HDF_STATUS相关状态 | 从SDIO函数0的地址空间读取给定长度的数据。 |
func0WriteBytes | dev:结构体指针,SDIO设备控制器 data:uint8_t类型指针,传入值 addr:uint32_t类型,地址值 size:uint32_t类型,大小 | 无 | HDF_STATUS相关状态 | 将给定长度的数据写入SDIO函数0的地址空间。 |
setBlockSize | dev:结构体指针,SDIO设备控制器 blockSize:uint32_t类型,Block大小 | 无 | HDF_STATUS相关状态 | 设置block大小 |
getCommonInfo | dev:联合体指针,SDIO设备控制器 infoType:uint32_t类型,info类型 | info:结构体指针,传出SdioFuncInfo信息 | HDF_STATUS相关状态 | 获取CommonInfo,说明见下 |
setCommonInfo | dev:结构体指针,SDIO设备控制器 info:联合体指针,SdioFuncInfo信息传入 infoType:uint32_t类型,info类型 | 无 | HDF_STATUS相关状态 | 设置CommonInfo,说明见下 |
flushData | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 当SDIO需要重新初始化或发生意外错误时调用的函数 |
enableFunc | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 使能SDIO设备 |
disableFunc | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 去使能SDIO设备 |
claimIrq | dev:结构体指针,SDIO设备控制器 irqHandler:void函数指针 | 无 | HDF_STATUS相关状态 | 注册SDIO中断 |
releaseIrq | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 释放SDIO中断 |
findFunc | dev:结构体指针,SDIO设备控制器 configData:结构体指针,SDIO函数关键信息 | 无 | HDF_STATUS相关状态 | 寻找匹配的funcNum |
claimHost | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 独占HOST |
releaseHost | dev:结构体指针,SDIO设备控制器 | 无 | HDF_STATUS相关状态 | 释放HOST |
说明:
CommonInfo包括maxBlockNum(单个request中最大block数)、maxBlockSize(单个block最大字节数)、maxRequestSize(单个Request最大字节数)、enTimeout(最大超时时间,毫秒)、funcNum(功能编号1~7)、irqCap(IRQ capabilities)、(void *)data。
开发步骤
SDIO模块适配包含以下四个步骤:
-
实例化驱动入口
-
实例化HdfDriverEntry结构体成员。
-
调用HDF_INIT将HdfDriverEntry实例化对象注册到HDF框架中。
-
-
配置属性文件
-
在device_info.hcs文件中添加deviceNode描述。
-
【可选】添加sdio_config.hcs器件属性文件。
-
-
实例化SDIO控制器对象
-
初始化SdioDevice成员。
-
实例化SdioDevice成员SdioDeviceOps。
说明:
实例化SdioDevice成员SdioDeviceOps,其定义和成员说明见接口说明。
-
-
驱动调试
【可选】针对新增驱动程序,建议验证驱动基本功能,例如SDIO控制状态,中断响应情况,读写数据是否成功等。
开发实例
下方将以//drivers/hdf_core/adapter/khdf/linux/model/storage/sdio_adapter.c为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。
-
实例化驱动入口
驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
SDIO 驱动入口参考:
struct HdfDriverEntry g_sdioDriverEntry = {.moduleVersion = 1,.Bind = Hi35xxLinuxSdioBind, // 见Bind开发参考.Init = Hi35xxLinuxSdioInit, // 见Init开发参考.Release = Hi35xxLinuxSdioRelease, // 见Release开发参考.moduleName = "HDF_PLATFORM_SDIO", // 【必要且与HCS文件中里面的moduleName匹配】 }; HDF_INIT(g_sdioDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中
-
配置属性文件
完成驱动入口注册之后,下一步请在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode信息,并在sdio_config.hcs中配置器件属性。deviceNode信息与驱动入口注册相关,器件属性值与核心层SdioDevice成员的默认值或限制范围有密切关系。本例只有一个SDIO控制器,如有多个器件信息,则需要在device_info.hcs文件增加deviceNode信息,以及在sdio_config文件中增加对应的器件属性。
独立服务模式的特点是device_info.hcs文件中设备节点代表着一个设备对象,如果存在多个设备对象,则按需添加,注意服务名与驱动私有数据匹配的关键字名称必须唯一。其中各项参数如表2所示:
表 2 device_info.hcs节点参数说明
成员名 值 policy 驱动服务发布的策略,SDIO设备控制器具体配置为1,表示驱动对内核态发布服务 priority 驱动启动优先级(0-200),值越大优先级越低。SDIO设备控制器具体配置为30 permission 驱动创建设备节点权限,SDIO设备控制器具体配置为0664 moduleName 驱动名称,SDIO设备控制器固定为hi3516_mmc_driver serviceName 驱动对外发布服务的名称,SDIO设备控制器服务名设置为HDF_PLATFORM_MMC_2 deviceMatchAttr 驱动私有数据匹配的关键字,SDIO设备控制器设置为hi3516_mmc_sdio -
device_info.hcs 配置参考:
root {device_info {match_attr = "hdf_manager";platform :: host {hostName = "platform_host";priority = 50;device_sdio :: device {device0 :: deviceNode {policy = 1;priority = 70;permission = 0644;moduleName = "HDF_PLATFORM_SDIO"; // 【必要】用于指定驱动名称,需要与驱动Entry中的moduleName一致。serviceName = "HDF_PLATFORM_MMC_2"; // 【必要】驱动对外发布服务的名称,必须唯一。deviceMatchAttr = "hisilicon_hi35xx_sdio_0"; // 【必要】用于配置控制器私有数据,要与sdio_config.hcs中对应控制器保持一致。}}}} }
-
sdio_config.hcs 配置参考:
root {platform {sdio_config {template sdio_controller {match_attr = "";hostId = 2; // 【必要】模式固定为2,在mmc_config.hcs有介绍。devType = 2; // 【必要】模式固定为2,在mmc_config.hcs有介绍。}controller_0x2dd1 :: sdio_controller {match_attr = "hisilicon_hi35xx_sdio_0"; // 【必要】需要和device_info.hcs中的deviceMatchAttr值一致。}} }
需要注意的是,新增sdio_config.hcs配置文件后,必须在hdf.hcs文件中包含sdio_config.hcs所在路径信息,否则配置文件无法生效。
-
-
实例化SDIO设备控制器对象
完成属性文件配置之后,下一步就是以核心层SdioDevice对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化SdioDevice成员SdioDeviceOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。
-
自定义结构体参考:
从驱动的角度看,自定义结构体是参数和数据的载体,而且sdio_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象。
typedef struct {uint32_t maxBlockNum; // 单个request最大的block个数uint32_t maxBlockSize; // 单个block最大的字节数1~2048uint32_t maxRequestSize; // 单个request最大的字节数1~2048uint32_t enTimeout; // 最大超时时间,单位毫秒,且不能超过一秒。uint32_t funcNum; // 函数编号1~7uint32_t irqCap; // 中断能力void *data; // 私有数据 } SdioFuncInfo;// SdioDevice是核心层控制器结构体,其中的成员在Bind函数中会被赋值。 struct SdioDevice {struct SdDevice sd;struct SdioDeviceOps *sdioOps;struct SdioRegister sdioReg;uint32_t functions;struct SdioFunction *sdioFunc[SDIO_MAX_FUNCTION_NUMBER];struct SdioFunction *curFunction;struct OsalThread thread; // 中断线程struct OsalSem sem;bool irqPending;bool threadRunning; };
-
SdioDevice成员钩子函数结构体SdioDeviceOps的实例化。
static struct SdioDeviceOps g_sdioDeviceOps = {.incrAddrReadBytes = Hi35xxLinuxSdioIncrAddrReadBytes,.incrAddrWriteBytes = Hi35xxLinuxSdioIncrAddrWriteBytes,.fixedAddrReadBytes = Hi35xxLinuxSdioFixedAddrReadBytes,.fixedAddrWriteBytes = Hi35xxLinuxSdioFixedAddrWriteBytes,.func0ReadBytes = Hi35xxLinuxSdioFunc0ReadBytes,.func0WriteBytes = Hi35xxLinuxSdioFunc0WriteBytes,.setBlockSize = Hi35xxLinuxSdioSetBlockSize,.getCommonInfo = Hi35xxLinuxSdioGetCommonInfo,.setCommonInfo = Hi35xxLinuxSdioSetCommonInfo,.flushData = Hi35xxLinuxSdioFlushData,.enableFunc = Hi35xxLinuxSdioEnableFunc,.disableFunc = Hi35xxLinuxSdioDisableFunc,.claimIrq = Hi35xxLinuxSdioClaimIrq,.releaseIrq = Hi35xxLinuxSdioReleaseIrq,.findFunc = Hi35xxLinuxSdioFindFunc,.claimHost = Hi35xxLinuxSdioClaimHost,.releaseHost = Hi35xxLinuxSdioReleaseHost, };
-
Bind函数开发参考。
入参:
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_MALLOC_FAIL 内存分配失败 HDF_ERR_IO I/O 错误 HDF_SUCCESS 初始化成功 HDF_FAILURE 初始化失败 函数说明:
初始化自定义结构体对象,初始化SdioCntlr成员,调用核心层SdioCntlrAdd函数,以及其他驱动适配者自定义初始化操作。
static int32_t Hi35xxLinuxSdioBind(struct HdfDeviceObject *obj) {struct MmcCntlr *cntlr = NULL;int32_t ret;......cntlr = (struct MmcCntlr *)OsalMemCalloc(sizeof(struct MmcCntlr));// 分配内存......cntlr->ops = &g_sdioCntlrOps; // 【必要】struct MmcCntlrOps g_sdioCntlrOps={// .rescanSdioDev = Hi35xxLinuxSdioRescan,};cntlr->hdfDevObj = obj; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提obj->service = &cntlr->service; // 【必要】使HdfDeviceObject与MmcCntlr可以相互转化的前提ret = Hi35xxLinuxSdioCntlrParse(cntlr, obj); // 【必要】初始化cntlr的index、devType,失败则goto _ERR。......ret = MmcCntlrAdd(cntlr); // 【必要】调用核心层mmc_core.c的函数,失败则goto _ERR。......ret = MmcCntlrAllocDev(cntlr, (enum MmcDevType)cntlr->devType); // 【必要】调用核心层mmc_core.c的函数,失败则goto _ERR。......MmcDeviceAddOps(cntlr->curDev, &g_sdioDeviceOps); // 【必要】调用核心层mmc_core.c的函数,钩子函数挂载。HDF_LOGD("Hi35xxLinuxSdioBind: Success!");return HDF_SUCCESS;_ERR:Hi35xxLinuxSdioDeleteCntlr(cntlr);HDF_LOGE("Hi35xxLinuxSdioBind: Fail!");return HDF_FAILURE; }
-
Init函数开发参考。
入参:
HdfDeviceObject是整个驱动对外提供的接口参数,具备HCS配置文件的信息。
返回值:
HDF_STATUS相关状态。
函数说明:
无操作,可根据驱动适配者需要添加。
static int32_t Hi35xxLinuxSdioInit(struct HdfDeviceObject *obj) {(void)obj; // 无操作,可根据驱动适配者的需要进行添加HDF_LOGD("Hi35xxLinuxSdioInit: Success!");return HDF_SUCCESS; }
-
Release函数开发参考。
入参:
HdfDeviceObject是整个驱动对外提供的接口参数,具备HCS配置文件的信息。
返回值:
无。
函数说明:
释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。
说明:
所有强制转换获取相应对象的操作前提是在Bind函数中具备对应赋值的操作。static void Hi35xxLinuxSdioRelease(struct HdfDeviceObject *obj) {if (obj == NULL) {return;}Hi35xxLinuxSdioDeleteCntlr((struct MmcCntlr *)obj->service); // 【必要】自定义的内存释放函数,这里有HdfDeviceObject到MmcCntlr的强制转换 }
-
-
驱动调试
【可选】针对新增驱动程序,建议验证驱动基本功能,例如SDIO控制状态,中断响应情况,读写数据是否成功等。
相关文章:
OpenHarmony平台驱动开发(十五),SDIO
OpenHarmony平台驱动开发(十五) SDIO 概述 功能简介 SDIO(Secure Digital Input and Output)由SD卡发展而来,与SD卡统称为MMC(MultiMediaCard),二者使用相同的通信协议。SDIO接口…...
ICMP协议详解及不同VLAN/VXLAN主机通信中的ICMP示例
一、ICMP协议概述 ICMP(Internet Control Message Protocol,互联网控制消息协议)是TCP/IP协议栈中的一项核心协议,用于在IP网络中传输控制消息和错误报告。ICMP定义在RFC 792中,主要用于诊断网络问题和传递控制信息。…...
SQL server数据库实现远程跨服务器定时同步传输数据
项目背景 数据需要定期迁移,数据存在于客户政务外网下,从旧数据库迁移到新数据库中,且要求能够定时增量同步。 注意: 源数据库所在服务器为windows服务器,目标数据库所在服务器为linux服务器。 源数据库所在windows服…...
贝叶斯优化Transformer融合支持向量机多变量时间序列预测,Matlab实现
贝叶斯优化Transformer融合支持向量机多变量时间序列预测,Matlab实现 目录 贝叶斯优化Transformer融合支持向量机多变量时间序列预测,Matlab实现效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.BO-TransformerSVM多变量时间序列预测,…...
服务器租用与托管注意事项有哪些
在当今数字化的时代,服务器对于企业和个人的重要性不言而喻。无论是搭建网站、运行应用程序,还是存储数据,服务器都是关键的基础设施。而服务器租用与托管作为常见的选择方式,其中的注意事项你可不能马虎。 企业在进行租用或者是…...
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】金融风控分析案例-10.3 风险指标可视化监控
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL金融风控分析之风险指标可视化监控实战一、引言二、案例背景三、数据准备(一)数据来源与字段说明(二)数据清洗 四、…...
【AI提示词】贝叶斯分析专家
提示说明 一名专业的贝叶斯推断专家,具备统计建模、数据分析和不确定性决策方面的专长。 提示词 # Role: 贝叶斯分析专家## Profile - language: 中文 - description: 一名专业的贝叶斯推断专家,具备统计建模、数据分析和不确定性决策方面的专长 - ba…...
星云智控自定义物联网实时监控模板-为何成为痛点?物联网设备的多样化-优雅草卓伊凡
星云智控自定义物联网实时监控模板-为何成为痛点?物联网设备的多样化-优雅草卓伊凡 引言:物联网监控的模板革命 在万物互联的时代,设备监控已成为保障物联网系统稳定运行的核心环节。传统的标准化监控方案正面临着设备类型爆炸式增长带来的…...
#跟着若城学鸿蒙#HarmonyOS NEXT学习之Blank组件详解
一、组件介绍 Blank(空白)组件是HarmonyOS NEXT中一个简单但非常实用的UI组件,它主要用于在布局中创建空白区域,帮助开发者更灵活地控制界面元素之间的间距和布局结构。虽然Blank组件本身不显示任何内容,但它在界面设…...
《Docker 入门与进阶:架构剖析、隔离原理及安装实操》
1 docker 简介 1.1 Docker 的优点 Docker 是一款开放平台,用于应用程序的开发、交付与运行,能将应用和基础架构分离,实现软件快速交付 ,还能以统一方式管理应用和基础架构,缩短代码从编写到上线的时间。其核心优势如…...
OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——mqtt库
准备工作 请依照这篇文章搭建环境 OpenHarmony 开源鸿蒙南向开发——linux下使用make交叉编译第三方库——环境配置_openharmony交叉编译-CSDN博客 下载 wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.5/gnutls-3.5.9.tar.xz 解压 tar -xf mkdir ./out cd ./out Cmake命…...
【LeetCode 热题 100】二叉树的最大深度 / 翻转二叉树 / 二叉树的直径 / 验证二叉搜索树
⭐️个人主页:小羊 ⭐️所属专栏:LeetCode 热题 100 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~ 目录 二叉树的中序遍历二叉树的最大深度翻转二叉树对称二叉树二叉树的直径二叉树的层序遍历将有序数组转换为二叉搜索树验…...
中国版 Cursor---腾讯云 CodeBuddy | 从安装VSCode到数独小游戏问世
中国版 Cursor---腾讯云 CodeBuddy | 从安装VSCode到数独小游戏问世 引言CodeBuddy环境准备VSCodeCodeBuddyNode.js下载安装 游戏开发Craft模型一句话生成数独游戏游戏体验 EdgeOne PagesMCPPages MCP Server配置 MCP Server 游戏源码总结 引言 在正文开始之前,先引…...
【蓝桥杯嵌入式】【复盘】第13届国赛真题
1. 前言 最近在准备16届的蓝桥杯嵌入式赛道的国赛,打算出一个系列的博客,记录STM32G431RBT6这块比赛用板上所有模块可能涉及到的所有考点,如果有错误或者遗漏欢迎各位大佬斧正。 本系列博客会分为以下两大类: 1.1. 单独模块的讲…...
Docker疑难杂症解决指南
Docker疑难杂症解决指南 Docker作为容器化技术的代表,广泛应用于开发、测试和部署环境中。然而,在使用过程中,用户可能会遇到各种问题。以下是一些常见的Docker疑难杂症及其解决方法。 容器无法启动 容器无法启动是常见问题之一࿰…...
嵌入式开发学习日志(数据结构--顺序结构单链表)Day19
一、顺序结构 安装软件命令: sudo apt-get install (软件名) 安装格式化对齐:sudo apt-get install clang-format 内存泄漏检测工具: sudo apt-get install valgrind 编译后,使用命令 valgrind ./a.out 即可看内…...
MySQL 8.0 OCP 1Z0-908 题目解析(2)
题目005 Choose two. Which two actions can obtain information about deadlocks? □ A) Run the SHOW ENGINE INNODB MUTEX command from the mysql client. □ B) Enable the innodb_status_output_locks global parameter. □ C) Enable the innodb_print_all_deadlock…...
短板效应--双指针
1.根据题意取决于最小的高,那么 若当移动最小高的一端,mv可能会变 但若移动较大的一端,v一定会变小就没有意义了,所以我们只需要每次移动一端,直到lr就行 2.原理就是与左右端点有关且每次只要移动一端就行 #include…...
CodeBuddy终极测评:中国版Cursor的开发革命(含安装指南+HTML游戏实战)
一、腾讯云CodeBuddy产品全景解读 1. 什么是腾讯云代码助手? 官方定义: Tencent Cloud CodeBuddy是由腾讯自研的AI编程辅助工具,基于混元大模型DeepSeek双引擎,提供: ✅ 智能代码补全(支持200语言&#x…...
【Linux】简单设计libc库
📝前言: 经过之间两篇文章,【Linux】基础IO(一)和【Linux】基础IO(二)的学些,我们对文件的基础IO已经有了一定的理解。 这篇文章我们来简单设计一下libc库,来复习一下文…...
3335. 字符串转换后的长度 I
3335. 字符串转换后的长度 I class Solution:def lengthAfterTransformations(self, s: str, t: int) -> int:# 大质数mod 10**97# 创建一个长度为26的数组cnt,对应26个小写字母cnt [0]*26# 计算出s中26个字符分别有多少个for ch in s:cnt[ord(ch)-ord(a)] 1f…...
《医院网络安全运营能力成熟度评估指南》(试行版)研究解读
引言 随着数字化转型的不断深入,医院信息化建设已从单点应用走向全面系统集成,信息系统已成为支撑医院业务运行和管理决策的基础设施。然而,信息化发展也带来了日益复杂的网络安全挑战,从传统的边界防护到如今的全方位安全威胁,医院网络安全建设面临着前所未有的压力。20…...
鸿蒙5.0项目开发——鸿蒙天气项目的实现(介绍)
【高心星出品】 文章目录 项目简介:项目运行效果图:主要功能:使用的技能点:开发环境: 项目简介: 这是一个基于鸿蒙系统(HarmonyOS)开发的天气应用,采用 ArkTS 语言开发&…...
软考软件测评师——计算机网络
目录 第一部分 核心知识点解析 1. IPv4地址规范 2. 层次化网络架构 3. 网络设备解析 4. URL结构规范 5. 关键网络命令 6. SNMP配置要求 第二部分 历年真题精析 2020年真题 2016年真题 2015年真题 高频考点总结 第一部分 核心知识点解析 1. IPv4地址规范 特殊地址说…...
Node.js 中的 URL 模块
一、URL 模块基础 1. 模块导入方式 // Node.js 方式 const url require(url);// ES 模块方式 (Node.js 14 或启用 ESM) import * as url from url; 2. 核心功能 解析 URL 字符串 格式化 URL 对象 URL 处理工具方法 WHATWG URL 标准实现 二、URL 解析与构建 1. 传统解…...
JavaWeb 前端开发
JavaWeb前端 初识 HTMLCSS 入门程序 什么是HTML HTML是由标签构成的 什么是CSS HTML快速入门 标签可以是大写,也可以是小写,也可以是大小写混用。 属性值也可以使用单引号,但一般使用双引号。 HTML的语法结构比较松散,不严谨…...
设计模式深度解析:AI大模型下的策略模式与模板方法模式对比解析
目录 一、策略模式:AI大模型的动态决策引擎 1.1 核心原理与工业级实现 1.2 AI时代的技术演进 二、模板方法模式:AI流水线的标准化基石 2.1 多模态处理框架设计 三、策略与模板方法的协同创新 3.1 电商推荐系统实践 四、前沿趋势与挑战 4.1 量子计算增强模式 五、伦理…...
2. 盒模型/布局模块 - 响应式产品展示页_案例:电商产品网格布局
2. 盒模型/布局模块 - 响应式产品展示页 案例:电商产品网格布局 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">:root {--primary-color…...
H5S 视频监控AWS S3 对象存储
本文介绍一下如何使用S3对象存储作为H5S 存储空间进行录像存储 然后创建一个对象存储,本文以minio 为例(实际项目亲测天翼云): 首先安装 s3fs 如果是redhat系列,使用如下命令 sudo yum install epel-release sudo yum install s3fs-fuse …...
Visual Studio 2022 跨网络远程调试
🚀 Visual Studio 2022 跨网络远程调试实践指南 在本地开发软件时,Visual Studio 的调试器是我们最依赖的工具之一。但是当目标程序运行在远程设备上,例如测试服务器、工控设备或嵌入式终端,如何实现 跨网络远程调试 成为了开发中…...
最短路与拓扑(1)
1、找最长良序字符串 #include<bits/stdc.h> using namespace std; const int N105; int dis[N]; int vis[N]; int edge[N][N]; int n,m; int vnum;void dij(int u, int v) {// 初始化距离数组和访问标记for(int i0; i<vnum; i) {vis[i] 0;dis[i] edge[u][i];}// D…...
【前缀和】和为 K 的子数组(medium)
【前缀和】和为 K 的子数组 题目描述算法原理和细节问题代码 题目描述 和为 K 的子数组 给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。 示例 1: 输入:nums [1,1,1], k 2 输出: 2 解释: 此题 [1,1] 与 [1,1] 为两种不同的…...
深入理解 JVM:StackOverFlow、OOM 与 GC overhead limit exceeded 的本质剖析及 Stack 与 Heap 的差异
摘要 在 Java 开发过程中,内存管理相关的问题一直是开发者需要重点关注的领域。StackOverFlow、OutOfMemory(OOM)和GC overhead limit exceeded是常见的运行时错误,而理解Stack(栈)和Heap(堆&a…...
汽车功能安全--TC3xx MBIST设计要点
英飞凌针对硬件潜伏故障的自测,提供了四种机制:PBIST、LBIST、MONBIST和MBIST。 LBIST和MONBIST我们已经聊过了,今天就快速介绍下MBIST。 MBIST,全程Memory Built-in Self Test,用于检测SRAM数据单元的完整性。 在2…...
blazor与硬件通信实现案例
在网页接入硬件交互通信方案这篇博客中,曾经提到了网页中接入各种硬件操作的方法,即通过Windows Service作为指令的中转,并建立websocket通信连接,进而实现接入硬件的各种操作。这篇博客就以实际的案例来讲解具体怎么实现。 一、建立Windows Service项目 比如我就建立了一…...
思迈特软件携手天阳科技,打造ChatBI金融智能分析新标杆
5月10日,广州思迈特软件有限公司(以下简称“思迈特软件”)与天阳宏业科技股份有限公司(以下简称“天阳科技”)在北京正式签署战略合作协议。思迈特软件董事长吴华夫、CEO姚诗成,天阳科技董事长兼总裁欧阳建…...
微服务的“导航系统”:使用Spring Cloud Eureka实现服务注册与发现
在上一篇中,我们理解了微服务架构的核心理念以及Spring Cloud为我们提供的强大工具集。我们提到,微服务架构的一个核心挑战在于,服务实例的网络位置是动态的,服务之间需要一种机制来互相定位。 想象一下,你开了一家新…...
Linux之初见进程
1. 冯诺依曼体系结构 冯诺依曼体系结构是计算机的基本设计原则之一,也被认为是现代计算机的基础。它由美国数学家约翰冯诺伊曼在20世纪40年代后期提出。冯诺依曼体系结构包括存储程序概念、将数据和指令存储在同一存储器中、按照顺序执行指令等关键特征。 具体来说…...
Docker入门教程:常用命令与基础概念
目录 简介常用命令Docker 常用命令汇总docker run 命令格式与参数解析 简介 Docker 是一个客户端-服务器(client-server)架构的应用程序,其中包含两个主要组件:Docker 客户端和 Docker 守护进程(也称为 Docker Daemon…...
内核深入学习3——分析ARM32和ARM64体系架构下的Linux内存区域示意图与页表的建立流程
内核深入学习3——ARM32/ARM64在Linux内核中的实现(2) 今天我们来讨论的是一个硬核的内容,也是一个老生常谈的话题——那就是分析ARM32和ARM64体系架构下的Linux内存区域示意图的内容。对于ARM64的部分,我们早就知道一个基本的…...
vim 练习题
文章目录 前言:学习了vim基础命令,上机实操下吧命令模式练习插入模式练习末行模式练习视图模式练习高级操作练习 总结 前言:学习了vim基础命令,上机实操下吧 命令模式练习 打开任意文本文件,使用gg跳转到首行&#x…...
CSS3 选择器完全指南:从基础到高级的元素定位技术
CSS3选择器完全指南:从基础到高级的元素定位技术 一、基本选择器:精准定位的基石 (一)元素选择器 通过元素标签名直接匹配页面元素,语法简洁直观: p { color: #333; } /* 选择所有<p>元素 */ div…...
从SAM看交互式分割与可提示分割的区别与联系:Interactive Segmentation Promptable Segmentation
SAM的火爆也带来了一项新的任务:Promptable Segmentation,并且作者在文中对比了交互式分割Interactive Segmentation,并且在训练过程中也参考了交互式分割的训练方法,那么可提示分割与交互式分割有什么区别? 个人观点…...
k8s初始化时候,报错无法通过 CRI(容器运行时接口)与 containerd 通信
报错主要信息处 [reset] Unmounting mounted directories in “/var/lib/kubelet” W0513 11:34:19.818023 27124 cleanupnode.go:134] [reset] Failed to evaluate the “/var/lib/kubelet” directory. Skipping its unmount and cleanup: lstat /var/lib/kubelet: no such f…...
k8s之k8s集群部署
一、kubernetes基础环境搭建 1.安装虚拟机 2. 基础环境配置 2.1 关闭防火墙 更改主机名 #系统更新 sudo dnf update -y # 关闭防火墙 sudo systemctl stop firewalld sudo systemctl disable firewalld # 临时关闭 SELinux sudo setenforce 0 # 永久关闭 SELinux sudo sed -i…...
百度智能云千帆携手联想,共创MCP生态宇宙
5月7日,2025联想创新科技大会(Tech World)在上海世博中心举行,本届大会以“让AI成为创新生产力”为主题。会上,联想集团董事长兼CEO杨元庆展示了包括覆盖全场景的超级智能体矩阵,包括个人超级智能体、企业超…...
黑白浮生项目测试报告
文章目录 一、项目背景二、项目功能三、测试计划1. 功能测试1.1 注册页面1.1.1 正常注册1.1.2 异常注册 1.2 登录页面1.2.1 正常登录1.2.2 异常登录 1.3 游戏大厅页面1.3.1 开始匹配1.3.2 取消匹配 1.4 游戏房间页面1.4.1 落子1.4.2 游戏结束 2. 自动化测试2.1 创建浏览器驱动类…...
《操作系统真象还原》第十四章(2)——文件描述符、文件操作基础函数
文章目录 前言文件描述符简介文件描述符原理文件描述符实现修改thread.h修改thread.c 文件操作相关的基础函数inode操作相关函数文件相关函数编写file.h编写file.c 目录相关函数完善fs/dir.h编写fs/dir.c 路径解析相关函数实现文件检索功能修改fs.h继续完善fs.c makefile 结语 …...
k8s v1.26 实战csi-nfs 部署
一 前言 使用自开发的一键k8s基础环境部署后,存储需要解决,就是测试环境故选择nfs比较简单,翻阅很多网上资料感觉都不是很全面,结合网上资料折腾了一天,总算是完成了csi-nfs部署。其实之前也部署过,经过一…...
测试集群的功能-执行wordcount程序
具体的操作步骤如下: 确保hadoop是正确运行的。hdfs和yarn都正常启动了。在集群根目录下创建wcinput目录,并在它的下面上传两个文本文件word1.txt, word2.txt,其中保存了要测试的单词信息。在任意一台设备中,进入到hadoop的主目录…...