美文网首页
嵌入式:STM32

嵌入式:STM32

作者: 我在等你回复可你没回 | 来源:发表于2019-11-02 12:46 被阅读0次

STM32 启动流程是怎样的?

根据启动模式,从不同的存储器加载程序运行。
STM32的启动代码在startup_stm32f10x_xx.s(xx根据微控制器所带的大、中、小容量存储器分别为hd、md、ld)中,其中的程序功能主要包括初始化堆栈、定义程序启动地址、中断向量表和中断服务程序入口地址,以及系统复位启动时,从启动代码跳转到用户main函数的入口地址。


image.png

原文链接:https://blog.csdn.net/wwt18811707971/article/details/78678059

SRAM和RAM的区别?

SRAM是静态RAM,速度快,价格贵。

SWD下载和调试程序时,boot引脚要怎么连接?

貌似不影响。

ISP是什么意思?

ISP(in-system programming)--在线系统编程

STM32的中断处理时怎样的?

从地址80000000开始执行,然后跑到reset中断,然后跳到main函数。
参考:https://www.cnblogs.com/long5683/p/9638866.html

STM32 IAP官方例子

https://www.st.com/en/embedded-software/x-cube-iap-usart.html

串口怎么判断数据结束的?

通过结束位和开始位,结束时高电平,如果后面继续时高电平,说明本次结束了。如果时低电平,说明是下一个数据到了。

HAL_Delay实现原理?

在一个while循环里面等待SysTick的滴答计时到达。注意不能放在中断里面,否则会卡死。

stm32 几个关键的地址

外设起始地址

define PERIPH_BASE 0x40000000UL /*!< Peripheral base address in the alias region */

define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000UL)

define USART1_BASE (APB2PERIPH_BASE + 0x1000UL)

所以串口1的地址是0x40000000UL + 0x00010000UL + 0x1000UL = 0x40011000

