7 Linux 内核移植

一、编译 ST 的 Linux 系统

1. 压缩源码

  首先先下载 ST 官方源码,之前章节已经下载过了,直接输入以下命令:

cd linux/atk-mpl/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0/

  然后压缩  linux-5.4.31.tar.xz  源码包压缩包:

tar -vxf linux-5.4.31.tar.xz

2. 给内核打补丁

输入以下命令:

cd linux-5.4.31/
for p in `ls -1 ../*.patch`; do patch -p1 < $p; done //打补丁# ls -1 ../*.patch:通过执行 ls 命令列出上一级目录(..)中以 .patch 结尾的所有文件,并使用 -1 选项确保每个文件显示为一行。这将生成一个包含所有补丁文件名的列表。
# for p in ...; do ...; done:通过循环结构遍历列表中的每个元素,并在循环体内执行相应的操作。这里对列表中的每个元素都被赋值给变量 p。
# patch -p1 < $p:对于每个补丁文件 $p,执行 patch 命令来应用补丁文件到当前目录。-p1 选项告诉 patch 命令去除补丁文件中的前缀路径(通常是一个目录),从而使补丁适用于当前目录。
# 循环遍历上一级目录中的所有以 .patch 结尾的文件,并使用 patch 命令将这些补丁文件应用到当前目录中,其中补丁文件的前缀路径被去除

3. 生成默认配置文件

  ST 原厂 Linux 内核需要先生成默认配置文件,并且对其进行打补丁,进入 Linux 内核源码根目录下,然后执行如下命令: 

make ARCH=arm multi_v7_defconfig "fragment*.config"# multi_v7_defconfig:指定要使用的配置文件。
# "fragment*.config":用于指定附加的配置片段文件。这里的 "fragment*.config" 是通配符表达式,指定了以 fragment 开头且以 .config 结尾的文件名模式。

  .config 文件非常重要, Linux 内核的所有配置项最终都保存在.config 文件里面,最终编译Linux 内核的时候需要读取.config 里面的配置项!此时我们只是生成了.config,并没有将 fragment config 补丁文件打进去,执行如下命令: 

for f in `ls -1 ../fragment*.config`; do scripts/kconfig/merge_config.sh -m -r .config $f; done
yes '' | make ARCH=arm oldconfig# scripts/kconfig/merge_config.sh -m -r .config $f:执行 merge_config.sh 脚本,将文件 $f 的配置合并到当前目录的 .config 文件中。-m 选项表示使用模块化配置,-r 选项表示要保留已经存在的配置。
# yes '':yes 命令会重复地输出指定的字符串(在本例中是空字符串 ''),直到被终止
# ARM 架构上使用旧的配置 .config 文件执行 make oldconfig,并在自动回答用户提示时使用空字符串来完成配置过程。这样可以自动化配置过程,减少了手动输入配置的需要

  至此, Linux 源码根目录下的.config 文件就已经保存了所有的配置项,所以只需要复制一份.config 作为我们的默认配置文件即可,复制命令如下: 

cp .config ./arch/arm/configs/stm32mp1_atk_defconfig

  Linux 内核全部打完补丁, linux-5.4.31 目录就是我们要移植的 Linux 源码。我们新建一个名为“my_linux”的目录来保存我们要移植的 linux 源码,然后将打完补丁的 linux 源码 linux-5.4.31 拷贝到“my_linux”目录下,命令如下: 

# 首先在/linux/atk-mpl创建 linux 目录,然后再linux目录下创建my_linux子目录
cd ~
cd linux/atk-mpl/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0/
cp linux-5.4.31 /linux/atk-mpl/linux/my_linux/ -rf //拷贝

二、编译 ST 官方 Linux 源码 

1. 修改Makefile

  其实跟uboot修改顶层 Makefile 一样,为了减少输入参数,就添加以下代码到顶层 Makefile 中。

  创建一个名为“stm32mp157d_atk.sh”的编译脚本,脚本内容如下: 

#!/bin/sh
make distclean
make stm32mp1_atk_defconfig
make menuconfig
make uImage dtbs LOADADDR=0XC2000040 -j16

  给 stm32mp157d_atk.sh  执行权限:

chmod 777 stm32mp157d_atk.sh     // 给予可执行权限
./stm32mp157d_atk.sh             // 运行编译脚本

  编译完成以后的到 uImage 镜像文件和设备树,其中 STM32MP157 系列的设备树有很多。

2. 修改网络驱动

  文件均来自正点原子的包里,下载地址:STM32MP157开发板 — 正点原子资料下载中心 1.0.0 文档

  将 motorcomm.c 和 motorcomm_phy.h 分别拷贝到 Linux 源码下的 drivers/net/phy 和include/linux 目录下。拷贝完成以后修改 drivers/net/phy/Makefile 文件,加上下面这句: 

obj-$(CONFIG_MOTORCOMM_PHY) += motorcomm.o# 如果定义了配置选项 CONFIG_MOTORCOMM_PHY 并且其值为 true,那么目标 motorcomm.o 将被添加到目标列表中,进而进行编译。

  还需要修改 drivers/net/phy/Kconfig 文件,添加以下代码:

config MOTORCOMM_PHYtristate "Motorcomm PHYs"---help---Supports the YT8010, YT8510, YT8511, YT8512 PHYs./* config MOTORCOMM_PHY:定义了一个名为 MOTORCOMM_PHY 的配置选项。这个配置选项可用于在编译内核时启用或禁用与 Motorcomm PHY 相关的功能。tristate "Motorcomm PHYs":配置选项的类型被设置为 tristate,即可以选择三个状态:y(编译进内核), m(编译为模块)和 n(禁用)。
"Motorcomm PHYs" 是配置选项的显示名称,将显示在配置界面上。---help---:用来提供配置选项的帮助说明。该行以下的内容将被视为对配置选项的详细描述。Supports the YT8010, YT8510, YT8511, YT8512 PHYs.:是对配置选项的详细描述,说明该选项的作用是支持 YT8010、YT8510、YT8511 和 YT8512 PHY 模块。
我们可以在 Linux 内核构建过程中选择是否编译或加载与 Motorcomm PHY 相关的功能模块*/

   在终端输入 make menuconfig,进入以下路径:

-> Device Drivers-> Network device support (NETDEVICES [=y])-> PHY Device support and infrastructure (PHYLIB [=y])-> <*> Motorcomm PHYs //将 YT8511 驱动编译进内核

3. 启动测试

  需要两个文件: uImage 和 stm32mp157d-ed1.dtb 

  首先将 /home/alientek/linux/tftpboot 文件删除,然后把这两个文件复制到tftp目录下并给予执行权限,命令如下:

cp stm32mp157d-ed1.dtb /home/alientek/linux/tftpboot/
cd ..
cp uImage /home/alientek/linux/tftpboot/
cd ~
cd linux/tftpboot/
chmod 777 stm32mp157d-ed1.dtb
chmod 777 uImage

  在 uboot 中输入:

tftp c2000000 uImage
tftp c4000000 stm32mp157d_ed1.dtb
bootm c2000000 - c4000000

三、在 Linux 中添加自己的开发板

1. 添加开发板对应的默认配置文件 

  首先添加开发板对应的默认配置文件,这里输入以下命令:

cd linux/atk-mpl/linux/my_linux/linux-5.4.31/arch/arm/configs
find stm32mp1_atk_defconfig

  就可以找到  stm32mp1_atk_defconfig  这个文件了。

2. 添加开发板对应的设备树 

 ① 新建设备树文件

   输入以下命令:

cd ~
cd linux/atk-mpl/linux/my_linux/linux-5.4.31/arch/arm/boot/dts/
cp stm32mp15xx-edx.dtsi stm32mp157d-atk.dtsi
cp stm32mp157d-ed1.dts stm32mp157d-atk.dts

  修改  stm32mp157d-atk.dts  文件:

 ② 修改 stm32mp157d-atk.dtsi 文件 

   跟uboot移植类似,PMIC 配置不需要,并在设备树里面添加电源节点信息。

