arm平台编译so文件回顾
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、几个点
- 二、回顾过程
- 1.上来就执行Makefile
- 2.编译第三方开源库.a文件
- 2.1 build.sh脚本
- 2.2 Makefile
- 3.最终编译
- 三、其它知识点
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
在编译arm平台so文件时,完成了以下的几个点:
1、根据第三方开源的build.sh文件编译第三方开源库,至于build.sh文件怎么写,大概是看开源仓的README文件吧。
2、写了一个MakeFile文件并运行编译了.a文件。最近查资料的时候获取到一个知识点就是,其实.a就是所有.o文件的集合。
3、根据子文件夹Makefile文件编译子文件夹.a文件。
4、解决编译过程中的多个问题
一、几个点
1、目标
在arm机器上编译出arm平台上可用的so文件
2、机器系统
[root@ncn4a-mapopenservice-34-12-242 ~]# uname -a
Linux ncn4a-mapopenservice-34-12-242 4.19.36-vhulk1907.1.0.h1393.eulerosv2r8.aarch64 #1 SMP Thu Jan 5 17:52:22 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
3、build.sh和Makefile领悟
接前言。现在理解了build和Makefile的区别。源于我将makefile的文件内容放在了build.sh脚本中。然后感觉突然恍然大悟。
Makefile文件是用来编译代码的。里面是有CXXFLAGS,就是将.c//cpp文件编译成.a文件。
OBJ关键词就要编译成.a还是.so文件格式。
而build.sh文件其实就是linux指令集合文件,里面写了编译库的很多指令。其中就包括调用makefile的一步,即调用make指令。
所以build.sh和makefile是有比较大的区别的。
而且自己写的代码只需要编写Makefile就可以了,即只需要Makefile就可以了。因为用不到第三方开源库的.configure、make install。只需要一个make就可以了,所以写个make就可以执行了。
二、过程回顾
1.上来就执行Makefile
拿到studio_compile工程后,以为是直接执行build就可以了。但是执行时报了一个文件格式不对的错误
[2023-12-06 16:38:38] [root@ncn4a-mapopenservice-34-12-242 compile_wrapper]# ll
[2023-12-06 16:38:39] total 16
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 include
[2023-12-06 16:38:39] -rw-rw-r-- 1 root root 1926 Apr 27 2023 Makefile
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 src
[2023-12-06 16:38:39] drwxrwxr-x 2 root root 4096 Apr 27 2023 vs
[2023-12-06 16:38:39] [root@ncn4a-mapopenservice-34-12-242 compile_wrapper]# make -jm98
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.cpp -o src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.o
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/CompileLayerWrapper.cpp -o src/CompileLayerWrapper.o
[2023-12-06 16:38:47] g++ -Werror=return-type -std=c++0x -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -w -c -shared -o -D__STDC_LIMIT_MACROS -Dlinux -I. -I./include -I../model/include -I../common/include -I../compiler/include -I../configurator/include -I../operation/include -I../preprocessor/include -I../pbencoder/include -I../../../3rd/gdal/include/linux -I../../../3rd/gdal/src/libtiff\include -I../../../3rd/boost/include -I../../../3rd/jni/include/linux -I../../../3rd/protobuf/include -I../../../3rd/sqlite/include -I../../../3rd/zlib/include/linux -I../../../platform/HuaweiSecureC/include src/ParseJNIObj.cpp -o src/ParseJNIObj.o
[2023-12-06 16:38:47] g++ -Wl,-z,relro,-z,now,-z,noexecstack -D_FORTIFY_SOURCE=2 -O2 -s -ftrapv -fPIC -fstack-protector-all -static-libstdc++ -shared -o libcompile_wrapper.so ./src/com_huawei_mobilegis_data_studiocompile_engine_NativeEngine.o ./src/CompileLayerWrapper.o ./src/ParseJNIObj.o -L../../../build/lib/linux -lcompiler -lconfigurator -lpreprocessor -lpbencoder -loperation -lcommon -L../../../3rd/gdal/lib/linux -lgdal -lgeos_c -lgeos -lproj -ljson-c -L../../../3rd/boost/lib/linux -lboost_serialization -lboost_filesystem -lboost_system -lboost_thread -L../../../3rd/protobuf/lib/linux -lprotobuf -L../../../3rd/sqlite/lib/linux/ -lsqlite3 -L../../../3rd/zlib/lib/linux/ -lz -L../../../3rd/gdal/src/libtiff/lib -ltiff -L../../../platform/HuaweiSecureC/lib/linux/ -lsecurec -ldl -lpthread
[2023-12-06 16:39:02] /usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a: file format not recognized; treating as linker script
[2023-12-06 16:39:02] /usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a:1: syntax error
[2023-12-06 16:39:02] collect2: error: ld returned 1 exit status
[2023-12-06 16:39:02] make: *** [Makefile:43: all] Error 1
即这一条:
/usr/bin/ld:../../../3rd/gdal/lib/linux/libgdal.a: file format not recognized; treating as linker script
然后就查看一下libgdal.a文件格式,使用file (filename)指令
[2023-12-06 17:41:48] [root@ncn4a-mapopenservice-34-12-242 linux]# file libgdal.a
[2023-12-06 17:41:58] libgdal.a: ASCII text
[2023-12-06 17:41:58] [root@ncn4a-mapopenservice-34-12-242 linux]# timed out waiting for input: auto-logout
这个显示情况其实还看不出来文件格式。这个ACII text文件其实是因为.a文件在windows环境下解压导致文件格式出问题了。但是其实正常的,也会是x86的格式,不是arm的格式。总而言之,就是报错格式不对。
这个文件是第三方开源库静态库文件,所以需要编译第三方开源静态库。
其实后来按照心哥的说法,即便格式没有变成ASCII码也是需要重新编译第三方开源库的,因为平台变了,之前的.a文件是x86格式的。
这边不得不吐槽,上传到git上的.a文件真是一点用没有啊。
2、编译第三方开源库.a文件
先后编译boost库、protobuf、sqlite、zlib、gdal库。其中有两个点需要单独领出来看。一个就是gdal库,还有一个就是没有Makefile然后我自己写的makefile文件编译的。
先说gdal库。gdal需要依赖tiff库、json-c库、geos库、proj库,最后才是安装gdal库。这边也是这次才理解的就是。就是对于这几个库,自己感觉是编译,其实也是在机器上安装这个库。可以用-- v查看版本号的。
然后这几个开源库用的build.sh脚本编译的。
2.1 build.sh
build.sh基本格式就是以下形式
PREFIX_INC_PATH=$(cd "$(dirname "$0")";pwd) //获取当前路径
| git下载 | 备注 | |
| 解压 | ||
| 更改文件夹名(可选) | 可选 | |
| 进入含有configure文件的文件夹中 | ||
| 执行./configure | --prefix=【】,//设置安装路径 | |
| --enable-xxx / --disable-xxx | 不懂 | |
| --with-xxx / --without-xxx | 不懂 | |
| --build=arm-linux //设置编译环境 | 国产arm机器需要设置平台环境,不然会configure失败,导致build.sh失败 | |
| SQLITE3_CFLAGS=路径 | 不懂 | |
| SQLITE3_LIBS=路径 -lsqlite3 | 不懂 | |
| sh autogen.sh / autoreconf | 不懂,但是要安装autoconf全家桶,可以参考本人帖子 | |
| make -j8 | ||
| make install | ||
| 移动OBJ文件 | 可选 | |
| 【完成】 |
2.2 Makefile
Makefile的格式大概如下
| CXXFLAGS= | 用于将.c或.cpp文件编译成.o文件,编译格式为 $(CXX) $(CXXFLAGS) $*.cpp -o $@ | |
| CXX= | CXX = xxx指定编译器 | |
搜到这个帖子说的比较详细:Linux Makefile入门总结-CSDN博客
看完这个贴子,增加了对以下几个知识点的了解
| 元素 | 说明 | 备注 |
| 目标文件 : 依赖文件 [TAB]命令 | [TAB]:是你键盘左边tab键 | |
| -c | -c 是生成 .o 文件的必要参数! | gcc -c main.c -o main.o |
| .PHONY: clean | 用来屏蔽同名clean的文件夹或文件 | |
| = :变量(可修改) += :追加 := :常量(不可修改) | TARGET = test CXX := g++ | |
| $(TARGET) | # 相当于C语言的宏定义 | |
| %c、%cpp、%o | 隐含规则: 任意的.c 或 任意的.cpp 或 任意的.o | 使用%c 或 %cpp 或 %o 或 %h 时,优先加点'.'使用,如:%.c、%.cpp、%.o、%.h |
| *.c、*.cpp、*.o | 所有的.c 或 所有的.cpp 或 所有的.o | |
| $^ | 所有的依赖文件 依赖文件:我要做这个操作,依赖哪些东西 | $(TARGET): $(OBJ) $(CXX) $^ -o $@ |
| $< | 所有依赖文件的第一个文件(应该也是最匹配的一个文件) | %.o: %cpp $(CXX) $(CXXFLAGS) $< -o $@ |
| $@ | 所有的目标文件 目标文件:我要做这个操作,要生成的东西; | |
| CXXFLAGS | CXXFLAGS = -c -Wall 类似于宏替换 | |
| SRC = $(wildcard *.cpp) | 获取项目路径下的所有.cpp源文件 | |
| OBJ = $(patsubst %.cpp, %.o, $(SRC)) | 根据源文件链接成 .o 文件 | wildcard 和 patsubst 是Makefile函数的用法 |
| -wall | 编译后显示所有警告 | Makefile 中 -g、-o、-c、-f 、-D、-Wall、-L、含义 | 码农家园 |
这个帖子绝佳,搞明白很多之前的疑问,赞!Makefile 中 -g、-o、-c、-f 、-D、-Wall、-L、含义 | 码农家园
3、最终编译
继续回顾流程,显示用各个开源库的build.sh脚本把各个开源库编译一遍。再把子文件夹用Makefile编译一遍,这个上面的帖子也说了,每个子文件夹都有一个Makefile

