嵌入式学习笔记——大小端及跳转到绝对地址
大小端以及跳转到绝对地址 0x100000
- 嵌入式编程中的大小端详解
- 一、大端模式与小端模式
- 二、判断当前系统是大端还是小端
- 方法一:指针强制类型转换
- 方法二:使用联合体(union)
- 三、结构体位段和大小端的影响
- 四、大小端影响内存的 memcpy 拷贝效果
- 五、大小端转换函数
- 六、总结
- 跳转到绝对地址 0x100000 的原理与实现
- 一、为何需要跳转?
- 二、跳转原理
- 三、代码实现
- 四、简化写法
- 五、Flash 分区结构示意图
- 六、注意事项
- 七、小结
嵌入式编程中的大小端详解
在嵌入式编程中,理解大小端是非常重要的,它直接关系到数据在内存中的布局和跨平台通信时的数据解析正确性。
一、大端模式与小端模式
大端模式(Big Endian):高字节存在低地址,低字节存在高地址。
小端模式(Little Endian):低字节存在低地址,高字节存在高地址。
例如:
unsigned int temp = 0x12345678;
假设 temp
的地址是 0x20000010
,那么:
-
在 大端模式 中,内存排列为:
0x20000010
:0x120x20000011
:0x340x20000012
:0x560x20000013
:0x78
-
在 小端模式(STM32) 中,内存排列为:
0x20000010
:0x780x20000011
:0x560x20000012
:0x340x20000013
:0x12
二、判断当前系统是大端还是小端
方法一:指针强制类型转换
#include <stdio.h>int main() {int num = 1; // 定义整型变量 num,值为1char *ptr = (char *)# // 强制转换为字符型指针,查看最低地址的字节内容if (*ptr == 1) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}
方法二:使用联合体(union)
#include <stdio.h>union endian_check {int num;char single_byte; // 访问低地址的单字节
};int main() {union endian_check check;check.num = 1; // 赋值为1(0x00000001)if (check.single_byte == 1) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}
三、结构体位段和大小端的影响
#include <stdio.h>struct mybitfields {unsigned short a : 4; // 4位位段unsigned short b : 5; // 5位位段unsigned short c : 7; // 7位位段
} test;int main() {int i;test.a = 2; // 二进制 0010test.b = 3; // 二进制 00011test.c = 0; // 二进制 0000000i = *((short *)&test); // 强制转换结构体地址为 short* 后解引用printf("%d\n", i); // 输出为50,实际内存内容:0010 00011 0000000 => 0x32return 0;
}
四、大小端影响内存的 memcpy 拷贝效果
#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main() {unsigned int uiVal_1 = 0x12345678; // 原始整型变量unsigned int uiVal_2 = 0; // 存储从字节数组拷贝后的数据unsigned char aucVal[4] = {0x12, 0x34, 0x56, 0x78}; // 定义字节数组unsigned short usVal_1 = 0;unsigned short usVal_2 = 0;memcpy(&uiVal_2, aucVal, sizeof(uiVal_2)); // 把数组内容复制到uiVal_2中usVal_1 = (unsigned short)uiVal_1; // 截断低16位 => 0x5678usVal_2 = (unsigned short)uiVal_2; // 拷贝后低16位 => 0x3412 (小端存储顺序)printf("usVal_1: %x\n", usVal_1); // 输出截断值printf("usVal_2: %x\n", usVal_2); // 输出截断值return 0;
}
五、大小端转换函数
// 32位整数转换
int swapInt32(int intValue) {int temp = 0;temp = ((intValue & 0x000000FF) << 24) |((intValue & 0x0000FF00) << 8) |((intValue & 0x00FF0000) >> 8) |((intValue & 0xFF000000) >> 24);return temp;
}// 16位短整型转换
unsigned short swapShort16(unsigned short shortValue) {return ((shortValue & 0x00FF) << 8) | ((shortValue & 0xFF00) >> 8);
}// 32位浮点数转换(使用联合体)
float swapFloat32(float floatValue) {typedef union {float unionFloat;int unionInt;} SWAP_UNION;SWAP_UNION swapUnion;swapUnion.unionFloat = floatValue;swapUnion.unionInt = swapInt32(swapUnion.unionInt);return swapUnion.unionFloat;
}// 64位双精度浮点数转换(使用指针反转)
void swapDouble64(unsigned char *pIn, unsigned char *pOut) {for (int i = 0; i < 8; i++) {pOut[7 - i] = pIn[i]; // 将输入按字节反转存入输出}
}int main() {int x = 0x12345678;int y = swapInt32(x); // 调用函数转换大小端printf("%x\r\n", y); // 输出结果应为 0x78563412return 0;
}
六、总结
- STM32 采用小端模式。
- 小端:低位字节存在低地址;大端:高位字节存在低地址。
- 判断大小端可使用指针、联合体等方法。
- 位段的使用也会受到大小端的影响。
- 在多平台数据交换时,必须进行大小端转换,确保数据一致性。
跳转到绝对地址 0x100000 的原理与实现
在嵌入式开发中,程序往往被分布在 Flash 的不同区域。例如,在采用 Bootloader + 主程序(APP)结构的设计中,Bootloader 启动后会跳转到主程序所在的地址开始执行。这种“跳转”就是我们常说的“跳转到绝对地址执行”,下面我们详细介绍其原理与实现方法。
一、为何需要跳转?
常见应用场景包括:
- Bootloader 启动后跳转到主应用程序执行
- 多镜像升级系统(A/B 双系统)
- 不同 Flash 区域运行不同的功能模块
例如,如果主程序被烧录在 Flash 的地址 0x100000
(假设起始地址),那么 Bootloader 启动后就需要跳转到这个地址运行主程序。
二、跳转原理
Cortex-M 内核芯片(如 STM32)启动时,会自动读取启动地址前 8 字节:
- 第 1 个字(偏移 0):主堆栈指针初始值(MSP)
- 第 2 个字(偏移 4):程序入口地址(Reset_Handler)
因此,跳转前必须:
- 设置新的 MSP 值为
*(uint32_t*)0x100000
- 设置跳转地址为
*(uint32_t*)(0x100000 + 4)
并执行
三、代码实现
推荐使用 typedef
简化函数指针写法:
#include <stdint.h>#define APP_ADDRESS 0x100000 // 目标程序地址typedef void (*pFunction)(void); // 定义函数指针类型void jump_to_app(void) {__disable_irq(); // 关闭中断,避免干扰uint32_t jump_address = *(volatile uint32_t*)(APP_ADDRESS + 4); // 程序入口地址pFunction JumpToApplication = (pFunction)jump_address; // 转换成函数指针__set_MSP(*(volatile uint32_t*)APP_ADDRESS); // 设置主堆栈指针(MSP)JumpToApplication(); // 跳转执行目标程序
}
上述代码完成了从 Bootloader 跳转到主程序的过程。
四、简化写法
((void (*)())0x100000)(); // 将地址当作函数指针并执行
虽然简洁,但不推荐用于 STM32,因为没有设置 MSP主堆栈指针,容易导致系统异常。
五、Flash 分区结构示意图
+------------------------+
| 地址 0x08000000 | → Bootloader
+------------------------+
| 地址 0x08010000 | → APP 主程序(即 0x100000)
+------------------------+
| ...... |
注:部分 STM32 芯片 Flash 起始地址是 0x08000000
,此处 0x100000
视具体芯片配置而定。
六、注意事项
- 跳转地址处必须是有效程序,并具备正确的中断向量表
- 必须先设置 MSP,否则可能因栈指针错误导致 HardFault
- 跳转前应关闭中断,避免中断未关闭造成干扰
- 若使用 FreeRTOS 等 RTOS,需要考虑中断向量重定向问题
七、小结
项目 | 说明 |
---|---|
跳转地址 | 比如 0x100000 ,主程序存放起点 |
MSP 设置 | 必须从地址读取并设置 __set_MSP() |
入口地址 | 是 *(uint32_t*)(addr + 4) |
函数指针跳转 | 把地址强转为函数指针并调用 |
相关文章:
嵌入式学习笔记——大小端及跳转到绝对地址
大小端以及跳转到绝对地址 0x100000 嵌入式编程中的大小端详解一、大端模式与小端模式二、判断当前系统是大端还是小端方法一:指针强制类型转换方法二:使用联合体(union) 三、结构体位段和大小端的影响四、大小端影响内存的 memc…...
eprime相嵌模式实验设计
一、含义与模型结构 该模式的实验设计至少 由两个存储不同实验材料及 属性的List和一个核心实验 过程CEP组成。子list1和 list2相嵌在父List中,CEP 可以调用List中的材料,也 可以调用list1和list2中的材 料。 二、相嵌模式的应用 应用于解决“多重随…...
编译uboot的Makefile编写
make ARCHarm CROSS_COMPILEarm-linux-gnueabihf- distcleanmake ARCHarm CROSS_COMPILEarm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfigmake V1 ARCHarm CROSS_COMPILEarm-linux-gnueabihf- -j12 这三条命令中 ARCHarm 设置目标为 arm 架构, CROSS_COMP…...
Go语言常用算法实现
以下是Go语言中常用的算法实现,涵盖排序、搜索、数据结构操作等核心算法。 一、排序算法 1. 快速排序 func QuickSort(arr []int) []int {if len(arr) < 1 {return arr}pivot : arr[0]var left, right []intfor i : 1; i < len(arr); i {if arr[i] < pi…...
Windows上使用NSSM注册定时服务
适用和不适用场景 适用场景 持续运行 的脚本或程序(如 Laravel 的 schedule:run 每分钟检查任务)后台常驻 的任务或服务(如监听服务、实时同步) 不适用场景 低频次任务(如每日/每周备份) NSSM 常驻内存…...
【Gorm】模型定义
intro package mainimport ("gorm.io/gorm""gorm.io/driver/sqlite" // GORM 使用该驱动来连接和操作 SQLite 数据库。 )type Product struct {gorm.Model // 嵌入GORM 内置的模型结构,包含 ID、CreatedAt、UpdatedAt、DeletedAt 四个字段Cod…...
程序化广告行业(65/89):AdX/SSP系统深度剖析与实战要点
程序化广告行业(65/89):AdX/SSP系统深度剖析与实战要点 大家好!一直以来,我都对程序化广告领域充满热情,这个领域发展迅速且不断涌现新的技术和模式。之前我们探讨了程序化广告的一些基础内容,…...
算法刷题记录——LeetCode篇(2.7) [第161~170题](持续更新)
更新时间:2025-04-06 算法题解目录汇总:算法刷题记录——题解目录汇总技术博客总目录:计算机技术系列博客——目录页 优先整理热门100及面试150,不定期持续更新,欢迎关注! 169. 多数元素 给定一个大小为…...
conda安装指定版本python环境
1. 创建指定 Python 版本的环境 使用以下命令创建环境,并将 <env_name> 替换为你的环境名称,<python_version> 替换为具体的 Python 版本(如 3.8, 3.9 等) conda create -n <env_name> python<python_vers…...
PH热榜 | 2025-04-05
1. Comp AI 标语:开源的 Vanta 和 Drata 替代方案 介绍:这款开源的 Drata 和 Vanta 替代方案,能够帮助你在几周内,轻松满足 SOC 2、ISO 27001 和 GDPR 等合规框架的要求,而不是像往常那样拖延数月。 产品网站&#…...
C++之红黑树
目录 一、红黑树的概念 1.1、红黑树的规则 1.2、红黑树如何确保最长路径不超过最短路径的二倍 1.3、红黑树的效率 二、红黑树的实现 2.1、红黑树的结构 2.2、红黑树的插入 2.2.1、红黑树插入一个值的大概过程 2.2.2、情况一:变色 2.2.3、情…...
各个语言对不同数据结构的叫法
一、基础数据结构对比 数组(Array) C/C:固定大小数组(int arr),动态数组通过vector(C)实现 Java:固定数组(int[]),动态数组…...
蓝桥杯 web 水果拼盘 (css3)
做题步骤: 看结构:html 、css 、f12 分析: f12 查看元素,你会发现水果的高度刚好和拼盘的高度一样,每一种水果的盘子刚好把页面填满了,所以咱们就只要让元素竖着排列,加上是竖着,排不下的换行…...
算法专题(八):分治-归并排序
目录 一、排序数组 1.1 题目 2.2 思路 2.3 代码实现 二、LCR 170. 交易逆序对的总数 (数组中的逆序对) 2.1 题目 2.2 思路 方法一:快速统计出某个数前面有多少个数比它大 方法二:快速统计出某个数后面有多少个数比它小 …...
51单片机使用定时器实现LCD1602的时间显示(STC89C52RC)
本文前半部分直接给出实现(注意进位问题是秒->分->小时,用 if 嵌套即可实现),后半部分讲解定时器和中断系统。 效果展示: LCD1602电路图: 项目结构: 代码实现: main.c #…...
微软2025年AI技术深度解析:从多模态大模型到企业级代理服务
微软2025年AI技术深度解析:从多模态大模型到企业级代理服务 一、微软AI技术全景概览 在2025年的AI领域,微软通过Azure AI Foundry、多模态大模型、企业级AI代理三大核心技术,构建了覆盖开发、部署、应用全流程的AI生态体系。根据最新财报数…...
24 设计模式总结
设计模式分类(意图) • 创建型模式:创建对象的机制,从所需要实例化的对象中解耦。 • 结构型模式:将对象或类组装到更大的结构中。 • 行为型模式:负责对象间的交互和分配职责。分类的目的是为了更抽象的了…...
【ARTS】2873.有序三元组中的最大值!
前言 仅做学习使用,侵删 什么是ARTS? 算法(Algorithm): 每周至少一道LeetCode算法题,加强编程训练和算法学习 阅读(Review): 阅读并点评至少一篇英文技术文章,提高英文水平 技巧 (Tip):学习至少一个技…...
Mysql进阶
目录 一.Mysql架构 1.连接层 2.服务层 3.引擎层 4.物理文件存储层 二.Mysql引擎 1.InnoDB 2.MyISAM 三.索引 1.什么是索引 2.为什么要有索引 3.索引的原理 4.索引优势 5.索引劣势 6.索引分类 主键索引 唯一索引 单值索引 组合索引(复合索引&#…...
探秘JVM内部
在我们编写Java代码,点击运行后,会发生什么事呢? 首先,Java源代码会经过Java编译器将其编译成字节码,放在.class文件中 然后这些字节码文件就会被加载到jvm中,然后jvm会读取这些文件,调用相关…...
c语言学习12天
c语言的宏定义:宏定义单纯的文本替换不会检查语法是否合法 #include #pragma 以及开头的#都属于预处理指令 预处理指令:在gcc编译套件中的cpp预处理器对程序进行编译之前所做的一些动作,如#include预处理指令就是在程序编译之前有预处理器…...
公司内网部署离线deepseek本地模型实战
企业内部可能有些数据比较敏感,不能连接互联网。deepseek来提高工作效率,这个时候你可以利用ollama在内网本地部署来实现。 本式样是先在自己电脑上用虚拟机部署好,再用U盘把虚拟机文件复制到内网去。 一、使用VMware新建WIN2022虚拟机 &a…...
rocketmq中的延迟队列使用详解
RocketMQ的延迟队列通过预设的延迟等级实现消息的定时投递,适用于订单超时、定时通知等高并发场景。以下是其核心原理、使用方式及优化策略的详细解析: 一、实现原理 延迟等级机制 RocketMQ默认提供18个固定延迟等级(1s、5s、10s、30s、1m、2…...
VB.NET Asp.Net Core模板WebAPI应用-宝塔面板Linux系统通过Docker部署
宝塔面板支持在Linux系统上部署Docker容器吗? 如何在宝塔面板上通过Docker部署VB.NET应用? Docker容器中的VB.NET Asp.Net Core WebAPI应用如何配置? 一,首先,创建一个ASP.NET Core测试项目 1.1 打开VS2019/2022,创建一个.NTE6 Core控制台应…...
4985 蜗牛
4985 蜗牛 ⭐️难度:中等 ⭐️考点:2023、省赛、动态规划 📖 📚 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scanner sc new Sc…...
springboot多模块工程打包部署运行
1、问题概述? 基于实际项目打包过程,各种配置面面俱到,已配置的可跳过。 本文以打包jar包为模板进行操作,部署方便。 在实际的开发中,项目的模块可能较多,如果都放在一个项目的目录中,势必会造成项目包中的文件冗余,难以管理,这个时候就需要使用多模块管理项目。 …...
吴恩达深度学习复盘(8)神经网络中激活函数的建模
激活函数的建模原理 到目前为止,在隐藏层等一直使用激活函数,最初通过逻辑回归建立新网络,组合多个逻辑回归单元。这表明激活函数在神经网络构建中一直存在,且最初的网络构建方式与逻辑回归相关。实际上,激活函数的种类…...
1-linux的基础知识
一.linux的文件系统结构 windows文件系统 微软windows系统将硬盘上的几个分区,用A: B: C: D:等符号标识。存取文件时一定要清楚放在那个磁盘的那个目录下。 linux文件系统 linux文件系统的组织模式犹如一颗倒置的树,这与windows文件系统有很大的差别…...
docker 常用命令
文章目录 一、帮助启动类命令启动docker停止docker重启docker查看docker状态开机自启查看docker概要信息 二、镜像命令列出本地主机上的镜像搜索镜像拉取镜像查看镜像所占空间删除镜像 三、容器命令新建运行容器交互式启动容器守护进程式启动容器列出当前所有的容器进入容器之后…...
使用docker搭建redis镜像时云服务器无法访问到国外的docker官网时如何解决
下载redis镜像 docker redis:版本号 此时截图中无法访问到国外的docker官网 解决方案: 通过更换镜像源来正常下载redis镜像 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<EOF {"registry-mirrors": ["https://docker.1…...
基于Python的人脸识别校园考勤系统
【Python】基于Python的人脸识别校园考勤系统 (完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 🌟 该系统主要分为前端和后端两个部分,前端👀负责人脸采集、人…...
微信小程序学习实录11:startLocationUpdateBackground:fail auth deny
startLocationUpdateBackground:fail auth deny 表明小程序在尝试开启后台位置更新时,用户授权被拒绝。以下是可能的原因及解决方法: 原因分析 缺少必要的用户授权: 使用 wx.startLocationUpdateBackground 接口需要用户授予 scope.userLo…...
DAPP实战篇:规划下我们的开发线路
前言 在DApp实战篇:先用前端起个项目一文中我们起了一个前端项目,在后续开发中笔者将带领大家一步步完成这个DAPP,为了方便后续讲解,本篇将完整说明后续我们要进行的开发和思路。 主打前端 实际上一个完整的DAPP是由前端和智能…...
docker配置redis容器时配置文件docker-compose.yml示例
1.配置数据节点(主从节点) version: 3.7 services:master:image: redis:5.0.9container_name: redis-masterrestart: alwayscommand: redis-server --appendonly yesports:- 6379:6379slave1:image: redis:5.0.9container_name: redis-slave1restart: a…...
清晰易懂的 Jenkins 安装与核心使用教程
Jenkins 是业界领先的开源自动化服务器,用于实现持续集成与持续交付(CI/CD)。本教程将覆盖 安装部署、核心功能配置、避坑指南,助你快速掌握企业级自动化流水线搭建! 一、Jenkins 安装(全平台指南ÿ…...
anomalib—2—输入图像大小调整
三个地方 第一:在定义model时,要在pre_processor里面去定义一个前处理,前处理就一个功能,定义图像的大小 pre_processor0 Patchcore.configure_pre_processor( image_size (128, 128)) model Patchcore( backbone"wide_r…...
小型园区组网图
1. 在小型园区中,S5735-L-V2通常部署在网络的接入层,S8700-4通常部署在网络的核心,出口路由器一般选用AR系列路由器。 2. 接入交换机与核心交换机通过Eth-Trunk组网保证可靠性。 3. 每个部门业务划分到一个VLAN中,部门间的业务在C…...
编程哲学——TCP可靠传输
TCP TCP可靠传输 TCP的可靠传输表现在 (1)建立连接时三次握手,四次挥手 有点像是这样对话: ”我们开始对话吧“ ”收到“ ”好的,我收到你收到了“ (2)数据传输时ACK应答和超时重传 ”我们去吃…...
2024华为OD机试真题-任务最优调度(C++/Java/Python)-E卷-200分
2024华为OD机试最新E卷题库-(D卷+E卷)-(JAVA、Python、C++) 目录 题目描述 输入描述 输出描述 用例1 考点 题目解析 代码 c++ java python 题目描述 给定一个正整数数组表示待系统执行的任务列表,数组的每一个元素代表一个任务,元素的值表示该任务的类型。请计算执…...
蓝桥杯 2023省B 飞机降落 dfs
传送门 P9241 [蓝桥杯 2023 省 B] 飞机降落 - 洛谷 n<10,考虑dfs,只有当 当前飞机的到达时刻盘旋时间 < 上一个飞机降落的时刻 时,当前飞机才能降落 const int N 1e3 10;int n; struct Node {LL t,d,l; }a[N];bool st[N];bool dfs(in…...
Mybatis--动态SQL
动态SQL是MyBatis的重要特征之一,能够完成不同条件下的SQL拼接,参考文档:动态 SQL_MyBatis中文网 一、<if>标签 该标签主要适用的情况为实现必填字段和非必填字段: 例如下面的例子就是将用户表中的性别设置成了非必填字段…...
计算机视觉中的基于网格的卷绕算法全解析
大家好呀~今天给大家带来一个超级实用且有趣的计算机视觉技巧:基于网格的卷绕算法(Grid Warp Algorithm)!如果你对图像变形、动画制作感兴趣,那一定不要错过这篇文章哦!话不多说,直接…...
xv6 文件系统
Buffer Cache buffer Cache 结构体 bcache 存放了 NBUF 个 buf 框,每个框对应 disk 上某一个 block。从初始化函数 binit中可以看出,bcache 是一个循环双向链表。通过双链表组织这些 buf,以近似 LRU 的策略管理,大概如下图。 st…...
Python Cookbook-5.5 根据内嵌的数字将字符串排序
任务 你想将一个字符串列表进行排序,这些字符串都含有数字的子串(比如一系列邮寄地址)。举个例子,“foo2.txt”应该出现在“foo10.txt”之前。然而,Python 默认的字符串比较是基于字母顺序的,所以默认情况下,“foo10.…...
EMC内参二(1-45页)学习【技术进阶】
EMC设计介入产品设计时间越早,成本越低。 微带线和带状线的区别: 微带线是PCB外层的走线,带状线是结余两个完整参考平面(电源层和地层)之间的走线。 天线效应: PCB上面任何悬空的金属都会积累电荷&…...
Ansible(7)——管理机密
目录 一、Ansible Vault : 二、ansible-vault 命令行工具: 1、创建加密文件: 2、查看加密文件: 3、编辑现有加密文件: 4、加密现有文件: 5、解密现有文件: 6、更改加密文件的密码&#…...
通俗地讲述DDD的设计
通俗地讲述DDD的设计 前言为什么要使用DDDDDD架构分层重构实践关键问题解决方案通过领域事件机制解耦服务依赖:防止逻辑下沉 领域划分电商场景下的领域划分 结语完结撒花,如有需要收藏的看官,顺便也用发财的小手点点赞哈,…...
【学Rust写CAD】34 精确 Alpha 混合函数(argb.rs补充方法)
源码 #[inline]pub fn over_exact(self, dst: Argb) -> Argb {let a 255 - self.alpha32();let t dst.rb() * a 0x80_00_80;let mut rb (t ((t >> 8) & Argb::MASK)) >> 8;rb & Argb::MASK;rb self.rb();// saturaterb | 0x1000100 - ((rb >&…...
10种电阻综合对比——《器件手册--电阻》
二、电阻 前言 10种电阻对比数据表 电阻类型 原理 特点 应用 贴片电阻 贴片电阻是表面贴装元件,通过将电阻体直接贴在电路板上实现电路连接 体积小、重量轻,适合高密度电路板;精度高、稳定性好,便于自动化生产 广泛应用于…...
SpringCloud入门及创建分布式项目
1、了解微服务 1.1 什么是微服务 微服务是一种架构风格一个应用拆分为一组小型服务每个服务运行在自己的进程内,也就是可独立部署和升级服务之间使用轻量级HTTP交互服务围绕业务功能拆分可以由全自动部署机制独立部署去中心化,服务自治。服务可以使用不同…...