OpenHarmony-4.基于dayu800 GPIO 实践(2)

  • 基于dayu800 GPIO 进行开发

1.DAYU800开发板硬件接口

  LicheePi 4A 板载 2x10pin 插针,其中有 16 个原生 IO,包括 6 个普通 IO,3 对串口,一个 SPI。TH1520 SOC 具有4个GPIO bank,每个bank最大有32个IO:
在这里插入图片描述
  以俯视底板正面为视角,TOP为左侧,BOTTOM为右侧,GPIO对应关系如下:
在这里插入图片描述
  GPIO 号的对应关系如下图所示:
在这里插入图片描述

  从以上可以看出板载20pin插针中,4个普通GPIO对应的数字分别如下表:

在这里插入图片描述
1.2.搭建点灯环境

  给GPIO接灯,使用HiSpark_WiFi_IoT_SSL_VER.A红绿灯板,将红绿灯板和DAYU800开发版按以下方式接线:
在这里插入图片描述
  GPIO进行相应的操作:

#黄灯
echo 428 > /sys/class/gpio/export  
echo out > /sys/class/gpio/gpio428/direction 
echo 1 > /sys/class/gpio/gpio428/value  
echo 0 > /sys/class/gpio/gpio428/value#红灯
echo 429 > /sys/class/gpio/export  
echo out > /sys/class/gpio/gpio429/direction 
echo 1 > /sys/class/gpio/gpio429/value  
echo 0 > /sys/class/gpio/gpio429/value#绿灯
echo 430 > /sys/class/gpio/export  
echo out > /sys/class/gpio/gpio430/direction 
echo 1 > /sys/class/gpio/gpio430/value  

2.GPIO 代码框架

  • vendor/hihope/dayu800/hdf_config/khdf/device_info/device_info.hcs
 32         platform :: host {33             hostName = "platform_host";34             priority = 50;35             device_gpio :: device {36                 device0 :: deviceNode {37                     policy = 0;38                     priority = 10;39                     permission = 0644;40                     moduleName = "linux_gpio_adapter";41                     deviceMatchAttr = "linux_gpio_adapter";42                 }43             }
  • driver/hdf_core/adapter/khdf/linux/platform/gpio/gpio_adapter.c:
269 static int32_t LinuxGpioInit(struct HdfDeviceObject *device)
270 {
271     if (device == NULL) {
272         HDF_LOGE("%s: Fail, device is NULL.", __func__);
273         return HDF_ERR_INVALID_OBJECT;
274     }
275
276     (void)gpiochip_find(device, LinuxGpioMatchProbe);
277     HDF_LOGI("%s: dev service:%s init done!", __func__, HdfDeviceGetServiceName(device));
278     return HDF_SUCCESS;
279 }319 struct HdfDriverEntry g_gpioLinuxDriverEntry = {
320     .moduleVersion = 1,
321     .Bind = LinuxGpioBind,
322     .Init = LinuxGpioInit,
323     .Release = LinuxGpioRelease,
324     .moduleName = "linux_gpio_adapter",
325 };
326 HDF_INIT(g_gpioLinuxDriverEntry);

  根据moduleName = "linux_gpio_adapter"进行配置之后,加载gpio hdf 驱动,调用LinuxGpioInit进行初始化,其中调用linux 内核gpiochip_find函数 遍历GPIO设备(gpio_devices)获取gpio控制器(gpio_chip).

232 static int LinuxGpioMatchProbe(struct gpio_chip *chip, void *data)
233 {
234     int32_t ret;
235     struct GpioCntlr *cntlr = NULL;
236
241     HDF_LOGI("%s: find gpio chip(start:%d, count:%u)", __func__, chip->base, chip->ngpio);
246
247     cntlr = (struct GpioCntlr *)OsalMemCalloc(sizeof(*cntlr));
252
253     cntlr->ops = &g_method;  //gpio 操作集
254     cntlr->start = (uint16_t)chip->base;
255     cntlr->count = (uint16_t)chip->ngpio;
256     ret = GpioCntlrAdd(cntlr);
263
264     HDF_LOGI("%s: add gpio controller(start:%d, count:%u) succeed",
265         __func__, cntlr->start, cntlr->count);
266     return 0; // return 0 to continue
267 }215 static struct GpioMethod g_method = {
216     .write = LinuxGpioWrite,
217     .read = LinuxGpioRead,
218     .setDir = LinuxGpioSetDir,
219     .getDir = LinuxGpioGetDir,
220     .setIrq = LinuxGpioSetIrq,
221     .unsetIrq = LinuxGpioUnsetIrq,
222     .enableIrq = LinuxGpioEnableIrq,
223     .disableIrq = LinuxGpioDisableIrq,
224 };

3.调试GPIO代码

3.1.代码目录结构

  vendor/hihope/dayu800目录下新建sample目录,目录结构如下:

dayu800/dayu800-sig/vendor/hihope/dayu800/sample$ tree
.
├── BUILD.gn
└── hardware├── BUILD.gn└── gpio├── BUILD.gn├── gpio_dayu800.c├── gpio_dayu800.h└── main.c2 directories, 6 files

3.2.增加编译sample

  创建模块目录//vendor/hihope/dayu800/sample,在vendor/hihope/dayu800/ohos.build module_list中添加 模块名称dayu800_sample,如下所示:

diff --git a/dayu800/ohos.build b/dayu800/ohos.build
index cea86ba..d268f2a 100644
--- a/dayu800/ohos.build
+++ b/dayu800/ohos.build
@@ -7,7 +7,8 @@"//vendor/hihope/dayu800/preinstall-config:preinstall-config","//vendor/hihope/dayu800/resourceschedule:resourceschedule","//vendor/hihope/dayu800/etc:product_etc_conf",
-        "//vendor/hihope/dayu800/audio:audio_policy_config"
+        "//vendor/hihope/dayu800/audio:audio_policy_config",
+        "//vendor/hihope/dayu800/sample:dayu800_sample"]}},

