面试stm32基础知识

1.ISP

第一步进入bootloader模式:先置BOOT0为高,BOOT1为低,再复位单片机进入bootloader模式,之后通过上位机下载程序;
第二步配置启动代码的地方:代码下载完毕后,置BOOT0为低,BOOT1为低,再复位单片机即可启动用户代码。

STM32三种启动模式

下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存,这就是所谓的启动过程。
1.STM32上电或者复位后,代码区始终从0x00000000开始,其实就是将存储空间的地址映射到0x00000000中。三种启动模式如下:
从主闪存存储器启动,将主Flash地址0x08000000映射到0x00000000,这样代码启动之后就相当于从0x08000000开始。主闪存存储器是STM32内置的Flash,作为芯片内置的Flash,是正常的工作模式。一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接从这启动程序。
2.从系统存储器启动。首先控制BOOT0、BOOT1管脚,复位后,STM32与上述两种方式类似,从系统存储器地址0x1FFF F000开始执行代码。系统存储器是芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段Bootloader,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。启动的程序功能由厂家设置。系统存储器存储的其实就是STM32自带的bootloader代码。
3.从内置SRAM启动,将SRAM地址0x20000000映射到0x00000000,这样代码启动之后就相当于从0x20000000开始。内置SRAM,也就是STM32的内存,既然是SRAM,自然也就没有程序存储的能力了,这个模式一般用于程序调试。假如我只修改了代码中一个小小的地方,然后就需要重新擦除整个Flash,比较的费时,可以考虑从这个模式启动代码,用于快速的程序调试,等程序调试完成后,在将程序下载到SRAM中。

2.储存映射:

4G的地址空间:8块,每块512MB;
在这里插入图片描述
第0块的内容:
在这里插入图片描述
第1块的内容:
在这里插入图片描述

3.GPIO

推挽输出:P管负责灌电流,N管负责拉电流
开漏输出:而在开漏输出模式时,上方的 P-MOS 管完全不工作。如果我们控制输出为 0,低电平,则 P-MOS管关闭,N-MOS 管导通,使输出接地,若控制输出为 1 (它无法直接输出高电平) 时,则 P-MOS管和 N-MOS 管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。为正常使用时必须外部接上拉电阻,参考图开漏电路 中等效电路。它具有“线与”特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接的电源的电压。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0 伏。

GPIO的工作模式:
在这里插入图片描述

4.volatile

C 语言中的关键字“volatile”,在 C 语言中该关键字用于表示变量是易变的,要求编译器不要优化。若没有这个关键字修饰,在某些情况下,编译器认为没有代码修改该变量,就直接从 CPU 的某个缓存获取该变量值,这时可以加快执行速度,但该缓存中的是陈旧数据,与我们要求的寄存器最新状态可能会有出入。加上这个值我们都要求 CPU 每次去该变量的地址重新访问。

用法举例:

  • 中断服务程序中修改的变量需要加 volatile;
  • 全局变量;
  • 多任务环境下各任务间共享的标志应该加 volatile

volatile const int a;
从结果中我们可以看到,编译器然后认为 a 的值为一开始定义的 7,所以对 const a 的操作就会产生上面的情况。所以千万不要轻易对const 变量设法赋值,这会产生意想不到的行为。如果不想让编译器察觉到上面到对 const 的操作,我们可以在 const 前面加上 volatile 关键字。Volatile 关键字跟 const 对应相反,是易变的,容易改变的意思。所以不会被编译器优化,编译器也就不会改变对 a 变量的操作。

5.位段操作

在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。比特位经过膨胀后得到位带别名。

6.启动文件的解析

1. 初始化堆栈指针 SP=_initial_sp
2. 初始化 PC 指针 =Reset_Handler
3. 初始化中断向量表
4. 配置系统时钟
5. 调用 C 库函数 _main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界

https://baijiahao.baidu.com/s?id=1716363537839969540&wfr=spider&for=pc
https://cloud.tencent.com/developer/article/1599577

7.keil的预处理宏:

STM32F10X_HD 宏:为了告诉 STM32 标准库,我们使用的芯片类型是 STM32 型号是大容
量的,使 STM32 标准库根据我们选定的芯片型号来配置。
USE_STDPERIPH_DRIVER 宏:为了让 stm32f10x.h 包含 stm32f10x_conf.h 这个头文件。

