嵌入式
文章平均质量分 79
tilblackout
score til you black out.
展开
-
位置无关码PIC详解:原理、动态链接库、代码重定位
本文解释了什么是位置无关代码,以及它如何帮助创建具有可共享只读文本段的共享库。位置无关代码(PIC)通过引入全局偏移表(GOT)和过程链接表(PLT)实现,解决了共享库加载时的重定位问题。GOT提供了数据和函数的间接引用,PLT实现了懒绑定,推迟函数地址的解析。当然这也伴随额外的内存加载和寄存器使用成本,但在权衡之下,现代的编译器都更倾向于使用PIC。原创 2024-01-23 07:00:00 · 3455 阅读 · 0 评论 -
单片机(STM32,GD32,NXP等)中BootLoader的严谨实现详解
Bootloader的主要任务是引导加载并运行应用程序,我们的软件升级逻辑也一般在BootLoader中实现。本文将详细介绍BootLoader在单片机中的实现,包括STM32、GD32、NXP Kinetis等等的所有单片机,因为无论是什么样的芯片,它实现的逻辑都是一样的。原创 2023-12-12 07:00:00 · 10976 阅读 · 4 评论 -
SD/SDIO(2):SDIO协议介绍和初始化流程
1、SDIO卡类型本规范定义了两种类型的SDIO卡。(1)全速支持SPI,1位SD和4位SD传输模式,时钟范围为0-25MHz,数据传输速率超过100Mb/s(2)低速该卡仅有SPI和1位SD传输模式,4位支持是可选的。低速SDIO卡应支持0-400 KHz的时钟范围。低速卡的预期用途是在使用较少引脚的情况下支持低速I/O功能,如调制解调器,条形码扫描器,GPS接收器等。2、SDIO卡模式SPI模式(强制,SDIO 2.0规范开始不强制要求支持SPI)1位SD数据传输模式(强制)原创 2023-10-22 23:28:46 · 3113 阅读 · 0 评论 -
SD/SDIO(1):SD总线协议介绍
SD标准提供了很大的灵活性,除了作为存储卡外,还提供了SD卡槽的标准来扩展设备的功能。本篇文章就先来介绍一下SD总线的规范。本文大致介绍SD总线协议,主要是为了理解SD卡初始化和使用的过程。原创 2023-10-18 21:00:00 · 1820 阅读 · 1 评论 -
嵌入式IDE(2):KEIL中SCF分散加载链接文件详解和实例分析
在上一篇文章中,我通过I.MX RT1170的SDK中的内存映射关系,分析了IAR中的ICF链接文件的语法。对于MCU编程所使用的IDE来说,IAR和Keil用得比较多,所以这一篇文章就来分析一下Keil的分散文件.scf。原创 2023-09-08 01:04:21 · 2707 阅读 · 0 评论 -
嵌入式IDE(1):IAR中ICF链接文件详解和实例分析
Keil和IAR都有自己生成链接脚本的格式,本篇文章就来介绍一下与IAR的链接脚本生成相关的.icf)后缀的IAR配置文件。原创 2023-09-05 22:26:53 · 7102 阅读 · 3 评论 -
一种简单的帧缓冲区管理机制和C语言代码实现
对于有些场景下,我们需要使用帧缓冲区来显示图像,实际上我们可以用一个循环缓冲区标识当前可用的帧,如果多个帧缓冲区的地址是不连续的,那么还需要一个链表结构来保存下一个帧缓冲区的地址。那有没有什么更简单的实现呢?原创 2023-07-20 17:20:17 · 236 阅读 · 0 评论 -
CRC校验(2):CRC32查表法详解、代码实现和CRC反转
对于现在的CPU来说,基本上都在硬件上实现了CRC校验。但我们还是想用软件来实现一下CRC的代码,这样可以更深入地理解里面的原理。所以这一节就来详细地解释如何使用查表法从软件上来实现CRC-32的校验。另外,CRC还有一种反转的情况,实际上反转和不反转没有什么太大的区别,主要是需求和标准的不同。原创 2023-06-15 02:08:57 · 16249 阅读 · 8 评论 -
CRC校验(1):CRC原理、计算例子和最优多项式的选择
CRC校验在做项目的过程中经常会使用到,在我上大学的时候有浅浅地理解这个计算的过程,后面工作了就是直接用NXP SDK中写的软件CRC的代码。说实话,我看不懂这简简单单的几行CRC-32查表算法,但我不希望我只是会用这些函数,而是要理解其中的原理。所以我开始写这一系列的博客深入地研究和理解常见的一些算法,希望能有所收获。对于现在的CPU来说,大多都在硬件上实现了CRC校验,但我想从软件上来实现CRC32的查表算法,包括表格的生成和CRC的计算。原创 2023-06-13 23:56:44 · 8828 阅读 · 2 评论 -
I.MX RT1170:如何在SRAM/SDRAM运行程序
如果程序链接到SDRAM中,我们还需要在镜像头中填充DCD字段,这样BootROM会通过DCD来初始化SDRAM,然后将程序从Flash拷贝到SDRAM中执行。BootROM是上电后一定会运行的BootLoader,而在这期间可能会使能一些中断、外设,然后在跳出的时候恢复最早的没有初始化的状态。对于DAP来说,需要修改这两个地方,一个是指定连接的时候运行我们的初始化SDRAM的脚本,一个是增加。到现在,对于方案②来说,如果你的程序链接在系统的SRAM中,就可以直接点调试开始运行程序了。原创 2023-05-29 00:21:23 · 1425 阅读 · 1 评论 -
I.MX RT1170启动详解:Boot配置、Bootable image头的组成
每次上电的时候都将执行里面的代码,它完成了对于特定引脚上的FlexSPI、SEMC和SDHC接口的初始化,并从这些接口连接到的Flash和RAM中引导程序启动。是NXP提供的一个软件,可以用来生成Bootable image,当然还有一些其它的功能,比如生成可以与Flashloader能识别的指定协议的镜像文件,可以实现修改eFuse、烧录Flash、AES固件加密等功能。其中镜像的绝对起始地址为0x30000000,程序镜像的大小为0x1000000(实际保存的是Flash的大小)。原创 2023-05-28 22:28:19 · 2938 阅读 · 0 评论 -
GCC编译优化选项及汇编优化实例
最近在做LVGL的GUI,移植官方的SDK,然后CPU占用率竟然达到了99%,这就让整个GUI界面的反应十分缓慢。然后我开启了编译器的优化-O3,CPU的使用率降低到了50%,今天来简单介绍一下GCC的编译优化级别。编译器优化级别由命令行选项-On控制,其中n是所需的优化级别。打开优化标志会使编译器提高性能和优化代码大小,但会牺牲编译时间和部分语句的Debug功能。原创 2023-04-15 15:10:42 · 1844 阅读 · 0 评论 -
NXP EDMA学习(3):Scatter/Gather模式之串口循环缓冲区的实现
在实际应用中,循环缓冲区的使用十分广泛,如果DMA每次接收一定字节然后再在中断中写入自己定义的循环缓冲区,这样又失去了使用DMA的意义。所以硬件上的循环缓冲区的实现非常重要。大部分芯片支持DMA循环模式,而NXP的eDMA则可以通过模式来实现硬件循环缓冲区。原创 2023-01-05 15:32:25 · 1337 阅读 · 1 评论 -
NXP EDMA学习(2):串口eDMA接收和发送流程详解
在单片机中,最基础的一个驱动就是串口,本文就以NXP中串口eDMA的收发为例,通过分析源代码来理解eDMA的执行过程。原创 2023-01-04 18:36:23 · 2925 阅读 · 6 评论 -
NXP EDMA学习(1):TCD寄存器详解
eDMA(Enhanced DMA)即增强型DMA,它是NXP芯片中独有的功能,其最重要的一个特性也是eDMA的核心就是TCD(Transfer Control Descriptor)即传输控制描述符。所以,我们就来看一下这个结构体中各个字段的内容的含义,对这些字段有一个基础印象,这样在后续代码中使用到的时候才不会摸不着头脑,到时候再回来看这些寄存器的定义也能理解地更加深刻。该字段分为三种情况,分别为失能次循环映射、使能次循环映射但没有使用和使能次循环映射且使用,不同情况下寄存器中各个位的含义都不同。原创 2023-01-04 18:29:33 · 2406 阅读 · 2 评论 -
C语言 CRC32分段计算实现
最近在写BootLoader过程中,需要对整个二进制文件进行CRC校验然后填写到汇编自定义的偏移处,然后这个保存CRC结果的位置不需要计算,所以从NXP提取了一个CRC校验的代码,可以一段一段将数据加进来校验。原创 2022-11-17 20:53:52 · 2904 阅读 · 0 评论 -
C语言结构体字节对齐的设置 #pragma和__attribute__
CPU不会一个字节一个字节地读或写内存,而是一次访问2/4/6/8/16/32/64字节,因为这比读一个字节要快得多。假设CPU按四字节对齐,我们把四字节称为一个chunk,此时要读内存0x03-0x06的内容,CPU就会读取0x00~0x03和0x04-0x07两个chunk,然后把两个chunk读到的内容移位并组合返回给用户。char b;};CPU就会在结构体最后填充两个字节,以保证字节对齐。原创 2022-11-18 11:36:13 · 1517 阅读 · 0 评论 -
泰凌微BLE实操(1):HCI层事件的注册和使用
断开连接事件属于HCI事件中,所以这里以建立连接和断开连接的事件为例。但是这毕竟是泰凌微官方给的事件,我们还是想知道真正的蓝牙协议中是如何处理这个事件,还有原始的报文是什么样的。是通过HCI将Controller所有的event报告给Host。来处理产生的事件,加入我们连接成功要获得连接句柄。首先我们来看一下在Host或App层接收。其中Octet为拉丁文,即字节,可以看到。原创 2022-11-17 22:31:15 · 924 阅读 · 0 评论 -
NXP BootLoader源码分析并改写SD卡启动
NXP BootLoader的分析并改写为SD启动原创 2022-11-17 14:38:54 · 1506 阅读 · 0 评论 -
C语言实现itoa函数【精简】
由于itoa函数仅在windows中可以使用,在linux中没有相应的函数,这里实现一个itoa函数,包括进制转换功能,正负数都能转换。具体见注释:char* itoa(int value, char* str, int radix) { static char dig[] = "0123456789" "abcdefghijklmnopqrstuvwxyz"; int n = 0, neg = 0; unsigned int v; char原创 2022-05-07 10:27:52 · 1810 阅读 · 0 评论 -
C语言正余弦函数定点查表算法原理及实现
如果用数学库中的sin和cos函数计算,可能涉及浮点、乘法、除法运算,运行速率较低。这里介绍一种正余弦查表算法。参考代码:SMT32 FOC电机库的mc_math.c。首先我们知道正弦和余弦的函数值差了90°,所以查表数据只需要保存正弦或者余弦的结果即可。待计算的角度范围为[0,2π],我们只需要保存的角度,其它象限的角度通过三角函数公式变换一下即可。(1)正余弦表格生成第一步当然是保存范围内正余弦函数的值,保存的越多计算结果越精确,但又消耗更多的存储空间。在STM32电机库中采用int16.原创 2022-04-24 16:21:30 · 11851 阅读 · 13 评论 -
C语言实现memcpy、memset、strcpy、strncpy、strcmp、strncmp、strlen
1、memcpyvoid *memcpy(void *dst, const void *src, unsigned int len){ void * ret = dst; while (len-- > 0) *((char *)dst)++ = *((char *)src)++; return ret;}2、memsetvoid * memset(void * s,char c,size_t count){ char *xs = (char *) s; while (原创 2022-04-21 21:39:55 · 827 阅读 · 0 评论 -
CORDIC算法 arctan反正切计算原理及C语言定点实现
之前做FOC算法的时候,用到了TLV493D磁传感芯片通过两个相差90°的正弦曲线计算角度,所以需要计算arctan的值。这里就基于CORDIC(坐标旋转数字计算方法,Coordinate Rotation Digital Computer)理论,实现一种arctan的定点计算方法。一、原理坐标旋转与FOC中的Park变换原理相同,CORDIC也是通过旋转坐标轴来求解反正切值的。如果去掉cosθ,这样不会影响角度旋转的结果,只是x和y都被缩小了cosθ,这样能简化计算,这称为伪旋原创 2022-04-06 21:12:22 · 9850 阅读 · 2 评论