typedef struct
{
__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 /
__IO uint32_t DR; /
!< USART Data register, Address offset: 0x04 /
__IO uint32_t BRR; /
!< USART Baud rate register, Address offset: 0x08 /
__IO uint32_t CR1; /
!< USART Control register 1, Address offset: 0x0C /
__IO uint32_t CR2; /
!< USART Control register 2, Address offset: 0x10 /
__IO uint32_t CR3; /
!< USART Control register 3, Address offset: 0x14 /
__IO uint32_t GTPR; /
!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;
可以看到,限制都是通过结构体的方式来操作寄存器了。

有什么常见的简称?

Interrupt Request,简称IRQ
NMI,不可屏蔽中断

什么是临界段代码?

代码的临界段也称为临界区,一旦这部分代码开始执行,则不允许任何中断打断。

stm32 如何关闭中断?

vPortRaiseBASEPRI

MRS与MSR寄存器是什么?

MRS: 状态寄存器到通用寄存器的传送指令。
MSR: 通用寄存器到状态寄存器的传送指令。

BASEPRI是什么?

设置为n后,屏蔽所有优先级数值大于等于n的中断和异常。Cortex-M的优先级数值越大其优先级越低。
参考:https://www.cnblogs.com/qiyuexin/p/8921718.html

HAL_NVIC_SetPriority的函数输入是怎么对应优先级的?

值越小,优先级越高

FreeRTOS任务切换过程?

https://blog.csdn.net/jiejiemcu/article/details/81039707

串口中断发送方式是怎样的?

起始就是给usart结构体先赋值,然后开中断
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
一个个字节赋值给DR寄存器,然后发出去。

STM32为什么要把代码烧到flash的0x0800000中去?

STM32开机会进行地址映射,在访问0x0000000时,会通过memmap,转换成0x08000000,进而访问flash。

image.png
要记住两个关键的地址:flash起始地址:0x08000000, ram起始地址0x20000000
至于为什么要写到0x08000000,据说时这样就有两个地址对应同一个物理地址,可以加快访问速度。例如(0x00000000和0x08000000都是对应flash的0x08000000地址)
参考:https://blog.csdn.net/weixin_42231514/article/details/106178653?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242

stm32一个字是多少字节?

stm32是32位的,所以一个字是32位,4个字节。

FreeRTOS的启动原理

通过pendsv和systick中断,来进行切换的。

FreeRTOS临界区怎么操作

使用vPortEnterCritical,进而是调用vPortRaiseBASEPRI(),
实际是把寄存器basepri的值设置成了0x50了

Stm32 HAL库一般是怎么管理寄存器的?

一般是结构体管理,每个结构体都有一个基地址
例如系统配置寄存器

#define SCB                 ((SCB_Type       *)     SCB_BASE      )   /*!< SCB configuration struct */


typedef struct
{
  __IM  uint32_t CPUID;                  /*!< Offset: 0x000 (R/ )  CPUID Base Register */
  __IOM uint32_t ICSR;                   /*!< Offset: 0x004 (R/W)  Interrupt Control and State Register */
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
  __IOM uint32_t VTOR;                   /*!< Offset: 0x008 (R/W)  Vector Table Offset Register */
#else
        uint32_t RESERVED0;
#endif
  __IOM uint32_t AIRCR;                  /*!< Offset: 0x00C (R/W)  Application Interrupt and Reset Control Register */
  __IOM uint32_t SCR;                    /*!< Offset: 0x010 (R/W)  System Control Register */
  __IOM uint32_t CCR;                    /*!< Offset: 0x014 (R/W)  Configuration Control Register */
        uint32_t RESERVED1;
  __IOM uint32_t SHPR[2U];               /*!< Offset: 0x01C (R/W)  System Handlers Priority Registers. [0] is RESERVED */
  __IOM uint32_t SHCSR;                  /*!< Offset: 0x024 (R/W)  System Handler Control and State Register */
} SCB_Type;

就规定了SCB这个SCB_Type结构体实例的地址是SCB_BASE

使能中断,实际修改的是什么寄存器呢?

HAL_NVIC_EnableIRQ修改的是ISER寄存器

FreeRTOS进行bootloader跳转时,需要注意什么?

需要关闭中断,一般我们都会关闭外设的中断,但其实了解FreeRTOS的切换任务流程后,可以知道任务切换时依赖systick中断的,所以我们一定要把systick中断也关闭掉。不然如果我们在app一开始调用__enable_irq()的时候,就会找不到中断处理函数,然后跑飞。关闭systick中断:
SysTick->CTRL = SysTick->CTRL & 0xFFFFFF00;

FreeRTOS的systick中断是在函数vPortSetupTimerInterrupt()中使能的。

stm32和freeRTOS的堆栈是怎样管理的?

在有freeRTOS时,他的map文件如下,可以看到堆栈时从0x0000000020015858开始,因为ram的基地址是0x0000000020000000,所以FreeRTOS总共占用了0x15858,转成10进制,约等于80K。从80K后面的就不属于freeRTOS管理。


image.png

从图片可以看出,堆和栈的空间是完全分开的。
这些不受freeRTOS管理的内存。
栈地址是:
0x0000000020015e58 到 0x0000000020015a58 可以看到是向下生长的。

堆地址是:
0x0000000020015858 到 0x0000000020015a58 可以看到是向上生长的。

下图是一个栈数据溢出到堆区,然后被堆区数据memset为0后,出现hard fatal的实际例子。


image.png

FreeRTOS堆和栈的配置如下,也可以单独配置Task的栈大小


堆栈配置.png 单独配置任务栈的大小.png

什么是freertos的优先级继承?

就是低优先级A的拿到互斥锁之后,然后一个高优先级的任务B要来拿锁,但A现在持有,所以B只能挂起来,为了尽快拿到锁,得让低优先级尽快跑完,不然任务B可能一直阻塞(如果来了个比B低优先级的任务C,因为B在阻塞,C就先跑了,这就导致了优先级反转,明明B优先级高,却任务C先跑),于是系统就把A的优先级调高到B的水平。

相关文章

网友评论

      本文标题:嵌入式:STM32

      本文链接:https://www.haomeiwen.com/subject/xuopyctx.html