RK Android11 WiFi模组 AIC8800 驱动移植流程
RK Android WiFi模组 AIC8800 驱动移植流程
- 作者:Witheart
- 更新时间:20250220
概要:本文介绍了基于 AIC8800D40 芯片的 WiFi6 模组 BL-M8800DS2-40 在 RK3568 平台上的驱动移植流程。主要涉及环境搭建、驱动代码分析、设备树修改、驱动编译配置、蓝牙库集成、wpa_supplicant 配置及 WiFi HAL 适配等内容,并提供详细的移植步骤和注意事项。
问题调试在另一篇文章:https://blog.csdn.net/Beihai_Van/article/details/145772085
1. 环境
- WiFi 模组:BL-M8800DS2-40(基于 AIC8800D40 芯片)
- CPU:RK3568
- OS:Android
2. WiFi芯片与WiFi模组的区别
- WiFi 芯片:核心部件,集成射频前端、基带处理器、数字信号处理等功能。
- WiFi 模组:基于 WiFi 芯片的完整无线通信组件,包含天线、外围电路、接口等。
AIC8800 属于 WiFi 芯片,而本次移植的 WiFi 模组是 BL-M8800DS2-40(基于 AIC8800D40)。
WiFi6 模组_必联(LB-LINK)官方网站
3. AIC8800 驱动代码包详解
3.1 驱动代码包结构
厂家送样后,需要获取最新的驱动代码包,并确保版本与模组匹配。驱动代码版本错误可能引发诸多问题。
3.2 Patch 注意事项
在 SDIO\patch\for_Rockchip\3566\Android11 目录下,提供了 Rockchip 平台的移植补丁(更像是移植成功的参考案例,不同wifi芯片还要具体配置),移植过程中需对比 mod 和 orig 文件夹的区别,可利用 git 进行差异分析。
在移植过程中需要注意一个问题:patch 仅仅指示了需要修改哪些文件以及具体的修改方法,但其中的驱动可能并不适用于你手头的模组。原因在于,官方提供的驱动包适用于多款模组,而 patch 仅是其中某款模组的案例,并且官方更新驱动时,并不会同步更新 patch 中的驱动。
因此,在移植时可以参考 patch 进行修改,但对于驱动适配系统的相关配置,一般无需更改。而对于新增的驱动文件,应在
driver_fw
文件夹中查找正确的驱动文件进行添加,而不是直接使用 patch 中的文件。
3.3 Patch 使用方法
在使用 patch 进行移植时,主要是对比 mod
文件夹和 orig
文件夹的区别,然后在你的源码中进行相应的配置修改。直接手动对比可能比较繁琐,因此可以借助 Git 进行对比分析。
3.3.1. 初始化 Git 仓库
首先,在 orig
文件夹中初始化一个 Git 仓库.
接着,找到 mod
相比 orig
新增的文件,通常包含以下三部分:
- 模组固件:
- 主要是厂家编译好的二进制
.bin
文件以及.txt
配置文件。
- 主要是厂家编译好的二进制
- 模组驱动:
- 用于与内核交互,主要是
.c
源码文件,编译后生成.ko
驱动文件。
- 用于与内核交互,主要是
- 模组库:
- 例如
libbt
之类的库,编译后生成.so
共享库文件。
- 例如
3.3.2. 删除 mod
中的新增文件
由于我们只关心 源码的修改内容,而这些新增的二进制文件、驱动和库文件无需对比修改,仅需直接复制,所以应当先删除 mod
中的新增文件
原因:
- 这些新增文件会导致 Git 对比时产生大量无关内容,影响分析。
- 厂商在更新驱动时,不会同步更新
patch
中的驱动,直接使用patch
提供的驱动可能会导致 bug。
(别问为什么知道的,踩坑经验)
3.3.3. 进行 Git 对比
删除新增文件后,将 mod
文件夹的内容 覆盖 orig
,然后使用 Git 进行对比:
⚠ VSCode 的 Git 对比 Bug
坑点提醒:
VSCode 的 Git 对比窗口 在路径长度超过 219 个字符 时,不会显示差异,容易导致遗漏修改。参考 Issue:
Git diff does not show files with long paths in Source Control View (Windows) #240770
4 设备树(DTS)修改
此处主要是参考RK官方文档去修改
01、Linux\Linux\Wifibt\Rockchip_Developer_Guide_Linux_WIFI_BT_CN.pdf
02、Android\android\wifi\Rockchip_Introduction_WIFI_Configuration_CN&EN.pdf
02、Android\common\MMC\Rockchip_Developer_Guide_SDMMC_SDIO_eMMC_CN.pdf
4.1 蓝牙部分
&wireless_bluetooth {compatible = "bluetooth-platdata";clocks = <&rk809 1>;clock-names = "ext_clock";uart_rts_gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_LOW>;pinctrl-names = "default", "rts_gpio";pinctrl-0 = <&uart8m0_rtsn>;pinctrl-1 = <&uart8_gpios>;BT,reset_gpio = <&gpio3 RK_PD5 GPIO_ACTIVE_LOW>;status = "okay";
};wireless-bluetooth {uart8_gpios: uart8-gpios {rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;};
};
- 这里比较重要的是BT,reset_gpio,这个模块的34脚,PWR_BT,根据描述来看,高电平时蓝牙部分关闭,低电平时蓝牙部分开启
- 但是此部分的配置不一定是最终生效的版本,最终还要看驱动里是怎么处理的,有的驱动会对电平作反相处理,所以这部分可以GPIO_ACTIVE_LOW和GPIO_ACTIVE_HIGH都试试看
- UART 配置: 确保蓝牙与 CPU 通过 UART8 进行通信。
4.2 WiFi 部分
sdio_pwrseq: sdio-pwrseq {compatible = "mmc-pwrseq-simple";clocks = <&rk809 1>;clock-names = "ext_clock";pinctrl-names = "default";pinctrl-0 = <&wifi_enable_h>;/** On the module itself this is one of these (depending* on the actual card populated):* - SDIO_RESET_L_WL_REG_ON* - PDN (power down when low)*/post-power-on-delay-ms = <200>;reset-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_LOW>;
};
重点配置 WiFi reset-gpios,确保正确的电源控制。
wireless_wlan: wireless-wlan {compatible = "wlan-platdata";rockchip,grf = <&grf>;wifi_chip_type = "AIC8800";status = "okay";
};
此处的WiFi芯片名称的配置,应该和frameworks\opt\net\wifi\libwifi_hal\rk_wifi_ctrl.cpp
这个文件中的
static wifi_device supported_wifi_devices[]中配置的名称一致(至少前三个字符要为AIC)
&sdmmc2 {max-frequency = <150000000>;supports-sdio;bus-width = <4>;disable-wp;cap-sd-highspeed;cap-sdio-irq;keep-power-in-suspend;mmc-pwrseq = <&sdio_pwrseq>;non-removable;pinctrl-names = "default";pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;sd-uhs-sdr104;status = "okay";
};
- sd-uhs-sdr104表示支持sdio3.0
5. 驱动部分
-
添加驱动文件,也就是
SDIO\driver_fw\driver\aic8800
下所有文件添加到
kernel\drivers\net\wireless\aic8800
-
然后在同级目录下的mk文件中添加编译选项,通过CONFIG_AIC_WLAN_SUPPORT宏定义控制是否编译aic8800/目录下的内容
kernel\drivers\net\wireless\Makefile
obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800/
- 并且在同级目录下的kconfig中,引用aic8800/目录下的Kconfig文件,用于增加menuconfig中的aic8800驱动编译选项
source "drivers/net/wireless/aic8800/Kconfig"
- 配置内核编译配置文件kernel\arch\arm64\configs\rockchip_defconfig,请修改你实际上应用的内核编译配置文件
CONFIG_AIC_WLAN_SUPPORT=y
CONFIG_AIC_FW_PATH="/vendor/etc/firmware"
CONFIG_AIC8800_WLAN_SUPPORT=m
-
- CONFIG_AIC_WLAN_SUPPORT用于控制编译这个驱动
- CONFIG_AIC_FW_PATH用于配置模组固件存放的位置,固件最后会被复制到配置的这个位置
- CONFIG_AIC8800_WLAN_SUPPORT说明驱动将不会被编译进内核,而是以模块的形式动态插入(如果是以模块的形式动态插入,内核将根据sdio读到的vid和pid匹配不同的模块进行加载)
-
在
vendor\rockchip\common\wifi\wifi.mk
文件中,添加编译出来的ko文件的路径,因为是动态加载ko文件的,所以ko文件编译出来后,将被复制到/vendor/lib/modules
路径下进行动态加载
AIC_WIFI_KO_FILES := $(shell find $(TOPDIR)kernel/drivers/net/wireless/aic8800 -name "*.ko" -type f)
BOARD_VENDOR_KERNEL_MODULES += \
$(foreach file, $(AIC_WIFI_KO_FILES), $(file))
此处的配置用于找到编译出的ko文件
- 配置Android 启动时用于加载内核模块(.ko) 的配置文件
device\rockchip\common\init.insmod.cfg
加入
insmod /vendor/lib/modules/aic8800_bsp.ko
- 最终会编译出三个ko文件,分别是
aic8800_bsp.ko aic8800_btlpm.ko aic8800_fdrv.ko -
- aic8800_bsp用于模组的初始化等基础功能
- aic8800_fdrv用于WiFi
- aic8800_btlpm用于蓝牙
- 移植到RK Android平台时,实际上只加载aic8800_bsp.ko,aic8800_fdrv.ko
6. 蓝牙库 libbt
libbt用于完成对蓝牙模块硬件初始化与控制。
6.1 添加蓝牙库文件
将 driver_fw\aic\libbt\8800 目录下所有文件添加到 hardware\aic\aicbt\libbt 目录。
6.2 配置编译 libbt
- 在libbt同级目录下添加Android.mk,如果BOARD_HAVE_BLUETOOTH_AIC被配置了,那么子目录下所有makefile都生效
ifeq ($(BOARD_HAVE_BLUETOOTH_AIC),true)
LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)
endif
而BOARD_HAVE_BLUETOOTH_AIC在device\rockchip\common\wifi_bt_common.mk这个mk文件中定义
BOARD_HAVE_BLUETOOTH_AIC := true
- 同样的,在libbt同级目录下添加aicbt.mk文件
CUR_PATH := hardware/aic/aicbtBOARD_HAVE_BLUETOOTH := truePRODUCT_PACKAGES += \libbt-vendor-aic
PRODUCT_PACKAGES += libbt-vendor-aic 定义了 libbt-vendor-aic 这个包,用于指定需要编译并包含到最终镜像
注意,此处有一个坑点,需要保证libbt中Android.mk中的LOCAL_MODULE与PRODUCT_PACKAGES一致,原厂的patch由于没有更新,这两者不一致
hardware\aic\aicbt\libbt\Android.mkLOCAL_MODULE := libbt-vendor-aic
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_OWNER := aic
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE 是用于定义模块名称,也就是最终会编译出libbt-vendor-aic.so这个模块。
7. wpa_supplicant 配置
7.1 wpa_supplicant 概念
wpa_supplicant 是一个用于管理 WiFi 连接的用户空间守护进程,主要负责:
- 处理 WPA/WPA2 认证
- 管理 WiFi 连接(扫描、连接、断开)
- 支持 WiFi Direct(P2P)
- 通过 socket 接口与 Android WiFi 框架交互
7.2 wpa_supplicant 具体配置
配置aic模块的wpa配置,设置aic模块的启动参数
device\rockchip\common\wpa_config.txt
添加
[aic]
/vendor/bin/hw/wpa_supplicant
-O/data/vendor/wifi/wpa/sockets
-puse_p2p_group_interface=1
-g@android:wpa_wlan0
-
[aic]
:表示该配置适用于 AIC WiFi 模块。/vendor/bin/hw/wpa_supplicant
:指定 wpa_supplicant 的可执行文件路径。-O/data/vendor/wifi/wpa/sockets
:指定 wpa_supplicant 使用的 socket 目录,通常用于与其他组件(如 hostapd 或 Android WiFi 框架)通信。-puse_p2p_group_interface=1
:启用 P2P 组接口支持,允许 WiFi Direct 功能。-g@android:wpa_wlan0
:定义全局控制接口,@android:wpa_wlan0 允许 Android 通过 wpa_supplicant 进行 WiFi 控制
设置加载wpa_config.txt中的配置
external\wpa_supplicant_8\wpa_supplicant\main.c
#define AIC_MODULE_NAME "[aic]"else if (0 == strncmp(wifi_type, "AIC", 3)) {wpa_printf(MSG_INFO,"Start aic_wpa_supplicant\n");ret = read_wpa_param_config(AIC_MODULE_NAME,argv[1]);
}
WiFi芯片类型前缀为AIC时,加载对应的aic的wpa_supplicant参数。
8. WiFi HAL 配置
这部分主要是通过配置vid:pid,选择加载不同的库。
8.1 动态加载原理
sdio握手成功后,就会读到vid:pid,将读到的数值与已经配置vid:pid比较,动态加载不同的库
8.2 具体配置
vid:pid配置
frameworks\opt\net\wifi\libwifi_hal\rk_wifi_ctrl.cpp
supported_wifi_devices 结构体数组中添加WiFi名称以及对应的vid:pid
{"AIC8800", "5449:0145"},
- 这里又有一个坑点,patch中提供的这个vid:pid不适用于我这个模组,需要具体配置。
- 获取真正的vid:pid有两种方式,一种是如果WiFi模组正常上电且sdio握手成功,那么是可以通过读/sys/bus/sdio/devices下的设备目录下的uevent文件得到的
rk3568_HW:/ # cat /sys/bus/sdio/devices/
mmc3:390b:1/ mmc3:390b:2/
rk3568_HW:/ # cat /sys/bus/sdio/devices/mmc3\:390b\:1/uevent
DRIVER=aicwf_sdio
SDIO_CLASS=07
SDIO_ID=C8A1:0082
MODALIAS=sdio:c07vC8A1d0082
rk3568_HW:/ # cat /sys/bus/sdio/devices/mmc3\:390b\:2/uevent
DRIVER=aicbsp_sdio
SDIO_CLASS=07
SDIO_ID=C8A1:0182
MODALIAS=sdio:c07vC8A1d0182
这个WiFi模组扫卡成功后可以读到两个mmc设备,分别是mmc3:390b:1/ mmc3:390b:2/,
读取到的mmc3:390b:1设备的vid:pid为C8A1:0082,那么增加这个vid:pid到rk_wifi_ctrl.cpp中即可。
- 二是直接向厂家询问,或在驱动包中寻找
接下来是检测流程,调用check_wifi_chip_type_string(wifi_type)函数,尝试获取wifi芯片类型,保存到wifi_type
frameworks\opt\net\wifi\libwifi_hal\rk_wifi_ctrl.cpp
int check_wifi_chip_type_string(char *type)
{if (identify_sucess == -1) {if (get_wifi_device_id(SDIO_DIR, PREFIX_SDIO) == 0)PLOG(DEBUG) << "SDIO WIFI identify sucess";else if (get_wifi_device_id(USB_DIR, PREFIX_USB) == 0)PLOG(DEBUG) << "USB WIFI identify sucess";else if (get_wifi_device_id(PCIE_DIR, PREFIX_PCIE) == 0)PLOG(DEBUG) << "PCIE WIFI identify sucess";else {PLOG(DEBUG) << "maybe there is no usb wifi or sdio or pcie wifi,set default wifi module Brocom APXXX";strcpy(recoginze_wifi_chip, "APXXX");identify_sucess = 1 ;}}strcpy(type, recoginze_wifi_chip);PLOG(ERROR) << "check_wifi_chip_type_string : " << type;return 0;
}
还未进行识别时,identify_sucess为-1,此时开始使用get_wifi_device_id()获取设备id,依次尝试sdio、usb、pcie设备
get_wifi_device_id()函数中,通过读uevent获取vid:pid,然后用一个for循环,比较已经在supported_wifi_devices中添加的设备vid:pid与读到的vid:pid,有相符的,就将对应的wifi芯片名称复制到recoginze_wifi_chip中,get_wifi_device_id()执行完成之后,会将recoginze_wifi_chip复制到type中,也就是wifi_type。
接下来配置动态加载不同的库
- 在
frameworks\opt\net\wifi\libwifi_hal\wifi_hal_common.cpp
中,有一个wifi_load_driver()
函数,调用了check_wifi_chip_type_string(wifi_type)
函数,尝试获取wifi芯片类型wifi_type
- 需要添加wifi ko驱动的路径,以及驱动与wifi类型的对应
wifi_hal_common.cpp
#define AIC8800_DRIVER_MODULE_PATH WIFI_MODULE_PATH"aic8800_fdrv.ko"
#define AIC8800_DRIVER_MODULE_NAME "aic8800_fdrv"
wifi_ko_file_name module_list[] ={{"AIC8800", AIC8800_DRIVER_MODULE_NAME, AIC8800_DRIVER_MODULE_PATH, UNKKOWN_DRIVER_MODULE_ARG},
}
- 定义蓝牙使用的库
在hardware\interfaces\bluetooth\1.0\default\vendor_interface.cc
中
static const char* VENDOR_AIC_LIBRARY_NAME = "libbt-vendor-aic.so";
然后根据wifi芯片类型,得到要加载的库的名称
if ((0 == strncmp(wifi_type, "AIC", 3))) {ALOGE("%s try to open %s \n", __func__, VENDOR_AIC_LIBRARY_NAME);strcpy(vendor_lib_name, VENDOR_AIC_LIBRARY_NAME);
}
根据这个名称进行加载
lib_handle_ = dlopen(vendor_lib_name, RTLD_NOW);
- 根据 Wi-Fi 芯片类型来确定应该使用哪个Wi-Fi 直连(P2P)接口名称
hardware\interfaces\wifi\1.4\default\wifi_chip.cpp
std::string getP2pIfaceName() {std::array<char, PROPERTY_VALUE_MAX> buffer;if (wifi_type[0] == 0) {check_wifi_chip_type_string(wifi_type);}if (0 == strncmp(wifi_type, "AP", 2) || 0 == strncmp(wifi_type, "AIC", 3)) {property_set("vendor.wifi.direct.interface", "p2p-dev-wlan0");property_get("wifi.direct.interface", buffer.data(), "p2p-dev-wlan0");} else {property_set("vendor.wifi.direct.interface", "p2p0");property_get("wifi.direct.interface", buffer.data(), "p2p0");}return buffer.data();
}
注:此处的AP应该是AP系列WiFi芯片的意思
9. 固件添加
-
主要是厂家编译好的二进制 .bin 文件以及 .txt 配置文件。
-
将厂家给的驱动包中
driver_fw\fw
下具体的固件放置在vendor\rockchip\common\wifi\firmware
下。 -
BL-M8800DS2-40
使用driver_fw\fw\aic8800D80
目录下的固件。
至此,驱动配置成功,但是在调试过程中还遇到一些问题,详情见另一篇文章。
相关文章:

RK Android11 WiFi模组 AIC8800 驱动移植流程
RK Android WiFi模组 AIC8800 驱动移植流程 作者:Witheart更新时间:20250220 概要:本文介绍了基于 AIC8800D40 芯片的 WiFi6 模组 BL-M8800DS2-40 在 RK3568 平台上的驱动移植流程。主要涉及环境搭建、驱动代码分析、设备树修改、驱动编译配…...

深度学习-6.用于计算机视觉的深度学习
Deep Learning - Lecture 6 Deep Learning for Computer Vision 简介深度学习在计算机视觉领域的发展时间线 语义分割语义分割系统的类型上采样层语义分割的 SegNet 架构软件中的SegNet 架构数据标注 目标检测与识别目标检测与识别问题两阶段和一阶段目标检测与识别两阶段检测器…...

免费送源码:ava+springboot+MySQL 基于springboot 宠物医院管理系统的设计与实现 计算机毕业设计原创定制
摘 要 在当今社会,宠物已经成为人们生活中不可或缺的一部分,因此宠物健康和医疗问题也备受关注。为了更好地管理宠物医院的日常运营和提供优质的医疗服务,本研究设计并实现了一套基于Spring Boot框架的宠物医院管理系统。这一系统集成了多项功…...

【电机控制器】ESP32-C3语言模型——DeepSeek
【电机控制器】ESP32-C3语言模型——DeepSeek 文章目录 [TOC](文章目录) 前言一、简介二、代码三、实验结果四、参考资料总结 前言 使用工具: 提示:以下是本篇文章正文内容,下面案例可供参考 一、简介 二、代码 #include <Arduino.h&g…...