3.3.新增sample目录BUILD.gn

  添加vendor/hihope/dayu800/sample/BUILD.gn文件,内容如下:

  1 import("//build/ohos.gni")23 group("dayu800_sample") {4  deps = [5   "hardware:hardware"6  ]7 }

  创建名为"dayu800_sample"的group。group的作用是将多个target(可以是源文件、库文件或可执行文件等)组织在一起,方便进行编译和管理。在这个group中,依赖名为"hardware:hardware"的target。这个依赖关系意味着在编译"dayu800_sample"时,需要先编译并链接"hardware:hardware"这个target。通过使用group,可以更方便地管理项目的编译和构建过程。

3.4.新增sample/hardware目录下的BUILD.gn

  新建hardware目录,并添加vendor/hihope/dayu800/sample/hardware/BUILD.gn文件:

  1 import("//build/ohos.gni")23 group("hardware") {4  deps = [5   "gpio:gpio_dayu800"6  ]7 }

  创建名为"hardware"的组(group)。该组依赖于名为"gpio:gpio_dayu800"的依赖项。这个函数的作用是将"hardware"组与"gpio:gpio_dayu800"依赖项相关联。

3.5.新增sample/hardware/gpio目录下的BUILD.gn

  新建gpio目录,并添加vendor/hihope/dayu800/sample/hardware/gpio/BUILD.gn文件,输入以下内容:

  1 import("//build/ohos.gni")2 import("//build/ohos/ndk/ndk.gni")34 ohos_executable("gpio_dayu800") {5  sources = [6   "main.c",7   "gpio_dayu800.c"8  ]910  include_dirs = [ "//commonlibrary/c_utils/base/include" ]1112  external_deps = [13   "c_utils:utils",14   "hilog_native:libhilog",15  ]1617  install_images = [ "system" ]18  part_name = "product_dayu800"19 }

  定义名为gpio_dayu800的可执行文件目标。该目标包含了两个源文件main.c和gpio_dayu800.c,并指定了包含目录//commonlibrary/c_utils/base/include。该目标依赖于外部库c_utils:utils和hilog_native:libhilog。最后,它指定了将生成的可执行文件安装到system镜像,并将该目标归属于product_dayu800部分。

