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 平台上的驱动移植流程。主要涉及环境搭建、驱动代码分析、设备树修改、驱动编译配…...
【大模型】DeepSeek-RAG 本地化部署与军事情报应用研究报告
【大模型】DeepSeek-RAG 本地化部署与军事情报应用研究报告 一、研究背景二、DeepSeek 本地部署(一)部署环境(二)部署步骤(三)本地化部署流程优化 三、RAG 知识库构建(一)数据预处理…...
Windows PyCharm的python项目移动存储位置后需要做的变更
项目使用的venv虚拟环境,因此项目移动存储位置后需要重新配置python解释器的位置,否则无法识别,若非虚拟环境中运行,则直接移动后打开即可,无需任何配置。 PyCharm版本为2021.3.3 (Professional Edition),其…...
浅棕色人像花卉照片Lr调色,手机滤镜PS+Lightroom预设下载!
调色介绍 提供一系列用于处理浅棕色调人像与花卉照片的后期预设资源,这些预设兼容手机滤镜的 PS 和 Lightroom 软件。其主要作用是令照片达成浅棕色的色调效果,帮助使用者快捷地对人像和花卉照片进行调色处理,无需繁复手动调节参数࿰…...
使用 Python 和 OpenCV 从一组图片生成 MP4 格式的视频
概要 在创建动画、制作幻灯片,从生成的图像数据中导出动态视频时,我们需要将一系列静态图片合成一个视频。 安装依赖 代码需要安装 OpenCV 库。可以通过命令行安装: pip install opencv-python 完整代码 图片尺寸不一时见后文 调整视频…...
POI pptx转图片
前言 ppt页面预览一直是个问题,office本身虽然有预览功能但是收费,一些开源的项目的预览又不太好用,例如开源的:kkfileview pptx转图片 1. 引入pom依赖 我这个项目比较老,使用版本较旧 <dependency><gro…...
全志A133 android10 适配SLM770A 4G模块
一,模块基本信息 1.官方介绍 SLM770A是美格智能最新推出的一款LTE Cat.4无线通讯模组,最大支持下行速率150Mbps及上行速率50Mbps。同时向下兼容现有的3G和2G网络,以确保即使在偏远地区也可以进行网络通信。 SLM770A模组支持分集接收和MIMO技…...
同步异步日志系统-设计模式
六大原则 单⼀职责原则(Single Responsibility Principle) 类的职责应该单⼀,⼀个⽅法只做⼀件事。职责划分清晰了,每次改动到最⼩单位的⽅法或 类。 使⽤建议:两个完全不⼀样的功能不应该放⼀个类中,⼀…...
DP-最长上升子序列
题面: 样例: 思路: 遇到动态规划问题,我们照旧思考两部分,状态表示以及状态计算。这里我们f[N]表示以第i个数结尾的上升子序列的最大值。我们将f[N]划分为若干个部分,因为我们要用到递推思路想办法用前面的…...
Spring Boot 中多线程工具类的配置与使用:基于 YAML 配置文件
文章目录 Spring Boot 中多线程工具类的配置与使用:基于 YAML 配置文件1. 为什么需要多线程工具类?2. 实现步骤2.1 添加依赖2.2 配置线程池参数2.3 创建配置类2.4 创建线程池工具类2.5 使用线程池工具类2.6 测试线程池工具类 3. 配置文件的灵活性4. 总结…...
mac安装Pyspark并连接Mysql
安装Scala, apache-spark, Hadoop brew install scala brew install apache-spark brew install hadoop pip install pyspark注意不要自己另外安装jdk, 会造成版本对不上报错。因为安装apache-spark的过程中会自动安装openjdk。 配置环境变量 JAVA_HOME/opt/homebrew/Cellar…...
【C++第二十章】红黑树
【C第二十章】红黑树 红黑树介绍🧐 红黑树是一种自平衡的二叉搜索树,通过颜色标记和特定规则保持树的平衡性,从而在动态插入、删除等操作中维持较高的效率。它的最长路径不会超过最短路径的两倍,它的查找效率比AVL树更慢(对于CPU…...
如何修改Windows系统Ollama模型存储位置
默认情况下,Ollama 模型会存储在 C 盘用户目录下的 .ollama/models 文件夹中,这会占用大量 C 盘空间,增加C盘“爆红”的几率。所以,我们就需要修改Ollama的模型存储位置 Ollama提供了一个环境变量参数可以修改Ollama的默认存在位…...
OpenAI ChatGPT在心理治疗领域展现超凡同理心,通过图灵测试挑战人类专家
近期,一项关于OpenAI ChatGPT在心理治疗领域的研究更是引起了广泛关注。据报道,ChatGPT已经成功通过了治疗师领域的图灵测试,其表现甚至在某些方面超越了人类治疗师,尤其是在展现同理心方面,这一发现无疑为AI在心理健康…...
Netflix Ribbon:云端负载均衡利器
Netflix Ribbon:云端负载均衡利器 ribbon Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support. 项目地…...
MAVSDK - Custom Mavlink处理
编译命令中开启 Custom Mavlink 编译 cmake -DCMAKE_BUILD_TYPERelease -DMAVLINK_DIALECTcustom -DBUILD_CUSTOM_MAVLINKON -DCUSTOM_MAVLINK_PATH"G:/Custom_Mavlink" -DBUILD_CUSTOM_PLUGINSON -DENABLED_CUSTOM_PLUGINS"speaker" -DENABLED_PLUGINS&qu…...
【Android】Android 悬浮窗开发 ( 动态权限请求 | 前台服务和通知 | 悬浮窗创建 )
文章目录 一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后返回处理 二、悬浮窗 前台服务和通知1、前台服务 启动 悬浮窗 的必要性① 保持悬浮窗存活② 悬浮窗的要求③ 悬浮窗版本兼容 2、其它类型服务简介① 前台服务…...
Python高级语法之jsonpathBeautifulSoup解析器
目录: 1、jsonPath的使用2、使用jsonpath解析淘票票网页3、BeautifulSoup解析器的使用4、BeautifulSoup层级选择器的使用 1、jsonPath的使用 2、使用jsonpath解析淘票票网页 3、BeautifulSoup解析器的使用 4、BeautifulSoup层级选择器的使用...
工业安卓主板在智慧粮仓设备中发挥着至关重要的作用
工业安卓主板在智慧粮仓设备中发挥着至关重要的作用。以下是关于其作用的具体分析: 一、提供稳定可靠的运行平台 智慧粮仓设备需要长时间稳定运行,以实现对粮食储存环境的实时监测和精准控制。工业安卓主板采用高性能的处理器和大容量的存储空间&#…...
ECMAScript6----var、let、const
ECMAScript6----var、let、const 1.var2.let3.const 1.var (1)在相同作用域下可重复声明 var a 20 var a 30 console.log(a) // 30(2)存在变量提升 console.log(a) // undefined var a 20(3)可修改声…...
【ST-LINK未能被keil识别STM32 ST-LINK Utility出现“Can not connect to target】
针对各种品牌32MCU boot0拉高,boot1拉低进入系统存储器,对Flash先擦除在下载 针对STM32f103 通过32复位和stlink Utilit解决 https://blog.csdn.net/Donglutao/article/details/129086960 https://www.bilibili.com/video/BV1F94y1g7be/?spm_id_…...
Android Http-server 本地 web 服务
时间:2025年2月16日 地点:深圳.前海湾 需求 我们都知道 webview 可加载 URI,他有自己的协议 scheme: content:// 标识数据由 Content Provider 管理file:// 本地文件 http:// 网络资源 特别的,如果你想直接…...
用deepseek学大模型05逻辑回归
deepseek.com:逻辑回归的目标函数,损失函数,梯度下降 标量和矩阵形式的数学推导,pytorch真实能跑的代码案例以及模型,数据,预测结果的可视化展示, 模型应用场景和优缺点,及如何改进解决及改进方法数据推导。…...
python实践-实现实时语音转文字本地部署版(二)
一、技术栈 python 3.10.6 vosk 需下载对应模型(vosk-model-cn-0.22)模型下载慢的同学看最后的资源链接。 pyaudio keyboard 二、实现功能 本地化实现麦克风语音录入,实时生成文字,并保存至本地文档。 三、实现代码 fro…...
tortoiseSVN 如何克隆项目到本地
导入项目成功,如下图:...
解决“QString的split()函数分割中文“报错
在使用Qt平台的QString类里的split()函数,分割.txt文件里中文的字符串时,发现中文会乱码。 问题原因:中文使用UTF-16编码。 解决方法:将.txt文件保存为UTF-16编码,然后使用split()去分割对应的字符串即可。…...
云平台结合DeepSeek的AI模型优化实践:技术突破与应用革新
目录 前言 一、技术架构:算力与算法的协同基石 1. 蓝耘平台的核心优势 2. DeepSeek的模型创新 二、应用场景:垂直领域的智能化落地 1. 商业领域:智能推荐与客服 2. 工业领域:质检与流程优化 3. 智慧城市与医…...
蓝桥杯(B组)-每日一题(1093字符逆序)
c中函数: reverse(首位置,尾位置) reverse(s.begin(),s.end()) 头文件:<algorithm> #include<iostream> #include<algorithm>//运用reverse函数的头文件 using namespace std; int main() {string s;//定义一…...
jsherp importItemExcel接口存在SQL注入
一、漏洞简介 很多人说管伊佳ERP(原名:华夏ERP,英文名:jshERP)是目前人气领先的国产ERP系统虽然目前只有进销存财务生产的功能,但后面将会推出ERP的全部功能,有兴趣请帮点一下 二、漏洞影响 …...
基于ffmpeg+openGL ES实现的视频编辑工具-字幕添加(六)
在视频编辑领域,字幕的添加是一项极为重要的功能,它能够极大地丰富视频内容,提升观众的观看体验。当我们深入探究如何实现这一功能时,FreeType 开源库成为了强大助力。本文将详细阐述借助 FreeType 库生成字幕数据的过程,以及如何实现字幕的缩放、移动、旋转、颜色修改、对…...