这其中还有一个很奇怪的一个点,就是工程写了一个build.sh脚本,是进入每个子文件夹分别执行Makefile,这个也是一个知识点。但这不是重点,重点是用这个build.sh脚本执行编译时,过程中会因为MobaXterm出现network断开导致编译失败,所以我是对子文件夹单独编译的。可以编好。就很奇怪。
到此第三方开源库、子文件的静态库都编好了。其中过程中遇到好几个问题,通过百度都解决了,也记录在自己的文章中了。报错处理集-CSDN博客,现在就开始编译最终的so文件了。
这其中还有一个知识点就是,其实我之前理解的所谓交叉编译环境是在x86机器上安装检查编译工具。但是过程中问了心哥知道其实我用的这个欧拉系统是arm环境,所以交叉编译是不是只能用arm机器呢,这个问题留存解决。
解释:百度了一下,理解了,意思就是交叉编译是因为目标平台可能不支持编译或者资源不够,跨平台编译就叫交叉编译。如果像我这样就不算交叉编译了吧。
【百度百科:
一个经常会被问到的问题就是,“既然我们已经有了主机编译器,那为什么还要交叉编译呢?”其实答案很简单。有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征;有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器;有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。
另一个经常会被问到的问题就是:“既然可以交叉编译,那还要主机编译干吗?”其实答案也很简单,交叉编译是不得已而为之!与主机编译相比,交叉编译受的限制更多,虽然在理论上我们可以做任何形式的交叉编译,但事实上,由于受到专利、版权、技术的限制,并不总是能够进行交叉编译,尤其是在业余条件下!举例来说,我们至今无法生成惠普公司专有的som格式的可执行文件,因此我们根本无法做目的平台为HPPA-HPUX的交叉编译。来源:交叉编译_百度百科】
还有一点就是这次编译过程比较复杂,一方面是因为集气室离线的,很多是要离线安装的。但是问了心哥,说可以用yum install在线安装,试了确实可以。这个可能跟是欧拉系统有关。
三、其他知识点
1、这边还有一个关于x86和arm平台区别的知识点,找到这篇帖子:https://www.cnblogs.com/kin-zhang/p/15031633.html
2、Makefile里面可以直接把.a换成.so吗?编译.a和编译.so的Makefile有什么区别?
这个需要后面了解下
Makefile链接静态库.a编译成动态库.so_makefile 链接.a-CSDN博客
3、linux安装git的用户设置
当时准备安装git拉取代码的,不过发现并不可行,所以没有深究下去。后面可以了解下。
4、LIB = ar cr什么意思,未知,后面要了解下
总结
对整个编译过程进行了总结,是有意义的,编成功了。但是经验不复用应该是不好的,需要把经验积累下来。突然想起来强哥之前一直说要经验复用,大概也是指的这个意思吧。
相关文章:
arm平台编译so文件回顾
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、几个点二、回顾过程 1.上来就执行Makefile2.编译第三方开源库.a文件 2.1 build.sh脚本2.2 Makefile3.最终编译三、其它知识点总结 前言 提示:这…...
【数据结构】顺序表的定义和运算
目录 1.初始化 2.插入 3.删除 4.查找 5.修改 6.长度 7.遍历 8.完整代码 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 &…...
idea使用maven的package打包时提示“找不到符号”或“找不到包”
介绍:由于我们的项目是多模块开发项目,在打包时有些模块内容更新导致其他模块在引用该模块时不能正确引入。 情况一:找不到符号 情况一:找不到包 错误代码部分展示: Failure to find com.xxx.xxxx:xxx:pom:0.5 in …...
MetricBeat监控MySQL
目录 一、安装部署 二、开启mysql监控模块 三、编辑mysql配置文件 四、启动Metricbeat 五、查看监控图表 一、安装部署 metriceat的安装部署参考章节: Metricbeat安装使用,这里不再赘述。 二、开启mysql监控模块 进入metricbeat安装目录 ./metricb…...
Child Mind Institute - Detect Sleep States(2023年第一次Kaggle拿到了银牌总结)
感谢 感谢艾兄(大佬带队)、rich师弟(师弟通过这次比赛机械转码成功、耐心学习)、张同学(也很有耐心的在学习),感谢开源方案(开源就是银牌),在此基础上一个月…...
Esxi7Esxi8设置VMFSL虚拟闪存的大小
Esxi7Esxi8设置VMFSL虚拟闪存的大小 ESXi7,8 默认安装会分配一个 VMFSL(VMFS-L)(Local VMFS)很大空间(120G), 感觉很浪费, 实际给 8G 就可以了, 最少 6G , 经实验,给2G没法安装 . Esxi7是虚拟闪存的 修改的方法是: 在安装时修改 设置 autoPartitionOSDataSize8192 在cdromBoo…...
vue2+electron桌面端一体机应用
vue2+electron项目 前言:公司有一个项目需要用Vue转成exe,首先我使用vue-cli脚手架搭建vue2项目,然后安装electron 安装electron 这一步骤可以省略,安装electron-builder时会自动安装electron npm i electron 安装electron-builder vue add electron-builder 项目中多出…...
目标检测——OverFeat算法解读
论文:OverFeat: Integrated Recognition, Localization and Detection using Convolutional Networks 作者:Pierre Sermanet, David Eigen, Xiang Zhang, Michael Mathieu, Rob Fergus, Yann LeCun 链接:https://arxiv.org/abs/1312.6229 文章…...
vue获取主机id和IP地址
获取主机id和IP地址 在vue.config.js const os require(“os”); function getNetworkIp() { let needHost “”; // 打开的host try { // 获得网络接口列表 let network os.networkInterfaces(); for (let dev in network) { let iface network[dev]; for (let i 0; i …...
在pytorch中自定义dataset读取数据
这篇是我对哔哩哔哩up主 霹雳吧啦Wz 的视频的文字版学习笔记 感谢他对知识的分享 有关我们数据读取预训练 以及如何将它打包成一个一个batch输入我们的网络的 首先我们来看一下之前我们在讲resnet网络时所使用的源码 我们去使用了官方实现的image folder去读取我们的图像数据 然…...
ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders
1.关于稀疏卷积的解释:https://zhuanlan.zhihu.com/p/382365889 2. 答案: 在深度学习领域,尤其是计算机视觉任务中,遮蔽图像建模(Masked Image Modeling, MIM)是一种自监督学习策略,其基本思想…...
Java后端的登录、注册接口是怎么实现的
目录 Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的注册接口怎么实现? 如何防止SQL注入攻击? Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的登录接口的实现方式有很多种&a…...
TCP Keepalive 和 HTTP Keep-Aliv
HTTP的Keep-Alive 在http1.0的版本中,它是基于请求-应答模型和TCP协议的,也就是在建立TCP连接后,客户端发送一次请求并且接收到响应后,就会立马断开TCP连接,称为HTTP短连接,这种方式比较耗费时间以及浪费资…...
操作系统 复习笔记
操作系统的目标和作用 操作系统的目标 1.方便性 2.有效性 3.可扩展性 4.开放性 操作系统的作用 1.OS作为用户与计算机硬件系统之间的接口 2.OS作为计算机系统资源的管理者 3.OS实现了对计算机系统资源的抽象 推动操作系统发展的主要动力 1.不断提高计算机系统资源的…...
Java中实现单例模式的方式
1. 使用静态内部类实现单例模式 在Java中,使用静态内部类实现单例模式是一种常见而又有效的方式。这种方式被称为“静态内部类单例模式”或者“Holder模式”。这种实现方式有以下优点: 懒加载(Lazy Initialization):静…...
Vue3-01-创建项目
环境准备 1.需要用到 16.0 以及更高版本的 node.js 2.使用vscode编辑器进行项目开发可以在命令行中查看node的版本号: node -v创建项目 1.准备一个目录 例如,我创建项目的时候是在该目录下进行的;D:\projectsTest\vue3project2.执行创建命令(*&#x…...
Go 语言中的反射机制
欢迎大家到我的博客浏览,更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见,但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单,所以它没有特别强的表达能…...
[leetcode 前缀和]
525. 连续数组 M :::details 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2: 输入: nums [0,1,0] 输出: …...
Python与ArcGIS系列(十五)根据距离抓取字段
目录 0 简述1 实例需求2 arcpy开发脚本0 简述 在处理gis数据的时候,会遇到这种需求:将一个图层与另一个图层中相近的要素进行字段赋值。本篇将介绍如何利用arcpy及arcgis的工具箱实现这个功能。 1 实例需求 为了介绍这个功能的实现,我们需要有一个特定的功能需求。在这里选…...
YOLOv8分割训练及分割半自动标注
YOLOv8是基于目标检测算法YOLOv5的改进版,它在YOLOv5的基础上进行了优化和改进,加入了一些新的特性和技术,如切片注意力机制、骨干网络的选择等。 本文以yolov8-seg为基准,主要整理分割训练流程及使用v8分割模型进行半自动标注的过程。 一、v8-seg训练 1.1 环境配置 github…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