8.断言的实现

#ifdef USE_FULL_ASSERT#define assert_param(expr)  ((expr)?(void)0:assert_failed((uint8_t *)__FILE__,__LINE___))void assert_failed(uint8_t *file,uint32_t line);
#else#define assert_param(expr) ((void)0)
#endifvoid assert_failed(uint8_t *file,uint32_t line)
{printf("\r\n 输入参数错误,错误文件名=%s,行号=%d",file,line);
}

9.如何让程序陷入无限循环(C语言)

// for循环
for(;;);
// while 循环
while(1);
// do while
do{}while(1);
// goto方式
state:
goto state;

2.查看can总线入门
3.stm32面试合集
5.第一期。题目开源地址
6.c语言
7.内存泄漏
8.stm32和GD32的区别

10.同步通信和异步通信

数据信号所传输的内容绝大部分就是有效数据,而异步通讯中会包含有帧的各种标识符,所以同步通讯的效率更高,但是同步通讯双方的时钟允许误差较小,而异步通讯双方的时钟允许误差较大。
TTL 逻辑1:2.4-5V
逻辑0:0-0.5V
RS_232 逻辑1:-15~-3V
逻辑0:+3V~+15V
而为了增加串口通讯的远距离传输及抗干扰能力,它使用-15V 表示逻辑 1,+15V 表示逻辑 0。
协议层:
起始位为0 数据位0-位7 校验位 停止位为高
串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑 0 的数据位表示,而数据包的停止信号可由0.5、1、1.5 或 2 个逻辑 1 的数据位表示,只要双方约定
一致即可。

通用同步异步收发器 (Universal Synchronous Asynchronous Receiver and Transmitter) 是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个 UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART。

11.存储器种类

易失性:静态随机存储器SRAM
SSRAM
SRAM
动态随机存储器DRAM:
SDRAM
DDR SDRAM

非易失性:
ROM
EPROM
EEPROM
NORFLASH
NANDFLASH

12.I2C读EEPROM

I2C的时钟和数据线都由主机控制,SCL高采样数据,低时数据切换
当有两个主机就会出现同步和仲裁的问题
同步,低电平由最长低电平周期决定,高电平由最短高电平决定。
仲裁,当SCL和SDA都为高电平时,处于空闲状态,主机们才能进行仲裁,最先输出低电平的仲裁成功。
地址为7位和10位。

13.SPI读写串行FLASH

SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK、MOSI、MISO,片选线。
MOSI 及 MISO 的数据在 SCK 的上升沿期间变化输出,在 SCK 的下降沿时被采样。
[SPI比IIC快]:(https://blog.csdn.net/z1026544682/article/details/90578313)

4.freertos的移植过程

(内核源码,头文件,内存,接口)
1.下载源码
2.拉取FreeRTOSv9.0.0\FreeRTOS\Source的所有.c文件=>>内核源码
3.拉取FreeRTOSv9.0.0\FreeRTOS\Source\portable{\MemMang,\RVDS\ARM_CM3}
4.拉取FreeRTOSv9.0.0\ FreeRTOS\Source\include==》头文件
5.工程中C++配置目录、
6.修改FreeRTOSConfig.h文件,堆栈空间问题,时间节拍
7.修改服务中断函数,stm32f10x_it.c,SysTick_Handler(void)
8.注释掉PendSV_Handler()、SVC_Handler()函数

1.为什么要在中断中进行任务切换

pendsv

freertos的几种状态

就绪 运行 阻塞 挂起

2.中断服务函数的写要求

  1. 中断处理函数的返回值和形参
    中断处理函数不能有返回值和形参,因为中断处理函数都是硬件调用(或者叫触发),没有程序给它传递参数,也没有程序接收它的返回值,其参数的传递通过全局变量的方式。

但是要注意,如果在中断服务函数中改变了供其他函数检测的全局变量的值,要使用volatile关键字定义该全局变量。因为主程序可能将该变量读取到寄存器中,以后每次只使用寄存器中的变量副本,这时候吐过不使用volatile关键字,会导致中断服务函数中修改该变量的操作被短路。

  1. 中断处理函数中进行浮点数运算
    由于浮点运算一般都是由专门的硬件来完成的,硬件设备会牵扯到一些类似全局变量的东西(比如硬件端口,或者硬件设备本身存放的数据),如果浮点运算的过程被中断,而其他函数也可能使用浮点数运算,这就会破坏当前硬件设备中的数据。可以理解为浮点运算一般是不可重入的,因此不能在中断服务函数中使用浮点运算。

可以在满足精度的前提下,将浮点运算扩大若干倍,变成整型运算。

  1. 中断处理函数中使用printf函数
    这个原理跟上面的在中断服务函数中使用浮点数类似,因为printf函数使用硬件资源,而这些资源本身就应该互斥访问(在多线程和多进程中),而这些导致printf函数不可重入,不能在中断中使用。

另外像malloc,free这些函数会使用全局的内存分配表,因此也是不可重入的,不能在中断中使用。

要注意,标准库函数中中很多都是不可重入的,在中断服务函数中要慎重使用它们。

中断服务函数应该是短而有效的。

参考资料:

中断服务函数能不能带形参和返回值?

如何理解这句话:“浮点一般都是不可重入的,printf()经常有重入和性能上的问题”
重入一般可以理解为一个函数在同时多次调用,例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。
一般浮点运算都是由专门的硬件来完成,举个例子假设有个硬件寄存器名字叫做FLOAT,用来计算和存放浮点数的中间运算结果
假设有这么个函数
void fun()
{
//…这个函数对FLOAT寄存器进行操作
}
假如第一次执行,有个对浮点数操作运算的结果临时存在FLOAT寄存器中,而就在这时被中断了,而中断函数或者另一个进程也调用fun函数,这时第二次调用的fun函数在执行的过程中就会破坏第一次FLOAT寄存器中的结果,这样当返回到第一次fun函数的时候,结果就不正确了。

可以把fun函数理解为printf()()函数。

不可重入的问题
把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写他。

其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。

第一,不要使用全局变量。因为别的代码很可能覆盖这些变量值。

第二,在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL来描述。

第三,不能调用任何不可重入的函数。

第四,谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。

还有一些规则,都是很好理解的,总之,时刻记住一句话:保证中断是安全的!

满足下列条件的函数多数是不可重入的:

(1)函数体内使用了静态的数据结构;

(2)函数体内调用了malloc()或者free()函数;

(3)函数体内调用了标准I/O函数。

下面举例加以说明。

可重入函数

void strcpy(char* lpszDest, char* lpszSrc)

{undefined

while(*lpszDest++ = *lpszSrc++);

*dest=0;

}

非可重入函数1

char cTemp; // 全局变量

void SwapChar1(char* lpcX, char* lpcY)

{undefined

cTemp = *lpcX;

*lpcX = *lpcY;

lpcY = cTemp; // 访问了全局变量,在分享内存的多个线程中可能造成问题

}

非可重入函数2

void SwapChar2(char* lpcX, char* lpcY)

{undefined

static char cTemp; // 静态局部变量

cTemp = *lpcX;

*lpcX = *lpcY;

lpcY = cTemp; // 使用了静态局部变量,在分享内存的多个线程中可能造成问题

}

如何写出可重入的函数?在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。

https://blog.csdn.net/maochengtao/article/details/40373039?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-4.pc_relevant_paycolumn_v3&utm_relevant_index=7

Modbus RTU和Modbus ASCII协议应用于串口链接(RS232、RS485、RS422)

FOC

程序跑飞的原因

1、意外中断:是否打开了某个中断,但是没有响应和清除中端标志,导致程序一直进入中断,造成死机假象。
2、中断变量处理不妥:若定义某些会在中断中修改的全局变量,这时要注意两个问题:首先为了防止编译器优化中断变量,要在这些变量定义时前加volatile;其次在主循环中读取中断变量前应该首先关闭全局中断,防止读到一半被中断给修改了,读完之后再打开全局中断,否则出现造成数据乱套。
3、地址溢出,常见错误为指针操作错误:着重说的是数组下标使用循环函数中循环变量,如果循环变量没控制好则会出现数组下标越界,意外修改系统的寄存器造成死机,这种情况下如果死机说明运气好,否则后面不知道发生什么头疼的事。
4、无条件的死循环:比如使用while(x),等待电平变化,正常情况下x都会变成0,就怕万一,因此最好加上时间限制。
5、看门狗没有关闭:有的单片机即使没使用看门狗开机时也有可能意外自动开启了最小周期的看门狗,导致软件不断复位,造成死机。这个要看芯片手册,最好在程序复位后首先应该显式清除看门狗再关闭看门狗。
6、堆栈溢出:最难查找的问题,对于容量小的单片机,尽量减少函数调用层级,减少局部变量,从而减少压栈的时候所需的空间。
当你把以上几条都试过不能解决问题,试一试把你的被调用少函数直接内置到调用的地方并且把占用RAM大的局部变量改成全局变量,试一试说不定就可以了。

堆栈溢出:

内存溢出:

[STM32如何解决堆栈溢出问题及详细分析溢出原因](http://www.openedv.com/forum.php?mod=viewthread&tid=90431)

内存泄漏

两个单片机传输一个浮点数

我们都知道,单片机串口传输的单位是字节,而浮点型数是占四个字节,简单思路是用一个char型指针指向浮点型数据,利用指针寻址即可以将浮点数拆成四个char数据。接收端接收到四个char型数,为了还原成float型数据,采用共用体是一不错的方式。

调试异常

优先级

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

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

相关文章

lambda捕获列表

lambda是C11新特性之一,优点是: 1.可以直接匿名定义目标函数或函数对象,不需要额外写一个函数 2.lambda是一个匿名的内联函数 捕获列表 总结:【】为值捕获,只读 【&】为引用捕获,可读可写

Day104:漏洞发现-漏扫项目篇武装BURP浏览器插件信息收集分析辅助遥遥领先

目录 插件类-武装BurpSuite-漏洞检测&分析辅助 1、如何加载插件: 2、漏洞检测类: Fiora TsojanScan RouteVulScan APIKit 3、分析辅助类: 插件类-武装谷歌浏览器-信息收集&情报辅助 HackBar Heimdallr Wappalyzer FindS…

Linux进阶篇:性能监控工具:socket 统计信息

Linux性能监控工具:socket 统计信息 1 ss命令介绍 ss 是 Socket Statistics 的缩写。ss 命令可以用来获取 socket 统计信息,它显示的内容和 netstat 类似。但 ss 的优势在于它能够显示更多更详细的有关 TCP 和连接状态的信息,而且比 netsta…

ArtCoder——通过风格转换生成多元化艺术风格二维码

简介 ArtCoder能够从原始图像(内容)、目标图像(风格)以及想要嵌入的信息中,生成具有艺术风格的二维码。这一过程类似于通常的图像风格转换,但特别针对二维码的特点进行了优化和调整。 通过这种方法&#…

图像生成模型浅析(Stable Diffusion、DALL-E、Imagen)

目录 前言1. 速览图像生成模型1.1 VAE1.2 Flow-based Model1.3 Diffusion Model1.4 GAN1.5 对比速览 2. Diffusion Model3. Stable Diffusion3.1 Text Encoder3.2 Decoder3.3 Generation Model 总结参考 前言 简单学习下图像生成模型的相关知识🤗 以下内容来自于李宏…

链表传一级指针以及leetcode做题有感

上个文章说要传二级指针,经过一段时间的学习之后才知道可以传一级指针: 之所以要传二级指针,是要改变一级指针的值,也就是把头节点的指针改变,如图: 从左边到右边,头指针 一级指针plist 的值发…

深入理解Transformer技术原理 | 得物技术

谷歌在2017年发布Transformer架构的论文时,论文的标题是:Attention Is All You Need。重点说明了这个架构是基于注意力机制的。 一、什么是注意力机制 在深入了解Transformer的架构原理之前,我们首先要了解下,什么是注意力机制。…

vulfocus靶场redis 未授权访问漏洞之CNVD-2015-07557

目标系统的权限不够redis用户无法写计划任务和公钥,而且也没有开放ssh端口。 主从复制getshell,写入恶意的so文件达到执行系统命令的目的。 github上有一键可以利用的脚本 https://github.com/n0b0dyCN/redis-rogue-server.git 利用条件:需…

逆向案例二十八——红某点集登录接口逆向序

网址:aHR0cHM6Ly93d3cuaHJkanl1bi5jb20vIy9sb2dpbj9yZWRpcmVjdD0lMkZyZWFsVGltZUxpdmluZw 登录接口,发现两个参数加密,分别是pwd和sig,t很明显是时间戳。 观察pwd,发现很像md5加密,我输入的密码是123456,在在线加密网…

day81 session会话 文件上传

知识点: session 文件上传 一 session 1)session:会话 在服务器端存储信息 指客户与服务器的会话 当用户通过浏览器访问服务器的某个页面时,在服务器开辟一个内存空间session 每个session 有唯一的id 2)session过期 …

