包头网站建设/百度官网网站首页
往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
- 持续更新中……
概述
功能简介
PIN即管脚控制器,用于统一管理各SoC的管脚资源,对外提供管脚复用功能。
基本概念
PIN是一个软件层面的概念,目的是为了统一对各SoC的PIN管脚进行管理,对外提供管脚复用功能,配置PIN管脚的电气特性。
- SoC(System on Chip)
系统级芯片,又称作片上系统,通常是面向特定用途将微处理器、模拟IP核、数字IP核和存储器集成在单一芯片的标准产品。
- 管脚复用
由于芯片自身的引脚数量有限,无法满足日益增多的外接需求。此时可以通过软件层面的寄存器设置,让引脚工作在不同的状态,从而实现相同引脚完成不同功能的目的。
运作机制
在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。PIN模块接口适配模式采用统一服务模式(如图1所示)。
在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。
PIN模块各分层作用:
-
接口层提供获取PIN管脚、设置PIN管脚推拉方式、获取PIN管脚推拉方式、设置PIN管脚推拉强度、获取PIN管脚推拉强度、设置PIN管脚功能、获取PIN管脚功能、释放PIN管脚的接口。
-
核心层主要提供PIN管脚资源匹配,PIN管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互。
-
适配层主要是将钩子函数的功能实例化,实现具体的功能。
图 1 统一服务模式结构图
约束与限制
PIN模块目前只支持小型系统LiteOS-A内核。
开发指导
场景介绍
PIN模块主要用于管脚资源管理。在各SoC对接HDF框架时,需要来适配PIN驱动。下文将介绍如何进行PIN驱动适配。
接口说明
为了保证上层在调用PIN接口时能够正确的操作PIN管脚,核心层在//drivers/hdf_core/framework/support/platform/include/pin/pin_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。
PinCntlrMethod定义:
struct PinCntlrMethod {int32_t (*SetPinPull)(struct PinCntlr *cntlr, uint32_t index, enum PinPullType pullType);int32_t (*GetPinPull)(struct PinCntlr *cntlr, uint32_t index, enum PinPullType *pullType);int32_t (*SetPinStrength)(struct PinCntlr *cntlr, uint32_t index, uint32_t strength);int32_t (*GetPinStrength)(struct PinCntlr *cntlr, uint32_t index, uint32_t *strength);int32_t (*SetPinFunc)(struct PinCntlr *cntlr, uint32_t index, const char *funcName);int32_t (*GetPinFunc)(struct PinCntlr *cntlr, uint32_t index, const char **funcName);
};
c
表 1 PinCntlrMethod成员的钩子函数功能说明
成员函数 | 入参 | 出参 | 返回值 | 功能 |
---|---|---|---|---|
SetPinPull | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 pullType:枚举常量,PIN管脚推拉方式 | 无 | HDF_STATUS相关状态 | PIN设置管脚推拉方式 |
GetPinPull | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 | pullType:枚举常量指针,传出获取的PIN管脚推拉方式 | HDF_STATUS相关状态 | PIN获取管脚推拉方式 |
SetPinStrength | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 strength:uint32_t变量,PIN推拉强度 | 无 | HDF_STATUS相关状态 | PIN设置推拉强度 |
GetPinStrength | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 | strength:uint32_t变量指针,传出获取的PIN推拉强度 | HDF_STATUS相关状态 | PIN获取推拉强度 |
SetPinFunc | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 funcName:char指针常量,传入PIN管脚功能 | 无 | HDF_STATUS相关状态 | PIN设置管脚功能 |
GetPinFunc | cntlr:结构体指针,核心层PIN控制器 index:uint32_t类型变量,管脚索引号 | funcName:char双重指针常量,传出获取的PIN管脚功能 | HDF_STATUS相关状态 | PIN获取管脚功能 |
开发步骤
PIN模块适配HDF框架包含以下四个步骤:
-
实例化驱动入口
-
配置属性文件
-
实例化PIN控制器对象
-
驱动调试
开发实例
下方将基于Hi3516DV300开发板以//device/soc/hisilicon/common/platform/pin/pin_hi35xx.c驱动为示例,展示需要驱动适配者提供哪些内容来完整实现设备功能。
- 实例化驱动入口
驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。
一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。
PIN驱动入口开发参考:
static struct HdfDriverEntry g_hi35xxPinDriverEntry = {.moduleVersion = 1,.Bind = Hi35xxPinBind, // PIN不需要实现Bind,本例是一个空实现,驱动适配者可根据自身需要添加相关操作.Init = Hi35xxPinInit, // 挂接PIN模块Init实例化.Release = Hi35xxPinRelease, // 挂接PIN模块Release实例化.moduleName = "hi35xx_pin_driver", // 【必要且与HCS文件中里面的moduleName匹配】};HDF_INIT(g_hi35xxPinDriverEntry); // 调用HDF_INIT将驱动入口注册到HDF框架中c
-
配置属性文件
完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以两个PIN控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息,以及在gpio_config.hcs文件中增加对应的器件属性。器件属性值对于驱动适配者的驱动实现以及核心层PinCntlr相关成员的默认值或限制范围有密切关系,比如控制器号,控制器管脚数量、管脚等,需要在pin_config.hcs中配置器件属性。
统一服务模式的特点是device_info.hcs文件中第一个设备节点必须为PIN管理器,其各项参数如表2所示:
表 2 device_info.hcs节点参数说明
成员名 | 值 |
---|---|
policy | 驱动服务发布的策略,PIN管理器具体配置为2,表示驱动对内核态和用户态都发布服务 |
| priority | 驱动启动优先级(0-200),值越大优先级越低。PIN管理器具体配置为8 |
| permission | 驱动创建设备节点权限,PIN管理器具体配置为0664 |
| moduleName | 驱动名称,PIN管理器固定为HDF_PLATFORM_PIN_MANAGER |
| serviceName | 驱动对外发布服务的名称,PIN管理器服务名设置为HDF_PLATFORM_PIN_MANAGER |
| deviceMatchAttr | 驱动私有数据匹配的关键字,PIN管理器没有使用,可忽略 |
- device_info.hcs 配置参考:
在//vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs文件中添加deviceNode描述。
root {device_info {platform :: host {hostName = "platform_host";priority = 50;device_pin :: device {device0 :: deviceNode { // 用于统一管理PIN并发布服务policy = 2; // 2:用户态可见;1:内核态可见;0:不需要发布服务。priority = 8; // 启动优先级permission = 0644; // 创建设备节点权限moduleName = "HDF_PLATFORM_PIN_MANAGER";serviceName = "HDF_PLATFORM_PIN_MANAGER";}device1 :: deviceNode { // 为每一个PIN控制器配置一个HDF设备节点,存在多个时必须添加,否则不用。policy = 0;priority = 10; // 驱动启动优先级permission = 0644; // 驱动创建设备节点权限moduleName = "hi35xx_pin_driver"; // 【必要】用于指定驱动名称,需要与期望的驱动Entry中的moduleName一致。deviceMatchAttr = "hisilicon_hi35xx_pin_0"; // 【必要】用于配置控制器私有数据,要与pin_config.hcs中对应控制器保持一致,具体的控制器信息在pin_config.hcs中。}device2 :: deviceNode {policy = 0;priority = 10;permission = 0644;moduleName = "hi35xx_pin_driver";deviceMatchAttr = "hisilicon_hi35xx_pin_1";}...... // 如果存在多个PIN控制器时【必须】添加节点,否则不用 }}}}c
- pin_config.hcs配置参考: 在//device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs文件配置器件属性,其中配置参数如下:
root {platform {pin_config_hi35xx {template pin_controller { // 【必要】配置模板配,如果下面节点使用时继承该模板,则节点中未声明的字段会使用该模板中的默认值。number = 0; // 【必要】PIN控制器号regStartBasePhy = 0; // 【必要】寄存器物理基地址起始地址regSize = 0; // 【必要】寄存器位宽pinCount = 0; // 【必要】管脚数量match_attr = "";template pin_desc {pinName = ""; // 【必要】管脚名称init = 0; // 【必要】寄存器默认值F0 = ""; // 【必要】功能0F1 = ""; // 功能1F2 = ""; // 功能2F3 = ""; // 功能3F4 = ""; // 功能4F5 = ""; // 功能5}}controller_0 :: pin_controller {number = 0;regStartBasePhy = 0x10FF0000;regSize = 0x48;pinCount = 18;match_attr = "hisilicon_hi35xx_pin_0";T1 :: pin_desc {pinName = "T1";init = 0x0600;F0 = "EMMC_CLK";F1 = "SFC_CLK";F2 = "SFC_BOOT_MODE";}...... // 对应管脚控制器下的每个管脚,按实际添加。}...... // 每个管脚控制器对应一个控制器节点,如存在多个PIN控制器,请依次添加对应的控制器节点。}}}c
需要注意的是,新增pin_config.hcs配置文件后,必须在产品对应的hdf.hcs文件中将其包含如下语句所示,否则配置文件无法生效。
#include "../../../../device/soc/hisilicon/hi3516dv300/sdk_liteos/hdf_config/pin/pin_config.hcs" // 配置文件相对路径c
- 实例化PIN控制器对象
完成配置属性文件之后,下一步就是以核心层PinCntlr对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化PinCntlr成员PinCntlrMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。
- 驱动适配者自定义结构体参考
从驱动的角度看,自定义结构体是参数和数据的载体,而且pin_config.hcs文件中的数值会被HDF读入并通过DeviceResourceIface来初始化结构体成员,一些重要数值也会传递给核心层对象。
在Hi35xxPinCntlrInit函数中对PinCntlr成员进行初始化操作。
// 驱动适配者自定义管脚描述结构体struct Hi35xxPinDesc {const char *pinName; // 管脚名uint32_t init; // 初始化值uint32_t index; // 管脚索引int32_t pullType; // 管脚推拉方式int32_t strength; // 管脚推拉强度const char *func[HI35XX_PIN_FUNC_MAX]; // 管脚功能名字符串数组};// 驱动适配者自定义结构体struct Hi35xxPinCntlr {struct PinCntlr cntlr; // 是核心层控制对象,具体描述见下面struct Hi35xxPinDesc *desc; // 驱动适配者自定义管脚描述结构体指针volatile unsigned char *regBase; // 寄存器映射地址uint16_t number; // 管脚控制器编号uint32_t regStartBasePhy; // 寄存器物理基地址起始地址uint32_t regSize; // 寄存器位宽uint32_t pinCount; // 管脚数量};// PinCntlr是核心层控制器结构体,其中的成员在Init函数中会被赋值。struct PinCntlr {struct IDeviceIoService service; // 驱动服务struct HdfDeviceObject *device; // 驱动设备对象struct PinCntlrMethod *method; // 钩子函数struct DListHead node; // 链表节点OsalSpinlock spin; // 自旋锁uint16_t number; // 管脚控制器编号uint16_t pinCount; // 管脚数量struct PinDesc *pins; // 管脚资源void *priv; // 私有数据};// PIN管脚控制器初始化static int32_t Hi35xxPinCntlrInit(struct HdfDeviceObject *device, struct Hi35xxPinCntlr *hi35xx){struct DeviceResourceIface *drsOps = NULL;int32_t ret;// 从hcs文件读取管脚控制器相关属性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;}ret = drsOps->GetUint16(device->property, "number", &hi35xx->number, 0);if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read number failed", __func__);return ret;}if (hi35xx->number > HI35XX_PIN_MAX_NUMBER) {HDF_LOGE("%s: invalid number:%u", __func__, hi35xx->number);return HDF_ERR_INVALID_PARAM;}ret = drsOps->GetUint32(device->property, "regStartBasePhy", &hi35xx->regStartBasePhy, 0);if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read regStartBasePhy failed", __func__);return ret;}ret = drsOps->GetUint32(device->property, "regSize", &hi35xx->regSize, 0);if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read regSize failed", __func__);return ret;}ret = drsOps->GetUint32(device->property, "pinCount", &hi35xx->pinCount, 0);if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read pinCount failed", __func__);return ret;}if (hi35xx->pinCount > PIN_MAX_CNT_PER_CNTLR) {HDF_LOGE("%s: invalid number:%u", __func__, hi35xx->number);return HDF_ERR_INVALID_PARAM;}// 将读取的值赋值给管脚控制器的成员,完成管脚控制器初始化。hi35xx->cntlr.pinCount = hi35xx->pinCount;hi35xx->cntlr.number = hi35xx->number;hi35xx->regBase = OsalIoRemap(hi35xx->regStartBasePhy, hi35xx->regSize); // 管脚控制器映射if (hi35xx->regBase == NULL) {HDF_LOGE("%s: remap Pin base failed", __func__);return HDF_ERR_IO;}hi35xx->desc = (struct Hi35xxPinDesc *)OsalMemCalloc(sizeof(struct Hi35xxPinDesc) * hi35xx->pinCount);if (hi35xx->desc == NULL) {HDF_LOGE("%s: memcalloc hi35xx desc failed", __func__);return HDF_ERR_MALLOC_FAIL;}hi35xx->cntlr.pins = (struct PinDesc *)OsalMemCalloc(sizeof(struct PinDesc) * hi35xx->pinCount);if (hi35xx->desc == NULL) {HDF_LOGE("%s: memcalloc hi35xx cntlr pins failed", __func__);return HDF_ERR_MALLOC_FAIL;}return HDF_SUCCESS;}c
- PinCntlr成员钩子函数结构体PinCntlrMethod的实例化。
static struct PinCntlrMethod g_method = {.SetPinPull = Hi35xxPinSetPull, // 设置推拉方式.GetPinPull = Hi35xxPinGetPull, // 获取推拉方式.SetPinStrength = Hi35xxPinSetStrength, // 设置推拉强度.GetPinStrength = Hi35xxPinGetStrength, // 获取推拉强度.SetPinFunc = Hi35xxPinSetFunc, // 设置管脚功能.GetPinFunc = Hi35xxPinGetFunc, // 获取管脚功能};c
- Init函数开发参考
入参:
HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
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_INVALID_PARAM | 参数非法 |
HDF_ERR_IO | I/O 错误 |
HDF_SUCCESS | 初始化成功 |
HDF_FAILURE | 初始化失败 |
函数说明:
初始化自定义结构体对象和PinCntlr成员,并通过调用核心层PinCntlrAdd函数挂载PIN控制器。
static int32_t Hi35xxPinReadFunc(struct Hi35xxPinDesc *desc, const struct DeviceResourceNode *node, struct DeviceResourceIface *drsOps){int32_t ret;uint32_t funcNum = 0;// 从hcs中读取管脚控制器子节点管脚功能名ret = drsOps->GetString(node, "F0", &desc->func[funcNum], "NULL");if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read F0 failed", __func__);return ret;}funcNum++;ret = drsOps->GetString(node, "F1", &desc->func[funcNum], "NULL");if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read F1 failed", __func__);return ret;}funcNum++;......return HDF_SUCCESS;}static int32_t Hi35xxPinParsePinNode(const struct DeviceResourceNode *node, struct Hi35xxPinCntlr *hi35xx, int32_t index){int32_t ret;struct DeviceResourceIface *drsOps = NULL;// 从hcs中读取管脚控制器子节点管脚相关属性drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) {HDF_LOGE("%s: invalid drs ops fail!", __func__);return HDF_FAILURE;}ret = drsOps->GetString(node, "pinName", &hi35xx->desc[index].pinName, "NULL");if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read pinName failed", __func__);return ret;}...ret = Hi35xxPinReadFunc(&hi35xx->desc[index], node, drsOps);if (ret != HDF_SUCCESS) {HDF_LOGE("%s:Pin read Func failed", __func__);return ret;}hi35xx->cntlr.pins[index].pinName = hi35xx->desc[index].pinName;hi35xx->cntlr.pins[index].priv = (void *)node;......return HDF_SUCCESS;}static int32_t Hi35xxPinInit(struct HdfDeviceObject *device){......struct Hi35xxPinCntlr *hi35xx = NULL;......ret = Hi35xxPinCntlrInit(device, hi35xx); // 管脚控制器初始化......DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { // 遍历管脚控制器的每个子节点ret = Hi35xxPinParsePinNode(childNode, hi35xx, index); // 解析子节点......}hi35xx->cntlr.method = &g_method; // PinCntlrMethod实例化实例化对象的挂载ret = PinCntlrAdd(&hi35xx->cntlr); // 添加控制器if (ret != HDF_SUCCESS) {HDF_LOGE("%s: add Pin cntlr: failed", __func__);ret = HDF_FAILURE;}return HDF_SUCCESS;}c
- Release函数开发参考
入参:
HdfDeviceObject:HDF框架给每一个驱动创建的设备对象,用来保存设备相关的私有数据和服务接口。
返回值:
无。
函数说明:
释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口。当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。
static void Hi35xxPinRelease(struct HdfDeviceObject *device){int32_t ret;uint16_t number;struct PinCntlr *cntlr = NULL;struct Hi35xxPinCntlr *hi35xx = NULL;struct DeviceResourceIface *drsOps = NULL;if (device == NULL || device->property == NULL) {HDF_LOGE("%s: device or property is null", __func__);return;}// 从hcs文件中读取管脚控制器编号drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if (drsOps == NULL || drsOps->GetUint32 == NULL || drsOps->GetString == NULL) { HDF_LOGE("%s: invalid drs ops", __func__);return;}ret = drsOps->GetUint16(device->property, "number", &number, 0);if (ret != HDF_SUCCESS) {HDF_LOGE("%s: read cntlr number failed", __func__);return;}cntlr = PinCntlrGetByNumber(number); // 通过管脚控制器编号获取管脚控制器PinCntlrRemove(cntlr);hi35xx = (struct Hi35xxPinCntlr *)cntlr;if (hi35xx != NULL) {if (hi35xx->regBase != NULL) {OsalIoUnmap((void *)hi35xx->regBase);}OsalMemFree(hi35xx);}}c
-
驱动调试
【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,PIN管脚设置推拉方式、推拉强度等。
最后
经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?
为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。
《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview
如何快速入门?
1.基本概念
2.构建第一个ArkTS应用
3.……
鸿蒙开发面试真题(含参考答案):
《OpenHarmony源码解析》:
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
- 系统架构分析
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……
OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview
相关文章:

OpenHarmony(鸿蒙南向)——平台驱动开发【PIN】
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 PIN即管脚控制器,用于统一管理各SoC的…...

南平自闭症寄宿制学校:让孩子自信绽放
在繁华与喧嚣交织的都市之中,有一片静谧而充满希望的土地——广州星贝育园自闭症儿童寄宿制学校,这里不仅是知识的殿堂,更是自闭症儿童心灵成长的温馨家园。星贝育园,以其独特的教育理念与细致入微的关怀,为这些特殊的…...

汽车总线之---- LIN总线
Introduction LIN总线的简介,对于传统的这种点对点的连接方式,我们可以看到ECU相关的传感器和执行器是直接连接到ECU的,当传感器和执行器的数量较少时,这样的连接方式是能满足要求的,但是随着汽车电控功能数量的不断增…...

Android开发MPAndroidChart两条折线图
Android开发MPAndroidChart两条折线图 Android开发两条折线图效果,还是有一定难度的,难点它的起点不是坐标0的开始,还有数值上有背景图 一、思路: 用的是MPAndroidChart的BarChart 二、效果图: 三、关键代码&#…...

HTML-ES6.0核心技术
1.ES6简介 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。ECMAScript 和 JavaScri…...

车间调度问题数学建模与CPLEX优化
完成了这些基础研究工作,整理成文档以供参考 序言... i 第一章 引言... 1 1.1 车间调度问题概述... 1 1.2 车间调度问题分类表示法... 5 1.3 车间调度对制造企业的作用... 6 1.4 本章小结... 7 第二章 CPLEX基础... 8 2.1 CPLEX概述... 8 2.1.1 CPLEX简介.…...
< 基础物理 >
SI国际单位制 常见的公制单位 为什么需要单位,是统一衡量的标准 通过国际单位,以及单位的拓展,以及单位的组合,形成一系列新的测量单位 面积 m^2 速率 m/s 米每二次方秒,m / s, delta表示增量, 每秒移动多少米 加…...

【web开发】Spring Boot 快速搭建Web项目(三)
Date: 2024.08.31 18:01:20 author: lijianzhan 简述:根据上篇原文Spring Boot 快速搭建Web项目(二),由于已经搭建好项目初始的框架,以及自动创建了一个启动类文件(TestWebApplication.java) …...

无人机之战斗机的详解!
一、高性能飞行能力 高速飞行:具备较高的巡航速度和最大飞行速度,以便快速抵达任务区域并灵活应对战场情况。 长航程:拥有足够的航程以执行远程任务,覆盖广阔的作战区域 高升限:能够飞行到较高的高度,以…...

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)
相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序…...

嵌入式边缘计算软硬件开发“1+X”考证建设方案
一、引言 随着物联网、大数据、人工智能等技术的飞速发展,嵌入式边缘计算作为连接物理世界与数字世界的桥梁,其重要性日益凸显。为了适应行业对高技能人才的需求,推动嵌入式边缘计算技术的普及与应用,特制定本“1X”考证建设方案…...

ES8的Java API client 8.0 简单示例操作 Elasticsearch
1.加入依赖 <dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.12.2</version></dependency>2.配置类 Slf4j Configuration public class ElasticSearchConfig {Valu…...

多线程CompletableFuture
最近发现同事整理了一个不错的关于CompletableFuture的文档,在这里记录一下,方便以后工作备用 CompletableFuture future CompletableFuture.supplyAsync(() -> {return "开新线程异步执行"; })result future.get(); // 线程阻塞等待结果…...

AR传送门+特定区域显示内容+放大镜 效果着色器使用
AR传送门特定区域显示内容放大镜 效果 关键词:Portal Mask 1、教程链接: AR 传送门教程 Unity - Portal Mask Implementation - Part 4_哔哩哔哩_bilibili 应用案例效果: 2、案例下载地址:使用unity 2021.3.33f1 obi 工具…...

设置Hadoop守护进程的JVM参数
一般情况下我们不去动守护进程的JVM,这里的守护进程说的是NameNode、DataNode等Hadoop服务自己本身的进程。但是有一些特殊情况下需要限制,比如工作中虽然集群中资源队列会有10%左右的预留空余,不过这是整个集群队列的限制,对于Da…...

可视化大屏
可视化大屏 是一种利用计算机图形学技术,将复杂的数据和信息转换为直观的可视化图形,以呈现数据信息的工具。它不仅在电影中常见,而且已经实实在在地被应用在商业、金融、制造等各个行业的业务场景中,成为大数据分析和展示的重要工…...

pytest框架
pytest测试框架 单元测试框架定义:针对软件开发最小的单元(函数,方法)进行正确性位置测试 单元测试框架:java(junit,testing)python(unittest,pytest&#…...

基于大数据的亚健康人群数据分析及可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

黄金短线交易策略:波动中的高效盈利之法
今日,亚市盘初,现货黄金就高位震荡。在昨日金价再度冲高,一度刷新历史高点至2685.49美元,收报2672.25美元。其中主要原因是美国公布了最新的核心PCE(个人消费支出)物价指数和初请失业金人数等经济数据&…...

西陆家政系统V1.0.1
微信小程序开发的西陆家政服务管理系统小程序 V1.0.1bug修复优化 1.修复首页轮播不能自动轮播问题;2.修复订单详情价格显示问题;3.修复在开放城市模式下,其他城市可以下单问题;4.修复个人二维码跳转小程序路径异常问题;5.修复小程序编辑我的地址选择定位后不刷新问题…...

时间安全精细化管理平台/iapp/mobile/facereg/facereg.html接口存在未授权访问漏洞
漏洞描述 登录--时间&安全精细化管理平台/iapp/mobile/facereg/facereg.html接口存在未授权访问漏洞,黑客可以未授权等级员工信息对平台造成影响 FOFA: body"登录--时间&安全精细化管理平台" 漏洞复现 IP/iapp/mobile/facereg…...

自动化测试实例:Web登录功能性测试(无验证码)
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是自动化测试 把人为驱动的测试行为转化为机器执行的一种过程称为自动化测试。(来自百度百科)本质上来说,自动化测试对比起手工测试除了需要…...

【算法篇】二叉树类(3)(笔记)
目录 一、Leetcode 题目 1. 二叉树的最近公共祖先 2. 二叉搜索树的最近公共祖先 (1)递归法 (2)迭代法 3. 二叉搜索树中的插入操作 (1)递归法 (2)迭代法 4. 删除二叉搜索树中…...

基于php的律所管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

MySQL 之索引详解
想象一下,你正在图书馆寻找一本关于 MySQL 索引的书。图书馆里有成千上万本书,但没有目录。你只能一排一排、一本一本地找,直到找到你想要的书。这将会花费大量的时间!数据库索引就像图书馆的目录一样,可以帮助数据库系…...

C#测试调用FreeSpire.PDFViewer浏览PDF文件
Free Spire.PDFViewer是商业版Spire.PDFViewer的社区版本,支持以控件形式打开并查看PDf文件,但由于是免费版本,存在使用限制,打开的PDF文档只显示前10页内容。如果日常操作的pdf文件都不超过10页,可以考虑使用Free Spi…...

又一挣钱副业:AI生成影视解说,半个月涨粉变现3.5W+!
这两年大家都在感叹生活不易,然而我想说的是,机会还是有的,但问题不在于有没有,而在于你是否能够认准机会,然后抓住它。 接触过很多咨询项目的人,发现很多人依旧停留在传统思维中,认为副业就是…...

R语言 基础 笔记 3
起因, 目的: 思考一个问题: AI 这么强,AI 什么都知道,为什么还要学习这些基础的东西, 为什么还要写这些笔记? 我觉得,大体过一遍,还是有好处的。 有个大致印象,下次查的时候,也方便一些。 几个函数 cbind() 按照列,拼接数据, 会改变某些列的数据类型。data() 查看…...

【MySQL】常见的SQL优化方式(一)
目录 1、插入数据 (1)批量插入 (2)手动提交事务 (3)主键顺序插入 2、主键优化 (1)页分裂 (2)页合并 3、order by 优化 (1)排…...

【重点】使用axios.request.put上传文件,报错分析
使用axios的put方法上传文件时,如果遇到错误,可能的原因有以下几点: 跨域问题:如果请求的URL与当前页面的域名不同,可能会触发跨域问题。解决方法是在服务器端设置允许跨域请求,如设置CORS(跨域…...