3.6.新增sample/hardware/gpio目录下文件gpio_dayu800.c和gpio_dayu800.h

  创建vendor/hihope/dayu800/sample/hardware/gpio/gpio_dayu800.c文件,内容如下:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include "hilog/log.h"
#include "securec.h"
#include "gpio_dayu800.h"int DAYU800_GPIO_Export(int gpioNum, int bExport)
{int ret = -1;char buffer[256] = {0};if (bExport) {(void) snprintf_s(buffer, sizeof(buffer), sizeof(buffer), "echo %d > %s", gpioNum, DAYU800_GPIO_EXPORT);} else {(void) snprintf_s(buffer, sizeof(buffer), sizeof(buffer), "echo %d > %s", gpioNum, DAYU800_GPIO_UNEXPORT);}sighandler_t old_handler;old_handler = signal(SIGCHLD, SIG_DFL);ret = system(buffer);if (ret < 0) {HILOG_ERROR(LOG_CORE, "set gpio%{public}d %{public}s failed", gpioNum, bExport == 1 ? "export" : "unexport");return DAYU800_GPIO_ERR;}(void) signal(SIGCHLD, old_handler);return ret;
}int DAYU800_GPIO_SetDirection(int gpioNum, int direction)
{int ret_sprintf_s = -1;// check gpio export or notchar gpio_file_name[128];(void) memset_s(gpio_file_name, sizeof(gpio_file_name), 0, sizeof(gpio_file_name));ret_sprintf_s = snprintf_s(gpio_file_name, sizeof(gpio_file_name), sizeof(gpio_file_name), "%s%d/direction",DAYU800_GPIO_PEX, gpioNum);if (ret_sprintf_s != 0) {}if (access(gpio_file_name, F_OK) != 0) {HILOG_ERROR(LOG_CORE, "gpio%{public}d not export", gpioNum);return DAYU800_GPIO_NOT_EXPROT_ERROR;}// set gpio directionFILE *fp = NULL;fp = fopen(gpio_file_name, "r+");if (fp == NULL) {HILOG_ERROR(LOG_CORE, "open %{public}s%{public}d/direction failed", DAYU800_GPIO_PEX, gpioNum);return DAYU800_GPIO_ERR;}if (direction == DAYU800_GPIO_DIRECTION_IN) {fprintf(fp, "%s", "in");} else if (direction == DAYU800_GPIO_DIRECTION_OUT) {fprintf(fp, "%s", "out");}(void) fclose(fp);fp = NULL;return 0;
}int DAYU800_GPIO_SetValue(int gpioNum, int value)
{int ret_sprintf_s = -1;// check gpio export or notchar gpio_file_name[128];(void) memset_s(gpio_file_name, sizeof(gpio_file_name), 0, sizeof(gpio_file_name));ret_sprintf_s = snprintf_s(gpio_file_name, sizeof(gpio_file_name), sizeof(gpio_file_name), "%s%d/value",DAYU800_GPIO_PEX, gpioNum);if (ret_sprintf_s != 0) {}if (access(gpio_file_name, F_OK) != 0) {HILOG_ERROR(LOG_CORE, "gpio%{public}d not export", gpioNum);return DAYU800_GPIO_NOT_EXPROT_ERROR;}// set gpio valueFILE *fp = NULL;fp = fopen(gpio_file_name, "r+");if (fp == NULL) {HILOG_ERROR(LOG_CORE, "open %{public}s%{public}d/value failed", DAYU800_GPIO_PEX, gpioNum);return DAYU800_GPIO_ERR;}if (value == DAYU800_GPIO_LOW_LEVE) {fprintf(fp, "%s", "0");} else if (value == DAYU800_GPIO_HIGH_LEVE) {fprintf(fp, "%s", "1");}(void) fclose(fp);fp = NULL;return 0;
}int DAYU800_GPIO_IsExport(int gpioNum, int *value)
{int ret_sprintf_s = -1;if (value == NULL) {return DAYU800_GPIO_ERR;}// check gpio export or notchar gpio_file_name[128];(void) memset_s(gpio_file_name, sizeof(gpio_file_name), 0, sizeof(gpio_file_name));ret_sprintf_s = snprintf_s(gpio_file_name, sizeof(gpio_file_name), sizeof(gpio_file_name), "%s%d/value",DAYU800_GPIO_PEX, gpioNum);if (ret_sprintf_s != 0) {}if (access(gpio_file_name, F_OK) != 0) {HILOG_INFO(LOG_CORE, "gpio%{public}d not export", gpioNum);*value = DAYU800_GPIO_NOT_EXPORT;} else {*value = DAYU800_GPIO_EXPORTED;}return 0;
}int DAYU800_GPIO_GetDirection(int gpioNum, int *value)
{int ret = 0;int ret_sprintf_s = -1;if (value == NULL) {return DAYU800_GPIO_ERR;}// check gpio export or notchar gpio_file_name[128];(void) memset_s(gpio_file_name, sizeof(gpio_file_name), 0, sizeof(gpio_file_name));ret_sprintf_s = snprintf_s(gpio_file_name, sizeof(gpio_file_name), sizeof(gpio_file_name), "%s%d/direction",DAYU800_GPIO_PEX, gpioNum);if (ret_sprintf_s != 0) {}if (access(gpio_file_name, F_OK) != 0) {HILOG_ERROR(LOG_CORE, "gpio%{public}d not export", gpioNum);return DAYU800_GPIO_NOT_EXPROT_ERROR;}// get gpio directionFILE *fp = NULL;char buffer[20] = {0};fp = fopen(gpio_file_name, "r");if (fp == NULL) {HILOG_ERROR(LOG_CORE, "read %{public}s%{public}d/direction failed", DAYU800_GPIO_PEX, gpioNum);return DAYU800_GPIO_ERR;}(void) fread(buffer, sizeof(buffer), 1, fp);(void) fclose(fp);fp = NULL;if (strstr(buffer, "out") != NULL) {*value = DAYU800_GPIO_DIRECTION_OUT;} else if (strstr(buffer, "in") != NULL) {*value = DAYU800_GPIO_DIRECTION_IN;} else {ret = DAYU800_GPIO_ERR;}return ret;
}int DAYU800_GPIO_GetValue(int gpioNum, int *value)
{int ret = 0;int ret_sprintf_s = -1;if (value == NULL) {return DAYU800_GPIO_ERR;}// check gpio export or notchar gpio_file_name[128];(void) memset_s(gpio_file_name, sizeof(gpio_file_name), 0, sizeof(gpio_file_name));ret_sprintf_s = snprintf_s(gpio_file_name, sizeof(gpio_file_name), sizeof(gpio_file_name), "%s%d/value",DAYU800_GPIO_PEX, gpioNum);if (ret_sprintf_s != 0) {}if (access(gpio_file_name, F_OK) != 0) {HILOG_ERROR(LOG_CORE, "gpio%{public}d not export", gpioNum);return DAYU800_GPIO_NOT_EXPROT_ERROR;}// get gpio valueFILE *fp = NULL;char buffer[20] = {0};fp = fopen(gpio_file_name, "r");if (fp == NULL) {HILOG_ERROR(LOG_CORE, "read %{public}s%{public}d/value failed", DAYU800_GPIO_PEX, gpioNum);return DAYU800_GPIO_ERR;}(void) fread(buffer, sizeof(buffer), 1, fp);(void) fclose(fp);fp = NULL;if (strstr(buffer, "0") != NULL) {*value = DAYU800_GPIO_LOW_LEVE;} else if (strstr(buffer, "1") != NULL) {*value = DAYU800_GPIO_HIGH_LEVE;} else {ret = DAYU800_GPIO_ERR;}return ret;
}

  创建vendor/hihope/dayu800/sample/hardware/gpio/gpio_dayu800.h文件,内容如下:

#ifndef __DAYU800_GPIO_H__
#define __DAYU800_GPIO_H__#define DAYU800_GPIO_EXPORT "/sys/class/gpio/export"
#define DAYU800_GPIO_UNEXPORT "/sys/class/gpio/unexport"
#define DAYU800_GPIO_PEX "/sys/class/gpio/gpio"// hilog
#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0
#define LOG_TAG "GPIO_DAYU800"// gpios
#define DAYU800_GPI0_1_3 427 /* IO1_3 */
#define DAYU800_GPI0_1_4 428 /* IO1_4 */
#define DAYU800_GPI0_1_5 429 /* IO1_5 */
#define DAYU800_GPI0_1_6 430 /* IO1_6 */// direction
#define DAYU800_GPIO_DIRECTION_IN 0
#define DAYU800_GPIO_DIRECTION_OUT 1// is export
#define DAYU800_GPIO_NOT_EXPORT 0
#define DAYU800_GPIO_EXPORTED 1// errno
#define DAYU800_GPIO_ERR (-1)
#define DAYU800_GPIO_NOT_EXPROT_ERROR (-2)// value high - low level
#define DAYU800_GPIO_LOW_LEVE 0
#define DAYU800_GPIO_HIGH_LEVE 1/*** set gpio export* @param gpioNum gpioNum* @param bExport export,0:not export 1:export*/
int DAYU800_GPIO_Export(int gpioNum, int bExport);/*** set gpio direction* @param gpioNum gpioNum* @param direction direction,0:in 1:out*/
int DAYU800_GPIO_SetDirection(int gpioNum, int direction);/*** set gpio value* @param gpioNum gpioNum* @param value value,0:low 1:high*/
int DAYU800_GPIO_SetValue(int gpioNum, int value);/*** check gpio export or not* @param gpioNum gpioNum* @param *value export,0:not export 1:exported*/
int DAYU800_GPIO_IsExport(int gpioNum, int *value);/*** get gpio direction* @param gpioNum gpioNum* @param *value direction,0:in 1:out*/
int DAYU800_GPIO_GetDirection(int gpioNum, int *value);/*** get gpio value* @param gpioNum gpioNum* @param *value value,0:low 1:high*/
int DAYU800_GPIO_GetValue(int gpioNum, int *value);#endif /* __DAYU800_GPIO_H__ */

  以上函数提供了对Dayu800开发板GPIO的控制,包括导出、设置方向、设置值、检查导出状态、获取方向和获取值等操作。用于管理Dayu800GPIO的C函数库。以下是每个函数的功能解释:

  • DAYU800_GPIO_Export 函数用于导出或取消导出GPIO。根据输入的bExport参数,函数将构建一个命令行字符串来执行导出或取消导出操作。如果操作成功,函数返回0,否则返回错误代码。

  • DAYU800_GPIO_SetDirection 函数用于设置GPIO的方向。首先,函数检查GPIO是否已导出。然后,它打开GPIO的方向文件,并根据输入的direction参数设置为输入或输出。

  • DAYU800_GPIO_SetValue 函数用于设置GPIO的值。首先,函数检查GPIO是否已导出。然后,它打开GPIO的值文件,并根据输入的value参数设置为低电平或高电平。

  • DAYU800_GPIO_IsExport 函数用于检查GPIO是否已导出。它构建GPIO的值文件路径并检查该文件是否存在。根据检查结果,函数通过value参数返回导出状态。

  • DAYU800_GPIO_GetDirection 函数用于获取GPIO的方向。首先,函数检查GPIO是否已导出。然后,它打开GPIO的方向文件并读取方向值。根据读取的结果,函数通过value参数返回方向值。

  • DAYU800_GPIO_GetValue 函数用于获取GPIO的值。首先,函数检查GPIO是否已导出。然后,它打开GPIO的值文件并读取值。根据读取的结果,函数通过value参数返回值。