C——文件操作

1.前言 为什么要使用文件呢? 文件是储存在电脑的磁盘中的,如果没有文件,我们写程序的数据就会存储在电脑的内存中,程序退出,操作系统就会收回内存,数据就丢失了等再次运行程序的时候,是看不到…

【春秋云镜】CVE-2023-43291 emlog SQL注入

靶场介绍 emlog是一款轻量级博客及CMS建站系统,在emlog pro v.2.1.15及更早版本中的不受信任数据反序列化允许远程攻击者通过cache.php组件执行SQL语句。 不感兴趣的可以直接拉到最后面,直接获取flag 备注:没有通过sql注入获取到flag&…

汇编语言——将DX,AX组成的32位数逻辑左移3位

data segment data ends stack segment stacktop label worddw 100 dup (?) stack ends code segmentassume cs:code,ds:data,ss:stack main proc farmov ax,datamov ds,axmov ax,stackmov ss,axlea sp,top;0000 0001 1100 1010 | 0000 0010 0001 1111;逻辑左移三位后&#xf…

基于SpringBoot框架的智慧食堂

采用技术 基于SpringBoot框架实现的web的智慧社区系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringBootMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统功能 系统首页 用户注册页面 菜品信息页面 …

Android 性能优化(七):APK安装包体积优化