小型字符级语言模型的改进方向和策略
小型字符级语言模型的改进方向和策略 一、回顾小型字符级语言模型的处理流程 前文我们已经从零开始构建了一个小型字符级语言模型,那么如何改进和完善我们的模型呢?有哪些改进的方向?我们先回顾一下模型的流程: 图1 小型字符级语言模型的处理流程 (1)核心模块交互过程:…...
力扣-贪心-56 合并区间
思路 先按照左区间进行排序,然后初始化left和right,重叠时,更新right,不重叠时,收集区间 代码 class Solution { public:static bool cmp(vector<int> a, vector<int> b){if(a[0] b[0]){return a[1] &…...

vue 3D 翻页效果
<template><view class"swipe-container" touchstart"onTouchStart" touchmove"onTouchMove" touchend"onTouchEnd"><view class"page">初始页</view></view> </template><script&g…...
【系列专栏】银行信息系统研发外包风险管控-08
银行信息系统研发外包风险管控 在金融科技日新月异的当下,银行业务对信息系统的依赖程度与日俱增。为了充分利用外部专业资源,提升研发效率并合理控制成本,许多银行选择将信息系统研发外包。然而,这一策略在带来诸多便利的同时&a…...

[ComfyUI] 【AI】如何获得一张人物图片的优质描述
在使用ComfyUI时,获取一张人物图片的优质英文描述非常重要,尤其是在涉及图像生成、自动化标签和多模态AI任务时。以下是一个简单的流程,可以帮助你快速从一张人物图片中提取出精确且高质量的英文描述。 1. 打开 Hugging Face 网站 首先,您需要访问 Hugging Face 提供的 J…...

深度学习基础--ResNet网络的讲解,ResNet50的复现(pytorch)以及用复现的ResNet50做鸟类图像分类
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 前言 如果说最经典的神经网络,ResNet肯定是一个,这篇文章是本人学习ResNet的学习笔记,并且用pytorch复现了ResNet50&…...
stack,queue,priority_queue学习知识点
容器适配器 在c常用的容器中,有的是以容器迭代器为核心,而有的则以容器适配器为核心。较为常用的就包括queue和stack。接下来我将简单的以queue和stack的模拟实现介绍其特点。 在以下的模拟实现中,class Con就是我们的容器适配器࿰…...
css特异性,继承性
html <div class"introduce"><div class"title">介绍</div><div class"card-box"><div class"card"><div class"title">管理</div></div></div> </div> scs…...

力扣hot100刷题——11~20
文章目录 11.滑动窗口最大值题目描述思路:滑动窗口单调队列code 12.最小覆盖子串题目描述思路:双指针/滑动窗口哈希code Ⅰcode Ⅱ 13.最大子数组和题目描述思路:dp/贪心code 14.合并区间题目描述思路:贪心code 15.轮转数组题目描…...

R语言Stan贝叶斯空间条件自回归CAR模型分析死亡率多维度数据可视化
全文链接:https://tecdat.cn/?p40424 在空间数据分析领域,准确的模型和有效的工具对于研究人员至关重要。本文为区域数据的贝叶斯模型分析提供了一套完整的工作流程,基于Stan这一先进的贝叶斯建模平台构建,帮助客户为空间分析带来…...

速通HTML
目录 HTML基础 1.快捷键 2.标签 HTML进阶 1.列表 a.无序列表 b.有序列表 c.定义列表 2.表格 a.内容 b.合并单元格 3.表单 a.input标签 b.单选框 c.上传文件 4.下拉菜单 5.文本域标签 6.label标签 7.按钮标签 8.无语义的布局标签div与span 9.字符实体 HTML…...
安装 Milvus Java SDK
本主题介绍如何为 Milvus 安装 Milvus Java SDK。 当前版本的 Milvus 支持 Python、Node.js、GO 和 Java SDK。 要求 Java(8 或更高版本)Apache Maven 或 Gradle/Grails 安装 Milvus Java SDK 运行以下命令安装 Milvus Java SDK。 Apache Maven &…...

云手机如何进行经纬度修改
云手机如何进行经纬度修改 云手机修改经纬度的方法因不同服务商和操作方式有所差异,以下是综合多个来源的常用方法及注意事项: 通过ADB命令注入GPS数据(适用于技术用户) 1.连接云手机 使用ADB工具连接云手机服务器,…...
牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)
文章目录 牛客周赛 Round 82(思维、差分、树状数组、大根堆、前后缀、递归)A. 夹心饼干B. C. 食堂大作战(思维)D. 小苯的排列计数(差分、树状数组)E. 和和(大根堆,前缀和)F. 怎么写线性SPJ &…...
MQTT实现智能家居------2、写MQTT程序的思路
举个最简单的例子: 手机------服务器-------家具 我们这里只看手机和家具的客户端: 手机:1)需要连接服务器 2)需要发布指令给服务器到家里的家具 3)接受来自于家里家具的异常状况 4)保持心…...

大模型面试问题准备
1. BERT的多头注意力为什么需要多头? 为了捕捉不同子空间的语义信息,每个头关注不同的方面,增强模型的表达能力 2. 什么是softmax上下溢出问题? 问题描述: 上溢出:ye^x中,如果x取非常大的正数…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...