3.7.新增sample/hardware/gpio目录下的main.c

  创建vendor/hihope/dayu800/sample/hardware/gpio/main.c文件,输入以下内容:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>#include "gpio_dayu800.h"int main(int argc, char **argv)
{int gpioNum = DAYU800_GPI0_1_3;int bExport = DAYU800_GPIO_EXPORTED;int direction = DAYU800_GPIO_DIRECTION_OUT;int value = DAYU800_GPIO_HIGH_LEVE;int getValue = -1;// 检查参数数量以确保至少提供了预期的参数数量if (argc < 2) {printf("Usage 1: %s <gpioNum> \n", argv[0]);printf("Usage 2: %s <gpioNum> <value>\n", argv[0]);printf("Usage 3: %s <gpioNum> <value> <direction>\n", argv[0]);return DAYU800_GPIO_ERR;}// 判断是否有输入参数,如有,则赋值指定gpio口if (argv[1] != NULL) {getValue = atoi(argv[1]);if (getValue >= DAYU800_GPI0_1_3 && getValue <= DAYU800_GPI0_1_6) {gpioNum = getValue;} else {printf("please input the gpioNum between 427 and 430.\n");return DAYU800_GPIO_ERR;}}// 判断gpio口是否已经导出,如未导出则执行对应函数DAYU800_GPIO_IsExport(gpioNum, &getValue);if (getValue == DAYU800_GPIO_NOT_EXPORT) {DAYU800_GPIO_Export(gpioNum, bExport);}if (argc == 2) {// 设置gpio口值取反DAYU800_GPIO_GetValue(gpioNum, &getValue);if(getValue == DAYU800_GPIO_LOW_LEVE){value = DAYU800_GPIO_HIGH_LEVE;}else{value = DAYU800_GPIO_LOW_LEVE;}printf("gpioNum:[%d], curvalue:[%d] setvalue:[%d]\n", gpioNum, getValue,value);}if (argc >=3 && argc <= 4) {if (argv[2] != NULL) {//读取GPIO口设定值getValue = atoi(argv[2]);if (getValue >= DAYU800_GPIO_LOW_LEVE && getValue <= DAYU800_GPIO_HIGH_LEVE) {value = getValue;} else {printf("please input the gpio value 0 (low)or 1 (high).\n");return DAYU800_GPIO_ERR;}}}if (argc == 4) {if (argv[3] != NULL) {//读取GPIO口输入或输出设定getValue = atoi(argv[3]);if (getValue >= DAYU800_GPIO_DIRECTION_IN && getValue <= DAYU800_GPIO_DIRECTION_OUT) {direction = getValue;} else {printf("please input the gpio direction 0 (in)or 1 (out).\n");return DAYU800_GPIO_ERR;}}}// 设置gpio口为输入或输出模式DAYU800_GPIO_SetDirection(gpioNum, direction);// 设置gpio口电平高低DAYU800_GPIO_SetValue(gpioNum, value);// 获取对应gpio口的模式并打印DAYU800_GPIO_GetDirection(gpioNum, &getValue);printf("gpioNum:[%d], direction:[%d]\n", gpioNum, getValue);// 获取对应gpio口的电平值并打印DAYU800_GPIO_GetValue(gpioNum, &getValue);printf("gpioNum:[%d], Value:[%d]\n", gpioNum, getValue);return 0;
}

  以上函数实现了是用指令对Dayu800开发板的GPIO引脚的操作,根据输入参数的数量和值,函数执行不同的操作,并在终端打印出相应的信息。支持的指令格式如下:

Usage 1: gpio_dayu800 <gpioNum> 
Usage 2: gpio_dayu800 <gpioNum> <value>
Usage 3: gpio_dayu800 <gpioNum> <value> <direction>

3.8.编译代码

#全量编译
./build.sh --product-name dayu800 --gn-args full_mini_debug=false --ccache
编译完成后可以直接烧录out/dayu800/packages/phone/images下生成的档案。#单模块编译
#前提是之前已全量编译过才可以使用单模块编译指令
./build.sh --product-name dayu800 --ccache --build-target product_dayu800
单模块编译后生成bin文件在out/dayu800/product_dayu800/product_dayu800/目录下的gpio_dayu800

3.9.hdc 调试

  将 gpio_dayu800推送到开发板,进入hdc工具所在目录,将编译生成的gpio_dayu800拷贝到hdc所在目录,开发板通过Type-C数据线连接到电脑,运行windows自带的“命令提示符”(cmd)窗口

#重新挂载DAYU800开发板的文件系统(以读写权限挂载)
hdc shell mount -o remount,rw /   #推送到DAYU800开发板/system/bin/目录
hdc file send gpio_dayu800  /system/bin/

  在DAYU800开发板上运行测试程序,使用hdc shell指令进入到开发板终端

hdc shell#接着运行测试指令:
gpio_dayu800 428
gpio_dayu800 429
gpio_dayu800 430
gpio_dayu800 428 0 1  //关灯
gpio_dayu800 428 1 1  //开灯