包体积优化重要性 移动 App 特别关注投放转化率指标,而 App 包体积是影响用户新增的重要因素,而 App 的包体积又是影响投放转化率的重要因素。 Google 2016 年公布的研究报告显示,包体积每上升 6MB 就会带来下载转化率降低 1%, …

直方图与核密度估计

技术背景 直方图是一种经常被用于统计的图形表达形式,简单来说它的功能就是用一系列的样本数据,去分析样本的分布规律。而直方图跟核密度估计(Kernel Density Estimation,KDE)方法的主要差别在于,直方图得到的是一个离散化的统计分…

【全开源】多功能完美运营版商城 虚拟商品全功能商城 全能商城小程序 智慧商城系统 全品类百货商城

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 完美运营版商城/拼团/团购/秒杀/积分/砍价/实物商品/虚拟商品等全功能商城 干干净净 没有一丝多余收据 还没过手其他站 还没乱七八走的广告和后门 后台可以自由拖曳修改前端UI页面 …

Aigtek功率放大器的使用方法有哪些

功率放大器是一种将小信号放大为大信号的电子设备,广泛应用于无线通信、音频系统、雷达等领域。在使用功率放大器时,需要注意以下几个方面: 电源供应:功率放大器需要提供稳定的电源供应以保证正常工作。通常情况下,功率…

正式发布的Spring AI,能让Java喝上AI赛道的汤吗

作者:鱼仔 博客首页: https://codeease.top 公众号:Java鱼仔 前言 最近几年AI发展实在太快了,仿佛只要半年没关注,一个新的大模型所产生的效果就能超越你的想象。Java在AI这条路上一直没什么好的发展,不过Spring最近出来了一个新的模块叫做S…

[Linux][进程间通信][一][匿名管道][命名管道]详细解读

目录 0.进程间通信?1.进程间通信目的2.进程间通信分类3.进程间通信的本质理解 1.什么是管道?2.匿名管道1.认识函数2.如何让不同的进程,看到同一份资源?3.用fork来共享管道原理4.站在文件描述符角度 -- 深刻理解管道5.站在内核角度…