解析STM32启动过程
相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x000000(PC = 0x000000)同时中断向量表的位置并不是固定的。而Cortex-M3内核则正好相反,有3种情况: 1、 通过boot引脚设置可以将中断向量表定位于SRAM区,即起始地址为0x2000000,同时复位后PC指针位于0x2000000处; 2、 通过boot引脚设置可以将中断向量表定位于FLASH区,即起始地址为0x8000000,同时复位后PC指针位于0x8000000处; 3、 通过boot引脚设置可以将中断向量表定位于内置Bootloader区,本文不对这种情况做论述; 而Cortex-M3内核规定,起始地址必须存放堆顶指针,而第二个地址则必须存放复位中断入口向量地址,这样在Cortex-M3内核复位后,会自动从起始地址的下一个32位空间取出复位中断入口向量,跳转执行复位中断服务程序。对比ARM7/ARM9内核,Cortex-M3内核则是固定了中断向量表的位置而起始地址是可变化的。 有了上述准备只是后,下面以STM32的2.02固件库提供的启动文件“stm32f10x_vector.s”为模板,对STM32的启动过程做一个简要而全面的解析。 程序清单一: ;文件“stm32f10x_vector.s”,其中注释为行号 DATA_IN_ExtSRAM EQU 0 ;1 Stack_Size EQU 0x00000400 ;2 AREA STACK, NOINIT, READWRITE, ALIGN = 3 ;3 Stack_Mem SPACE Stack_Size ;4 __initial_sp ;5 Heap_Size EQU 0x00000400 ;6 AREA HEAP, NOINIT, READWRITE, ALIGN = 3 ;7 __heap_base ;8 Heap_Mem SPACE Heap_Size ;9 __heap_limit ;10 THUMB ;11 PRESERVE8 ;12 IMPORT NMIException ;13 IMPORT HardFaultException ;14 IMPORT MemManageException ;15 IMPORT BusFaultException ;16 IMPORT UsageFaultException ;17 IMPORT SVCHandler ;18 IMPORT DebugMonitor ;19 IMPORT PendSVC ;20 IMPORT SysTickHandler ;21 IMPORT WWDG_IRQHandler ;22 IMPORT PVD_IRQHandler ;23 IMPORT TAMPER_IRQHandler ;24 IMPORT RTC_IRQHandler ;25 IMPORT FLASH_IRQHandler ;26 IMPORT RCC_IRQHandler ;27 IMPORT EXTI0_IRQHandler ;28 IMPORT EXTI1_IRQHandler ;29 IMPORT EXTI2_IRQHandler ;30 IMPORT EXTI3_IRQHandler ;31 IMPORT EXTI4_IRQHandler ;32 IMPORT DMA1_Channel1_IRQHandler ;33 IMPORT DMA1_Channel2_IRQHandler ;34 IMPORT DMA1_Channel3_IRQHandler ;35 IMPORT DMA1_Channel4_IRQHandler ;36 IMPORT DMA1_Channel5_IRQHandler ;37 IMPORT DMA1_Channel6_IRQHandler ;38 IMPORT DMA1_Channel7_IRQHandler ;39 IMPORT ADC1_2_IRQHandler ;40 IMPORT USB_HP_CAN_TX_IRQHandler ;41 IMPORT USB_LP_CAN_RX0_IRQHandler ;42 IMPORT CAN_RX1_IRQHandler ;43 IMPORT CAN_SCE_IRQHandler ;44 IMPORT EXTI9_5_IRQHandler ;45 IMPORT TIM1_BRK_IRQHandler ;46 IMPORT TIM1_UP_IRQHandler ;47 IMPORT TIM1_TRG_COM_IRQHandler ;48 IMPORT TIM1_CC_IRQHandler ;49 IMPORT TIM2_IRQHandler ;50 IMPORT TIM3_IRQHandler ;51 IMPORT TIM4_IRQHandler ;52 IMPORT I2C1_EV_IRQHandler ;53 IMPORT I2C1_ER_IRQHandler ;54 IMPORT I2C2_EV_IRQHandler ;55 IMPORT I2C2_ER_IRQHandler ;56 IMPORT SPI1_IRQHandler ;57 IMPORT SPI2_IRQHandler ;58 IMPORT USART1_IRQHandler ;59 IMPORT USART2_IRQHandler ;60 IMPORT USART3_IRQHandler ;61 IMPORT EXTI15_10_IRQHandler ;62 IMPORT RTCAlarm_IRQHandler ;63 IMPORT USBWakeUp_IRQHandler ;64 IMPORT TIM8_BRK_IRQHandler ;65 IMPORT TIM8_UP_IRQHandler ;66 IMPORT TIM8_TRG_COM_IRQHandler ;67 IMPORT TIM8_CC_IRQHandler ;68 IMPORT ADC3_IRQHandler ;69 IMPORT FSMC_IRQHandler ;70 IMPORT SDIO_IRQHandler ;71 IMPORT TIM5_IRQHandler ;72 IMPORT SPI3_IRQHandler ;73 IMPORT UART4_IRQHandler ;74 IMPORT UART5_IRQHandler ;75 IMPORT TIM6_IRQHandler ;76 IMPORT TIM7_IRQHandler ;77 IMPORT DMA2_Channel1_IRQHandler ;78 IMPORT DMA2_Channel2_IRQHandler ;79 IMPORT DMA2_Channel3_IRQHandler ;80 IMPORT DMA2_Channel4_5_IRQHandler ;81 AREA RESET, DATA, READONLY ;82 EXPORT __Vectors ;83 __Vectors ;84 DCD __initial_sp ;85 DCD Reset_Handler ;86 DCD NMIException ;87 DCD HardFaultException ;88 DCD MemManageException ;89 DCD BusFaultException ;90 DCD UsageFaultException ;91 DCD 0 ;92 DCD 0 ;93 DCD 0 ;94 DCD 0 ;95 DCD SVCHandler ;96 DCD DebugMonitor ;97 DCD 0 ;98 DCD PendSVC ;99 DCD SysTickHandler ;100 DCD WWDG_IRQHandler ;101 DCD PVD_IRQHandler ;102 DCD TAMPER_IRQHandler ;103 DCD RTC_IRQHandler ;104 DCD FLASH_IRQHandler ;105 DCD RCC_IRQHandler ;106 DCD EXTI0_IRQHandler ;107 DCD EXTI1_IRQHandler ;108 DCD EXTI2_IRQHandler ;109 DCD EXTI3_IRQHandler ;110 DCD EXTI4_IRQHandler ;111 DCD DMA1_Channel1_IRQHandler ;112 DCD DMA1_Channel2_IRQHandler ;113 DCD DMA1_Channel3_IRQHandler ;114 DCD DMA1_Channel4_IRQHandler ;115 DCD DMA1_Channel5_IRQHandler ;116 DCD DMA1_Channel6_IRQHandler ;117 DCD DMA1_Channel7_IRQHandler ;118 DCD ADC1_2_IRQHandler ;119 DCD USB_HP_CAN_TX_IRQHandler ;120 DCD USB_LP_CAN_RX0_IRQHandler ;121 DCD CAN_RX1_IRQHandler ;122 DCD CAN_SCE_IRQHandler ;123 DCD EXTI9_5_IRQHandler ;124 DCD TIM1_BRK_IRQHandler ;125 DCD TIM1_UP_IRQHandler ;126 DCD TIM1_TRG_COM_IRQHandler ;127 DCD TIM1_CC_IRQHandler ;128 DCD TIM2_IRQHandler ;129 DCD TIM3_IRQHandler ;130 DCD TIM4_IRQHandler ;131 DCD I2C1_EV_IRQHandler ;132 DCD I2C1_ER_IRQHandler ;133 DCD I2C2_EV_IRQHandler ;134 DCD I2C2_ER_IRQHandler ;135 DCD SPI1_IRQHandler ;136 DCD SPI2_IRQHandler ;137 DCD USART1_IRQHandler ;138 DCD USART2_IRQHandler ;139 DCD USART3_IRQHandler ;140 DCD EXTI15_10_IRQHandler ;141 DCD RTCAlarm_IRQHandler ;142 DCD USBWakeUp_IRQHandler ;143 DCD TIM8_BRK_IRQHandler ;144 DCD TIM8_UP_IRQHandler ;145 DCD TIM8_TRG_COM_IRQHandler ;146 DCD TIM8_CC_IRQHandler ;147 DCD ADC3_IRQHandler ;148 DCD FSMC_IRQHandler ;149 DCD SDIO_IRQHandler ;150 DCD TIM5_IRQHandler ;151 DCD SPI3_IRQHandler ;152 DCD UART4_IRQHandler ;153 DCD UART5_IRQHandler ;154 DCD TIM6_IRQHandler ;155 DCD TIM7_IRQHandler ;156 DCD DMA2_Channel1_IRQHandler ;157 DCD DMA2_Channel2_IRQHandler ;158 DCD DMA2_Channel3_IRQHandler ;159 DCD DMA2_Channel4_5_IRQHandler ;160 AREA |.text|, CODE, READONLY ;161 Reset_Handler PROC ;162 EXPORT Reset_Handler ;163 IF DATA_IN_ExtSRAM == 1 ;164 LDR R0,= 0x00000114 ;165 LDR R1,= 0x40021014 ;166 STR R0,[R1] ;167 LDR R0,= 0x000001E0 ;168 LDR R1,= 0x40021018 ;169 STR R0,[R1] ;170 LDR R0,= 0x44BB44BB ;171 LDR R1,= 0x40011400 ;172 STR R0,[R1] ;173 LDR R0,= 0xBBBBBBBB ;174 LDR R1,= 0x40011404 ;175 STR R0,[R1] ;176 LDR R0,= 0xB44444BB ;177 LDR R1,= 0x40011800 ;178 STR R0,[R1] ;179 LDR R0,= 0xBBBBBBBB ;180 LDR R1,= 0x40011804 ;181 STR R0,[R1] ;182 LDR R0,= 0x44BBBBBB ;183 LDR R1,= 0x40011C00 ;184 STR R0,[R1] ;185 LDR R0,= 0xBBBB4444 ;186 LDR R1,= 0x40011C04 ;187 STR R0,[R1] ;188 LDR R0,= 0x44BBBBBB ;189 LDR R1,= 0x40012000 ;190 STR R0,[R1] ;191 LDR R0,= 0x44444B44 ;192 LDR R1,= 0x40012004 ;193 STR R0,[R1] ;194 LDR R0,= 0x00001011 ;195 LDR R1,= 0xA0000010 ;196 STR R0,[R1] ;197 LDR R0,= 0x00000200 ;198 LDR R1,= 0xA0000014 ;199 STR R0,[R1] ;200 ENDIF ;201 IMPORT __main ;202 LDR R0, =__main ;203 BX R0 ;204 ENDP ;205 ALIGN ;206 IF :DEF:__MICROLIB ;207 EXPORT __initial_sp ;208 EXPORT __heap_base ;209 EXPORT __heap_limit ;210 ELSE ;211 IMPORT __use_two_region_memory ;212 EXPORT __user_initial_stackheap ;213 __user_initial_stackheap ;214 LDR R0, = Heap_Mem ;215 LDR R1, = (Stack_Mem + Stack_Size) ;216 LDR R2, = (Heap_Mem + Heap_Size) ;217 LDR R3, = Stack_Mem ;218 BX LR ;219 ALIGN ;220 ENDIF ;221 END ;222 ENDIF ;223 END ;224 ----------------------------------------------------------------------------------------------------------------------------------------------------------------- 如程序清单一,STM32的启动代码一共224行,使用了汇编语言编写,这其中的主要原因下文将会给出交代。现在从第一行开始分析: 第1行:定义是否使用外部SRAM,为1则使用,为0则表示不使用。此语行若用C语言表达则等价于: #define DATA_IN_ExtSRAM 0 第2行:定义栈空间大小为0x00000400个字节,即1Kbyte。此语行亦等价于: #define Stack_Size 0x00000400 第3行:伪指令AREA,表示 第4行:开辟一段大小为Stack_Size的内存空间作为栈。 第5行:标号__initial_sp,表示栈空间顶地址。 第6行:定义堆空间大小为0x00000400个字节,也为1Kbyte。 第7行:伪指令AREA,表示 第8行:标号__heap_base,表示堆空间起始地址。 第9行:开辟一段大小为Heap_Size的内存空间作为堆。 第10行:标号__heap_limit,表示堆空间结束地址。 第11行:告诉编译器使用THUMB指令集。 第12行:告诉编译器以8字节对齐。 第13—81行:IMPORT指令,指示后续符号是在外部文件定义的(类似C语言中的全局变量声明),而下文可能会使用到这些符号。 第82行:定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000) 第83行:将标号__Vectors声明为全局标号,这样外部文件就可以使用这个标号。 第84行:标号__Vectors,表示中断向量表入口地址。 第85—160行:建立中断向量表。 第161行: 第162行:复位中断服务程序,PROC…ENDP结构表示程序的开始和结束。 第163行:声明复位中断向量Reset_Handler为全局属性,这样外部文件就可以调用此复位中断服务。 第164行:IF…ENDIF为预编译结构,判断是否使用外部SRAM,在第1行中已定义为“不使用”。 第165—201行:此部分代码的作用是设置FSMC总线以支持SRAM,因不使用外部SRAM因此此部分代码不会被编译。 第202行:声明__main标号。 第203—204行:跳转__main地址执行。 第207行:IF…ELSE…ENDIF结构,判断是否使用DEF:__MICROLIB(此处为不使用)。 第208—210行:若使用DEF:__MICROLIB,则将__initial_sp,__heap_base,__heap_limit亦即栈顶地址,堆始末地址赋予全局属性,使外部程序可以使用。 第212行:定义全局标号__use_two_region_memory。 第213行:声明全局标号__user_initial_stackheap,这样外程序也可调用此标号。 第214行:标号__user_initial_stackheap,表示用户堆栈初始化程序入口。 第215—218行:分别保存栈顶指针和栈大小,堆始地址和堆大小至R0,R1,R2,R3寄存器。 第224行:程序完毕。 以上便是STM32的启动代码的完整解析,接下来对几个小地方做解释: 1、 AREA指令:伪指令,用于定义代码段或数据段,后跟属性标号。其中比较重要的一个标号为“READONLY”或者“READWRITE”,其中“READONLY”表示该段为只读属性,联系到STM32的内部存储介质,可知具有只读属性的段保存于FLASH区,即0x8000000地址后。而“READONLY”表示该段为“可读写”属性,可知“可读写”段保存于SRAM区,即0x2000000地址后。由此可以从第3、7行代码知道,堆栈段位于SRAM空间。从第82行可知,中断向量表放置与FLASH区,而这也是整片启动代码中最先被放进FLASH区的数据。因此可以得到一条重要的信息:0x8000000地址存放的是栈顶地址__initial_sp,0x8000004地址存放的是复位中断向量Reset_Handler(STM32使用32位总线,因此存储空间为4字节对齐)。 2、 DCD指令:作用是开辟一段空间,其意义等价于C语言中的地址符“&”。因此从第84行开始建立的中断向量表则类似于使用C语言定义了一个指针数组,其每一个成员都是一个函数指针,分别指向各个中断服务函数。 3、 标号:前文多处使用了“标号”一词。标号主要用于表示一片内存空间的某个位置,等价于C语言中的“地址”概念。地址仅仅表示存储空间的一个位置,从C语言的角度来看,变量的地址,数组的地址或是函数的入口地址在本质上并无区别。 4、 第202行中的__main标号并不表示C程序中的main函数入口地址,因此第204行也并不是跳转至main函数开始执行C程序。__main标号表示C/C++标准实时库函数里的一个初始化子程序__main的入口地址。该程序的一个主要作用是初始化堆栈(对于程序清单一来说则是跳转__user_initial_stackheap标号进行初始化堆栈的),并初始化映像文件,最后跳转C程序中的main函数。这就解释了为何所有的C程序必须有一个main函数作为程序的起点——因为这是由C/C++标准实时库所规定的——并且不能更改,因为C/C++标准实时库并不对外界开发源代码。因此,实际上在用户可见的前提下,程序在第204行后就跳转至.c文件中的main函数,开始执行C程序了。 至此可以总结一下STM32的启动文件和启动过程。首先对栈和堆的大小进行定义,并在代码区的起始处建立中断向量表,其第一个表项是栈顶地址,第二个表项是复位中断服务入口地址。然后在复位中断服务程序中跳转¬¬C/C++标准实时库的__main函数,完成用户堆栈等的初始化后,跳转.c文件中的main函数开始执行C程序。假设STM32被设置为从内部FLASH启动(这也是最常见的一种情况),中断向量表起始地位为0x8000000,则栈顶地址存放于0x8000000处,而复位中断服务入口地址存放于0x8000004处。当STM32遇到复位信号后,则从0x80000004处取出复位中断服务入口地址,继而执行复位中断服务程序,然后跳转__main函数,最后进入mian函数,来到C的世界。 |
相关文章:
解析STM32启动过程
相对于ARM上一代的主流ARM7/ARM9内核架构,新一代Cortex内核架构的启动方式有了比较大的变化。ARM7/ARM9内核的控制器在复位后,CPU会从存储空间的绝对地址0x000000取出第一条指令执行复位中断服务程序的方式启动,即固定了复位后的起始地址为0x…...
微信小程序开发自学笔记 —— 八、小程序基础库的更新迭代
小程序基础库的更新迭代 小程序基础库 小程序的运行环境是分成渲染层和逻辑层的,在渲染层可以用各类组件组建界面的元素,在逻辑层可以用各类API来处理各种逻辑,组件、API其实都是小程序基础库进行包装提供的,基础库的职责还要处…...
Mysql迁移Postgresql
目录原理环境准备操作系统(Centos7)Mysql客户端安装Psql客户端安装数据库用户空字符串处理成null导表脚本dbmysql2pgmysqlcopy测试在mysql中建表导表测试查看pg中的表原理 Mysql抽取:mysql命令重定向到操作系统文件,处理成csv文件; PG装载&a…...
关于信息安全认证CISP、PTE对比分析
CISP 注册信息安全专业人员 CISP-PTE 注册渗透测试工程师(以下简称PTE) 1 、发证机构 CISP与PTE的发证机构都是中国信息安全测评中心,政府背景给认证做背书,学员信息都在中国政府可控的机构手中; 如果想在政府、国…...
游戏场景编辑器和骨骼动画相关软件
游戏场景编辑器 一.Tiled(2D) Tiled 是帮助你开发游戏内容的 2D 地图编辑器。它的主要功能是可以编辑各种形式的瓦片地图,还支持通过用空图片这种强大的方式来标记额外信息给游戏使用。Tiled 关注的是总体灵活性,同时尽量保持直观性。 Tiled Map 不但…...
vue3常用的API
目录 1.ref函数 2.reactive函数 3.reactive对比ref 4.computed函数 5.watch函数 6.toRef 7..provide && inject 1.ref函数 作用: 定义一个响应式的数据 语法: const xxx ref(initValue) 创建一个包含响应式数据的引用对象(reference对象ÿ…...
Qt中使用
LIB库路径,include 头文件,运行的时候记得吧dll库带上,这基本就完成了。准备工作:Qt可以是傻瓜式的安装就行,GE的驱动里面有exe,直接点击安装即可,完了记得到安装路径把“.h”“.liib”和“.dll…...
controller-runtime搭建operator开发环境
目录 基本结构 注入CRD 基本结构 首先下载相应的go pkg go get -u sigs.k8s.io/controller-runtime 接下来需要创建控制器和Manager Operator的本质是一个可重入的队列编程模式,而Manager可以用来管理Controller、Admission Webhook,包括访问资源对…...
FPGA使用GTX实现SFP光纤收发SDI视频 全网首创略显高端 提供工程源码和技术支持
目录1、前言2、设计思路和框架3、vivado工程详解4、上板调试验证并演示5、福利:工程代码的获取1、前言 FPGA实现SDI视频编解码目前有两种方案: 一是使用专用编解码芯片,比如典型的接收器GS2971,发送器GS2972,优点是简…...
Django 之 CharField 和 TextField
CharField test_char models.CharField(max_length288)设置长度为 288 并不会报错,这取决于你的数据库后端,mysql char 类型长度为 255,django 里面设置超过 255 并不会有提示,个人感觉有点误导人,起码给个警告也行&…...
recyclerview 使用的坑
1.有不同的布局 12_GridLayoutManager setSpanSizeLookup()方法 - 简书 setSpanSizeLookup 这个方法要会 spanCount和 getSpanSize spanCount/getSpanSize() 才是这一项所占的宽度 2.均分 item布局要设置宽度为match_paraent 3.设置完了。发现高度不一样,…...
DBeaver连接mysql、oracle数据库
1. DBeaver连接mysql 1) 下载DBeaver https://dbeaver.io/download/,并安装 2) 新建数据库连接 3)选择mysql驱动程序 4)填写连接设置内容 5)点击 “编辑驱动设置”,并填写相关信息 6)选择本地…...
Kivy GridLayout 布局
Kivy GridLayout 是一种用于构建用户界面的布局类型,可以帮助我们快速创建具有固定列和行的网格布局。GridLayout 布局是可以适用于任意数量的行和列的布局,然后在这些行和列中放置 UI 元素。 Kivy 的 GridLayout 使用起来类似于 HTML 的表格,…...
Spark高手之路2—Spark安装配置
文章目录Spark 运行环境一、Local 模式1. 下载压缩包2.上传到服务器3. 解压4. 启动 Local 环境5. 命令行工具6. 退出本地模式7. 提交应用二、Standalone 模式1. 解压2. 修改配置文件1)进入解压缩后路径的 conf 目录,复制 workers.template 文件为 worker…...
Java中对象的比较
目录元素的比较基本类型的比较引用类型的比较1. 覆写基类的equals2. 基于Comparble接口类的比较3. 基于比较器比较三种方法对比元素的比较 基本类型的比较 这里就拿整型, 字符型, 布尔型 为例: public static void main(String[] args) {int a 10;int b 20;System.out.pri…...
Python编程训练题2
1.11 有 n 盏灯,编号 1~n(0<n<100)。第 1 个人把所有灯打开,第 2 个人按下所有编号为 2 的倍数的开关(这些灯将被关掉),第 3 个人按下所有编号为 3 的倍数的开关(其…...
Shifu基础功能:设备管理
设备管理 deviceshifu_configmap.yaml中的telemetries表示自动测量记录传导。Shifu通过telemetries中设置的方法,以指定时间向设备周期性地发送请求,来判断设备的连接情况。如果设备出现故障或者连接出现问题,edgeDevice的状态将发生改变&am…...
交互:可以执行命令行的框架才是好框架
上一节课,我们开始把框架向工业级迭代,重新规划了目录,这一节课将对框架做更大的改动,让框架支持命令行工具。 第三方命令行工具库 cobra obra 不仅仅能让我们快速构建一个命令行,它更大的优势是能更快地组织起有许多…...
eunomia-bpf 和 wasm-bpf 项目的 3 月进展
eunomia-bpf 项目是一个开源项目,旨在提供一组工具,用于在 Linux 内核中更方便地编写和运行 eBPF 程序。在过去一个月中,该项目取得了一些新的进展,以下是这些进展的概述。 首先,eunomia-bpf 动态加载库进行了一些重要…...
Spring框架核心功能手写实现
文章目录概要Spring启动以及扫描流程实现基础环境搭建扫描逻辑实现bean创建的简单实现依赖注入实现BeanNameAware回调实现初始化机制模拟实现BeanPostProcessor模拟实现AOP模拟实现概要 手写Spring启动以及扫描流程手写getBean流程手写Bean生命周期流程手写依赖注入流程手写Be…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