refer to

  • https://blog.csdn.net/lxs_vip/article/details/139391687
  • https://wiki.sipeed.com/hardware/zh/lichee/th1520/lpi4a/6_peripheral.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/24051.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win11 24h2 远程桌面 频繁断开 已失去连接 2025

一、现象 Windows11自升级2025年2月补丁后版本号为系统版本是26100.3194&#xff0c;远程桌面频繁断开连接&#xff0c;尝试连接&#xff0c;尤其在连接旧的server2012 二、临时解决方案 目前经测试&#xff0c;在组策略中&#xff0c;远程桌面连接客户端&#xff0c;关闭客户…

rust学习笔记6-数组练习704. 二分查找

上次说到rust所有权看看它和其他语言比有什么优势&#xff0c;就以python为例 # Python3 def test():a [1, 3, -4, 7, 9]print(a[4])b a # 所有权没有发生转移del b[4]print(a[4]) # 由于b做了删除&#xff0c;导致a再度访问报数组越界if __name__ __main__:test() 运行结…

Windows安装NVIDIA显卡CUDAD调用GPU,适用于部署deepseek r1

显卡、显卡驱动、CUDA之间的关系 显卡&#xff1a;&#xff08;GPU&#xff09;&#xff0c;主流是NVIDIA的GPU&#xff0c;因为深度学习本身需要大量计算。GPU的并行计算能力&#xff0c;在过去几年里恰当地满足了深度学习的需求。AMD的GPU基本没有什么支持&#xff0c;可以不…

基于无人机遥感的烟株提取和计数研究

一.研究的背景、目的和意义 1.研究背景及意义 烟草作为我国重要的经济作物之一&#xff0c;其种植面积和产量的准确统计对于烟草产业的发展和管理至关重要。传统的人工烟株计数方法存在效率低、误差大、难以覆盖大面积烟田等问题&#xff0c;已无法满足现代烟草种植管理的需求…

《深度学习实战》第3集:循环神经网络(RNN)与序列建模

第3集&#xff1a;循环神经网络&#xff08;RNN&#xff09;与序列建模 引言 在深度学习领域&#xff0c;处理序列数据&#xff08;如文本、语音、时间序列等&#xff09;是一个重要的研究方向。传统的全连接网络和卷积神经网络&#xff08;CNN&#xff09;难以直接捕捉序列中…

【前沿探索篇七】【DeepSeek自动驾驶:端到端决策网络】

第一章 自动驾驶的"感官革命":多模态神经交响乐团 1.1 传感器矩阵的量子纠缠 我们把8路摄像头+4D毫米波雷达+128线激光雷达的融合称为"传感器交响乐",其数据融合公式可以简化为: def sensor_fusion(cam, radar, lidar):# 像素级特征提取 (ResNet-152…

可狱可囚的爬虫系列课程 13:Requests使用代理IP

一、什么是代理 IP 代理 IP&#xff08;Proxy IP&#xff09;是一个充当“中间人”的服务器IP地址&#xff0c;用于代替用户设备&#xff08;如电脑、手机等&#xff09;直接与目标网站或服务通信。用户通过代理IP访问互联网时&#xff0c;目标网站看到的是代理服务器的IP地址&…

https:原理

目录 1.数据的加密 1.1对称加密 1.2非对称加密 2.数据指纹 2.1数据指纹实际的应用 3.数据加密的方式 3.1只使用对称加密 3.2只使用非对称加密 3.3双方都使用对称加密 3.4非对称加密和对称加密一起使用 4.中间人攻击 5.CA证书 5.1什么是CA证书 CA证书的验证 6.https的原理 1.数据…

Github项目管理之 其余分支同步main分支