#include "stm32mp157-m4-srm.dtsi"
#include "stm32mp157-m4-srm-pinctrl.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/mfd/st,stpmic1.h>/ {memory@c0000000 {device_type = "memory";reg = <0xC0000000 0x40000000>;};reserved-memory {#address-cells = <1>;#size-cells = <1>;ranges;mcuram2: mcuram2@10000000 {compatible = "shared-dma-pool";reg = <0x10000000 0x40000>;no-map;};vdev0vring0: vdev0vring0@10040000 {compatible = "shared-dma-pool";reg = <0x10040000 0x1000>;no-map;};vdev0vring1: vdev0vring1@10041000 {compatible = "shared-dma-pool";reg = <0x10041000 0x1000>;no-map;};vdev0buffer: vdev0buffer@10042000 {compatible = "shared-dma-pool";reg = <0x10042000 0x4000>;no-map;};mcuram: mcuram@30000000 {compatible = "shared-dma-pool";reg = <0x30000000 0x40000>;no-map;};retram: retram@38000000 {compatible = "shared-dma-pool";reg = <0x38000000 0x10000>;no-map;};};vddcore: buck1 {compatible = "regulator-fixed";regulator-name = "vddcore";regulator-min-microvolt = <1200000>;regulator-max-microvolt = <1350000>;regulator-always-on;regulator-boot-on;};v3v3: regulator-3p3v {compatible = "regulator-fixed";regulator-name = "v3v3";regulator-min-microvolt = <3300000>;regulator-max-microvolt = <3300000>;regulator-always-on;regulator-boot-on;};
};&cpu0 {cpu-supply = <&vddcore>;
};&crc1 {status = "okay";
};&dma1 {sram = <&dma_pool>;
};&dma2 {sram = <&dma_pool>;
};&dts {status = "okay";
};&ethernet0 {status = "okay";pinctrl-0 = <&ethernet0_rgmii_pins_a>;pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;pinctrl-names = "default", "sleep";phy-mode = "rgmii-id";max-speed = <1000>;phy-handle = <&phy0>;mdio0 {#address-cells = <1>;#size-cells = <0>;compatible = "snps,dwmac-mdio";phy0: ethernet-phy@0 {reg = <0>;};};
};&hash1 {status = "okay";
};&ipcc {status = "okay";
};&iwdg2 {timeout-sec = <32>;status = "okay";
};&rng1 {status = "okay";
};&rtc {status = "okay";
};&sdmmc1 {pinctrl-names = "default", "opendrain", "sleep";pinctrl-0 = <&sdmmc1_b4_pins_a>;pinctrl-1 = <&sdmmc1_b4_od_pins_a>;pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;broken-cd;st,neg-edge;bus-width = <4>;vmmc-supply = <&v3v3>;status = "okay";
};&sdmmc2 {pinctrl-names = "default", "opendrain", "sleep";pinctrl-0 = <&sdmmc2_b4_pins_a>;pinctrl-1 = <&sdmmc2_b4_od_pins_a>;pinctrl-2 = <&sdmmc2_b4_sleep_pins_a>;non-removable;st,neg-edge;bus-width = <8>;vmmc-supply = <&v3v3>;keep-power-in-suspend;status = "okay";
};&sram {dma_pool: dma_pool@0 {reg = <0x50000 0x10000>;pool;};
};&uart4 {pinctrl-names = "default", "sleep", "idle";pinctrl-0 = <&uart4_pins_a>;pinctrl-1 = <&uart4_sleep_pins_a>;pinctrl-2 = <&uart4_idle_pins_a>;pinctrl-3 = <&uart4_pins_a>;/delete-property/dmas;/delete-property/dma-names;status = "okay";
};

  这里是替换整个文件的代码,直接复制进去即可。

 ③ 编译 stm32mp157d-atk.dts 设备树

  打开 arch/arm/boot/dts/Makefile,到“ dtb-$(CONFIG_ARCH_STM32)”配置项,在此配置项中加入“stm32mp157d-atk.dtb”, 表示编译的时候也将 stm32mp157datk.dts 编译为 stm32mp157d-atk.dtb 。

3. 关闭内核模块验证

  后续做 Linux 驱动实验的时候我们都是编译驱动模块,然后在系统里面加载,加载的时候系统会验证模块,有时候会验证出错。比如板子运行的系统和编译驱动模块所用的系统不一致的时候。为了方便开发,我们可以关闭内核模块验证。打开默认配置文件 stm32mp1_atk_defconfig,里面有如下所示配置项目: 

  我们也可以直接在 Linux 的图形化配置界面上关闭掉内核模块验证,输入如下命令打开 Linux 内核图形化配置界面: 

# 在 /linux/atk-mpl/linux/my_linux/linux-5.4.31 该目录下
make menuconfig# 配置路径如下:
-> Enable loadable module support (MODULES [=y])->Module signature verification

  只要通过图形化界面修改了 Linux 内核配置,最好及时将其保存到stm32mp1_atk_defconfig 文件。因为图形化界面修改的配置只是暂时保存到.config 文件里面,一旦使用“make clean”清理工程,那么.config 文件就会被删除掉,所有的配置也就丢失了!

4. 编译测试

  进入该目录 /linux/atk-mpl/linux/my_linux/linux-5.4.31,再编译 stm32mp157d_atk.sh。二、3启动测试类似,把文件拷贝到 tftp 服务器目录下。在uboot下输入以下命令。

tftp c2000000 uImage
tftp c4000000 stm32mp157d-atk.dtb
bootm c2000000 - c4000000

  有这样的 log 信息就启动成功。

四、烧写系统镜像到 EMMC  

  我们现在都是通过 tftp 命令从网络上下载测试的,实际产品开发中最终是要将系统烧写到外部 Flash 中的,比如 EMMC。现在我们将 uIamge 和 stm32mp157d-atk.dtb 打包成 ext4 格式,然后通过 STM32CubeProgrammer 烧写到 EMMC 里面,最终启动 EMMC 里面的 Linux 系统。

1. 系统镜像打包

  先在 linux/atk-mpl/linux/ 路径下创建子目录 bootfs,然后再把 /linux/tftpboot 路径下的 stm32mp157d-atk.dtb 和 uImage 文件拷贝到 bootfs 里面。

① 新建 ext4 格式磁盘

  首先新建一个 ext4 格式的磁盘,然后挂载这个 ext4 格式的磁盘,将 stm32mp157d-atk.dtb 和 uImage 拷贝到这个 ext4 磁盘即可。 

cd bootfs
dd if=/dev/zero of=bootfs.ext4 bs=1M count=10
mkfs.ext4 -L bootfs bootfs.ext4    # 使用 mkfs.ext4 将 bootfs.ext4 磁盘格式化为 ext4 格式# 使用 dd 命令创建一个名为 bootfs.ext4 的磁盘, of 指定磁盘名字为“bootfs.ext4”;bs 指定磁盘输入/输出块大小为 1MB; count 指定磁盘的块数量为 10 个。
# 将会在当前目录下创建一个大小为10MB的bootfs.ext4文件,并用零填充它。

② 将系统镜像拷贝到 ext4 磁盘中

  首先创建一个目录用来挂载前面制作制作出来的 bootfs.ext4,比如我这里创建目录/mnt/bootfs,命令如下: 

cd /
sudo mkdir /mnt/bootfs

  使用 mount 命令将 bootfs.ext4 挂载到/mnt/bootfs 目录下,命令如下: 

cd /home/alientek/linux/atk-mp1/linux/bootfs
sudo mount bootfs.ext4 /mnt/bootfs

  挂载成功以后就将 uImage 和 stm32mp157d-atk.dtb 拷贝到/mnt/bootfs 目录下,命令如下: 

sudo cp uImage stm32mp157d-atk.dtb /mnt/bootfs/

  拷贝完成以后使用 umount 卸载/mnt/bootfs 即可,命令如下: 

sudo umount /mnt/bootfs

  这里我的理解是:先创建.ext4 磁盘,这个磁盘必须挂在到目录下,把需要放在这个磁盘下的东西放在挂载的目录里,最后再卸载该目录下的挂载。

2. 烧写到 EMMC 

  利用 FileZilla 将 bootfs.ext4 拷贝到 image 目录下:

  修改 Flashlayout:

  先把拨片波到USB,然后烧写,烧写完成后,把拨片拨到 EMMC 然后 RESET ,在 uboot 输入以下命令来验证是否烧写了  uImage 和stm32mp157d-atk.dtb 

ext4ls mmc 1:2

  设置 bootcmd 环境变量,从 EMMC 里面读取系统镜像和设备树并启动,命令如下:

setenv bootcmd 'ext4load mmc 1:2 c2000000 uImage;ext4load mmc 1:2 c4000000 stm32mp157d-atk.dtb;bootm c2000000 - c4000000'
saveenv
boot

  一般情况下,调试阶段都是用网络调试,也就是 tftp 或 nfs,当最终产品开发完成后,出厂的时候才烧写到 EMMC 里面。

五、文件系统缺失错误   

  Linux 内核启动以后是需要根文件系统的,根文件系统存在哪里是由 uboot 的 bootargs 环境变量指定的,它会传递给 Linux 内核作为命令行(command line)参数。  没有对应的根文件系统,必须要自己做根文件系统。 在没有根文件系统的情况下, Linux 内核启动的时候就会有下图所示的错误: 

  也就是提示内核崩溃, VFS(虚拟文件系统)不能挂载根文件系统,因为根文件系统目录不存在。解决方法就是制作根文件系统,并且设置 uboot 的 bootargs 环境变量,指定根文件系统所在的目录。 

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

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

相关文章

EasyExcel使用模板导出复杂Excel

1&#xff09;添加easyexlce的依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.0-beta1</version> </dependency>2&#xff09;添加excel模板文件 实现的效果&#xff1a;…

打包less

接HTML和css之后对less进行打包 1.在之前的文件夹里的src文件夹创建一个less文件 2.打开webpack——>中文文档——>Loader——>less—loader 3.复制下图代码到终端 4.复制下图内容到webpack.config.js脚本 5.在src里的js文件年引入less文件 6.在终端运行 npm run te…

助力工业生产质检,基于轻量级yolov5-seg开发构建工业场景下滚珠丝杠传动表面缺陷分割检测系统

AI赋能工业生产是一个强有力的方式&#xff0c;在我们之前的系列博文中也有很多相应的开发实践&#xff0c;感兴趣的胡都可以自行移步阅读&#xff0c;本文的核心思想就是想要基于轻量级的实例分割模型来开发构建工业场景下的滚珠丝杠传动表面缺陷分割检测系统&#xff0c;首先…

STM32-固件打包部署

STM32-固件打包部署 Fang XS.1452512966qq.com STM32固件输出 工程上使用Keil开发STM32软件&#xff1b;在调试过程中&#xff0c;可直接编译下载&#xff1b;例如bootloader和APP&#xff0c;在调试时&#xff0c;可以直接下载2次&#xff1b;但是工程上&#xff0c;需要大…

力扣经典面试题——合并区间

合并区间 https://leetcode.cn/problems/merge-intervals/description/?envTypestudy-plan-v2&envIdtop-interview-150 这题思维量一般但比较考察API的使用。 1、数组的自定义排序 2、数组的初始化定义 3、Arrays转int 通过重写Comparator的compare方法来自定义排序规则…

Spring Boot监听redis过期的key

Redis支持过期监听&#xff0c;可以实现监听过期数据&#xff0c;实现过程如下 1、pom依赖 <!-- Redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></depend…

Django讲课笔记02:Django环境搭建

文章目录 一、学习目标二、相关概念&#xff08;一&#xff09;Python&#xff08;二&#xff09;Django 三、环境搭建&#xff08;一&#xff09;安装Python1. 从官方网站下载最新版本的Python2. 运行安装程序并按照安装向导进行操作3. 勾选添加到路径复选框4. 完成安装过程5.…

【计算机网络】UDP报文详解

目录 一. UDP协议概述 二. UDP报文格式 首部 三. UDP的缓冲区 一. UDP协议概述 UDP——用户数据报协议&#xff0c;是传输层的一个重要协议 基于UDP的应用层协议有&#xff1a;DNS&#xff0c;TFTP&#xff0c;SNMP&#xff0c;NTP 协议全称默认端口号DNSDomain Name Se…

开源框架Apache NiFi调研

开源框架Apache NiFi调研 NiFi背景介绍一、什么是NiFi1.1 Apache NiFi特点&#xff1a;流管理、易用性、安全性、可扩展的体系结构和灵活的伸缩模型。1.2 Apache NiFi特性1.2 Apache NiFi核心概念1.3架构 二、NiFi的诞生&#xff0c;要致力于解决的问题有哪些&#xff1f;三、为…

AICore 带来了 Android 专属的 AI 能力,它要解决什么?采用什么架构思路?

前言 Google 最近发布的 Gemini 模型在全球引起了巨大反响&#xff0c;其在多模态领域的 Video demo 无比震撼。对于 Android 开发者而言&#xff0c;其中最振奋人心的消息莫过于 Gemini Nano 模型将内置到 Android 系统当中&#xff0c;并开放给开发者使用。 事实上&#xf…

IDEA 2023.3 start failed 启动失败修复

发现是 RestfulToolkit 插件有冲突导致的&#xff0c;删除插件后成功启动 open ~/Library/Application\ Support/JetBrains/IntelliJIdea2023.3/plugins参考&#xff1a;https://youtrack.jetbrains.com/issue/IDEA-340080/Critical-startup-error-after-upgrading-to-Intelli…

无人零售柜:快捷舒适购物体验

无人零售柜&#xff1a;快捷舒适购物体验 通过无人零售柜和人工智能技术&#xff0c;消费者在购物过程中可以自由选择商品&#xff0c;根据个人需求和喜好查询商品清单。这种自主选择的购物环境能够为消费者提供更加舒适和满意的体验。此外&#xff0c;无人零售柜还具有节约时间…

LabVIEW使用单板RIO开发远程监控电源信号

LabVIEW使用单板RIO开发远程监控电源信号 设计和构建用于智能电网的本地功耗分析系统&#xff0c;主要服务于领先的电力监控设备设计者和制造商。随着智能电网投资的增加&#xff0c;对于能够有效处理替代电源&#xff08;如太阳能和风能&#xff09;间歇性功率水平的技术需求…

【EMNLP 2023】面向垂直领域的知识预训练语言模型

近日&#xff0c;阿里云人工智能平台PAI与华东师范大学数据科学与工程学院合作在自然语言处理顶级会议EMNLP2023上发表基于双曲空间和对比学习的垂直领域预训练语言模型。通过比较垂直领域和开放领域知识图谱数据结构的不同特性&#xff0c;发现在垂直领域的图谱结构具有全局稀…

【开源】基于Vue+SpringBoot的教学资源共享平台

文末获取源码&#xff0c;项目编号&#xff1a; S 068 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S068。} 文末获取源码&#xff0c;项目编号&#xff1a;S068。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

虹科Pico汽车示波器 | 汽车免拆检修 | 2019款别克GL8豪华商务车前照灯水平调节故障

一、故障现象 一辆2019款别克GL8豪华商务车&#xff0c;搭载LTG发动机&#xff0c;累计行驶里程约为10.7万km。车主反映&#xff0c;车辆行驶过程中组合仪表提示前照灯水平调节故障。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上提示“前照灯水平调节…

windows10安装MongoDB的入门简易教程【学习自用】

一、下载安装包 下载地址 https://www.mongodb.com/try/download/community 因为我是在windows上安装&#xff0c;所以下载windows版本的压缩包格式 二、下载后解压到要安装的目录里去 我这里在D盘装&#xff0c;所以就解压到D盘中我自己建的的mongoDB文件夹中。 三、在解…

02-Nacos和Eureka的区别与联系

Nacos和Eureka的区别 联系 Nacos和Eureka整体结构类似: 都支持服务注册, 服务拉取, 采用心跳方式对服务提供者做健康监测的功能 区别 Nacos支持服务端主动检测服务提供者状态: 临时实例采用心跳模式,非临时实例采用主动检测模式但对服务器压力比较大(不推荐) 心跳模式: 服务…

.net 安装Postgresql驱动程序ngpsql

.net 安装Postgresql驱动程序ngpsql 最近搞一个物联网项目&#xff0c;需要采集fanuc数控机床的数据&#xff0c;厂家提供的API只支持windows&#xff0c;所以就决定C#开发&#xff0c;数据库用postgresql&#xff0c; 安装数据库驱动一波三折。 作为一个讨厌微软的老程序猿&…

静态链接库和动态链接库(隐式载入显式载入)

文章目录 动态链接库和静态链接库什么是链接库&#xff1f;静态链接库动态链接库动态链接库的俩种链接方式加载时动态链接运行时动态链接 动态链接库和静态链接库 动态链接库和静态链接库都是共享代码的方法&#xff0c;只是二者略有区别。 以C/C为例&#xff0c;一个可执行文…