文章目录 方法&#xff1a;通过 Pull Request 同步分支1. **创建一个从 main 到目标分支的 Pull Request**2. **合并 Pull Request** 注意事项总结 在 GitHub 网页上&#xff0c;你可以通过 Pull Request 的方式将一个分支&#xff08;例如 main 分支&#xff09;的修改同步到…

Aseprite绘画流程案例(5)——花盆

1.最终图片效果 参考素材来源于&#xff1a;手绘像素画第三课&#xff1a;像素画盆花示范&#xff08;无参考图&#xff09;_哔哩哔哩_bilibili 2.流程 1.新建画布40X27的画布&#xff0c;打开显示网格&#xff0c;背景色为白色 2.画出梯形的盆 3.给盆进行亮暗对比上色 4.添…

【模板】csdn markdown语法演示

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

【Python系列】PYTHONUNBUFFERED=1的作用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Adobe After Effects的动画制作

作者&#xff1a;余佳琪 目录 一、 前言 二、 可动骨骼的选择 三、 运动曲线的设置 四、 图层的选定与应用 五、 插件的应用&#xff08;阴影&#xff0c;高光&#xff0c;特效&#xff09; 六、 导出 一、 前言 在当今世界&#x…

可狱可囚的爬虫系列课程 14:10 秒钟编写一个 requests 爬虫

一、前言 当重复性的工作频繁发生时&#xff0c;各种奇奇怪怪提高效率的想法就开始萌芽了。当重复代码的模块化封装已经不能满足要求的时候&#xff0c;更高效的方式就被揭开了神秘的面纱。本文基于这样的想法&#xff0c;来和大家探讨如何 10 秒钟编写一个 requests 爬虫程序。…

QNX上如何抓tracelogger日志

背景 因QNX侧 QVM的分析CPU负载问题在android侧使用trace无法分析&#xff0c;故QNX侧的CPU负载问题需要用到tracelogger日志分析。 例如&#xff1a;使用hogs -l 42|grep qvm 中发现qvm的cpu负载 30%多 但是使用trace日志在Perfetto又查不到qvm信息&#xff0c;则需要抓取qn…

DeepSeek开源周 Day02:从DeepEP开源趋势重新审视大模型Infra

DeepEP 今天DeepSeek开源周第二天&#xff0c;开放了DeepEP仓库&#xff0c;属实看了下源码&#xff0c;和昨天FlashMLA一样&#xff0c;C权重&#xff08;包括CUDA&#xff09;还是占据了绝对部分&#xff0c;作为调包侠的我&#xff0c;看到之后望而却步&#xff0c;想看原理…

【Ambari】Ranger KMS

目录 一、Ranger KMS介绍 二、KMS基于Ranger插件安装 一、Ranger KMS介绍 Ranger KMS是把数据存储入后台数据库中。通过Ranger Admin可以集中化管理KMS服务。 Ranger KMS有三个优点 l Key management Ranger admin 提供了创建&#xff0c;更新&#xff0c;删除密钥的Web UI…

055 SpringCache

文章目录 缓存一致性Spring Cachepom.xmlapplication.ymlCubemallProductApplication.javaSpringCache改造三级分类MyCacheConfig.java缓存一致性 缓存一致性 锁 设置过期时间 读写锁 设置过期时间 Spring Cache 1.读模式 缓存穿透&#xff1a;查询一个null数据&#xff0c;…

神卓 S500 组网设备连接交换机的详细步骤

神卓 S500 组网设备连接交换机的详细步骤 神卓 S500 组网设备以其高效、灵活的解决方案&#xff0c;在异地监控组网中发挥着重要作用。本文将详细介绍神卓 S500 组网设备连接交换机的步骤&#xff0c;帮助您轻松实现网络的互联互通。 一、前期准备 确认设备型号与规格&#x…

图像处理案例06 OCR应用

OCR应用 1 OCR读取账单1.1 背景及思路1.2 代码 1 OCR读取账单 1.1 背景及思路 思路 目标是读取图片中账单的信息。首先要截取图片上的账单&#xff0c;考虑到账单并非都是整齐摆放&#xff0c;为了保持算法的通用性&#xff0c;通过透视变换对扣取的账单摆正&#xff0c;然后调…