作者归档:softsim

ARM Vectored Interrupt Controller

支持 32 路中断请求输入

每路输入可配置是否使能,每一路中断输入可配置为 FIQ 或 IRQ

具有一个 FIQ 通道,为了使处理速度最快,务必使只有一个通道设置为 FIQ,优先级最高

具有 32 个 IRQ 通道,每个通路可配置选择哪路中断源输入

32 个通道分为 8 个不同的优先级,

通道 0—3 具有最高的优先级,通道 4—7 具有次高的优先级,依次类推,通道 28—31
具有最低的优先级

相同优先级的 4 个通道之间不能相互打断;

如果同时产生相同优先级的几个通道的中断(比如通道 0—3),会优先执行低通道中断(先执行通道 0,然后通道 1,然后通道 2,最后通道 3)。


中断向量在ARM7处理器中位于0到0x1C地址
为了在不同的操作模式下对中断的替换使用,一小片的Boot块和SRAM空间,需要重新映射。中断向量的重映射是通过内存映射控制特性完成的。

模式 激活条件 用途
boot loader 通过任何复位操作硬件激活 在复位后,boot loader总是被执行。启动块的中断向量被映射到0地址,在boot期间处理异常和使用中断。
Flash模式 通过boot代码,软件激活 在Flash中的有效的用户程序签名被识别出来,且不强制执行boot操作时,就会激活,启动用户程序。中断向量没有重新映射,还是处于Flash的0地址
RAM模式 通过用户程序,软件激活 由用户程序激活。中断向量被映射到SRAM的底部

有些SOC的Boot Block是Boot ROM,

另外一些,还是Flash, 只不过是从整体的Flash重新映射一部到boot block地址空间,比如 LPC213x, BOOT BLOCK(12 kB REMAPPED FROM ON-CHIP FLASH MEMORY) 从0x7FFF D000到0x8000 0000

当一个软件中断(SWI)生成时, ARM内核 总是会从 0x8地址取得一个32位宽的数据。 这意味着, 当MEMMAP[1:0]=10 (RAM模式), 数据实际是由
0x4000 0008地址提供的。 当MEMMAP[1:0]=00 (boot loader模式), 数据由 0x7FFF E008 地址 提供(从芯片上的bootloader映射的boot block)

The flash boot loader code is executed every time the part is powered on or reset. The
loader can execute the ISP command handler or the user application code.

The boot block is 12 kB in size and resides in the top portion (starting from 0x0007 D000) of the on-chip flash memory.

After any reset the entire boot block is also mapped to the top of the on-chip memory space i.e. the boot block is also visible in the memory region starting from the address 0x7FFF D000.

The flash boot loader is designed to run from this memory area but both the ISP and IAP software use parts of the on-chip RAM. The interrupt vectors residing in the boot block of the on-chip flash memory also become active after reset, i.e., the bottom 64 bytes of the boot block are also visible in the memory region starting from the address 0x0000 0000. The reset vector contains a jump instruction to the entry point of the flash boot loader software.

The boot block is present at addresses 0x0007 D000 to 0x0007 FFFF in all devices. ISP and IAP commands do not allow write/erase/go operation on the boot block.
启动块是不能被擦除的

LPC213x Bootloader(启动装载程序)控制复位后的初始化操作,并提供Flash ISP编程接口。它驻留在Flash的最前面的12KB,只能读不能写

同方微电子THC80F09BC

Memory分为ROM, RAM, Flash三种
ROM起始地址 0, 大小 8K
也就是从 0到0x2000

从 0x2000 0000开始,也能访问到ROM

RAM 起始地址 0x0800 0000
0x800 0000 到 0x800 4000, 大小16K

Flash(NorFlash) 起始地址 0x00000000 – 0x03FFFFFF 64M空间,
实际大小0x89000 (548K)

NORFLASH 起始地址为 0x20000000

地址重映射寄存器

SCREMAP 0X30000034 地址重映射寄存器

Flash读写
FLCON0
000 读
001 对一行进行编程
101 擦除一行
110 擦除一页

FLSTS 操作状态


IO管脚复用选择寄存器
FUN_SEL 0X30000044

位         名称       读写      功能
0     gpio_spi_sel      r/w   0=gpio, 1=spi_m
1     保留     
2     iso7816_gpio_sel  r/w   0=7816 slave, 1=gpio
4:3   jtag_gpio_sel     r/w   00=jtag, 01=jtag, 10=gpio, 11=spi_s
6:5   gpio_uart_sel     r/w   00=gpio,01=gpio, 10=uart, 11=7816 master   

LPC213x GPIO设置

首先,选择是传统的寄存器控制,还是增强型控制(增强型,用的CPU本地总线,速度更快)
System Control and Status flags register (SCS)
其中 GPIO0M位 = 0, 表示GPIO 端口0通过传统的APB地址控制寄存器
= 1, 表示GPIO 端口0,高速控制

复位后, GPIO0M =0, 通过APB地址控制

传统的APB访问寄存器有:
IOPIN= 当前的GPIO值
IOSET= 输出设置寄存器,控制输出引脚的状态。写1在对应的引脚产生高电平。
写0,没影响。
IODIR= 方向控制寄存器。决定是输入,还是输出。
IOCLR= 输出清除寄存器。控制输出引脚的状态。写1在对应引脚产生低电平,并且会
清除IOSET寄存器中的对应位。写0,没有影响。


高速端口访问
FIODIR = 快速GPIOS端口方向控制寄存器。
FIOMASK = 掩码寄存器
FIOPIN = 快速GPIO引脚值寄存器。
FIOSET =
FIOCLR =


PINSEL0 功能选择寄存器
配置 端口0的P0.0到P0.15引脚功能

bit1-bit0 = 00 表示 P0.0 的引脚为 GPIO
01 为 UART0的TXD
10 为 PWM1
11 保留

PINSEL0在系统复位后为 0

PINSEL1 配置 端口0 的P0.16到P0.31引脚

AT91SAM7S MCU点亮LED灯

初始化并行输入输出(PIO)控制器

  1. PMC(电源管理控制器)打开 外围时钟. 如果要将IO引脚配置为输出,起始连时钟都可以不打开。如果配置为输入或者要求中断的化,时钟还是必须打开的
  2. 在 AIC里配置 中断源 (可选操作)
  3. 将对应的PIO引脚,配置为输出(output)
    (1) 往PER(PIO Enable Register)寄存器里写入对应的管脚号。
    (2) PIO的方向是由 OER(Output Enable Register)和ODR(Output Disable Regiser)两个寄存器控制的。
  4.  控制引脚电平的高低:通过写 PIO_SODR ( 置位输出数据寄存器 ) 与 PIO_CODR ( 清零输出数据寄存器 ),可将 I/O 改为电平驱动。写操作对 PIO_ODSR ( 输出数据状态寄存器 ) 分别置位与清零,表示在 I/O 线上的数据驱动。

注意,在每个PIO引脚,都有个独立的内部上拉电阻. 这些上拉电阻默认都是启用的。因为它们在点亮LED上没有用。所以,应该被关掉,以减少电量消耗。可以通过PUDR(Pull Up Disable Register)来关掉。

#include "AT91SAM7S256.h"

#define LED_A (1U<<0) // PA0, pin 48
#define LED_B (1U<<1) // PA1, pin 47

/* Configure the pins as outputs */
AT91C_BASE_PIOA->PIO_OER = (LED_A | LED_B);

/* Enable PIOC control on the pins*/
AT91C_BASE_PIOA->PIO_PER = (LED_A | LED_B);

/* Disable pull-ups */
AT91C_BASE_PIOA->PIO_PPUDR = (LED_A | LED_B);

/* Turn LED on, high level */
AT91C_BASE_PIOA->PIO_SODR = LED_A;

/* Turn LED off, low level */
AT91C_BASE_PIOA->PIO_CODR = LED_A;

ST32微控制器GPIO功能描述

每个GPI/O端口有

两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),

两个32位数据寄存器(GPIOx_IDR和GPIOx_ODR),

一个32位置位/复位寄存器(GPIOx_BSRR),

一个16位复位寄存器(GPIOx_BRR)

一个32位锁定寄存器(GPIOx_LCKR)。

每个I/O端口位可以自由编程,然而必须按照32位字访问I/O端口寄存器(不允许半字或字节访
问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器进行读/更改的独立访问;这
样,在读和更改访问之间产生IRQ时不会发生危险。

几种配置GPIO的分析

RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //开启 GPIO端口 C 的时钟

GPIOC->CRH=0x33333333; //将 8-15号 GPIO配置成:输出模式,速度50MHz

GPIOC->ODR ^= (1 << 13) // 13号 GPIO输出 高电平


// I/O port C clock enable
RCC->APB2ENR = RCC_APB2ENR_IOPCEN;
// Set PC_12 to output
GPIOC->CRH &= ~(GPIO_CRH_MODE12 | GPIO_CRH_CNF12);
GPIOC->CRH |= GPIO_CRH_MODE12;

while(1)
{
GPIOC->BSRR = (1<<12);
delay();
GPIOC->BRR = (1<<12);
delay();
}


// Enable GPIO port clock
RCC -> APB2ENR |= RCC_APB2ENR_IOPAEN;
// Configure the pins using CRL/CRH GPIO registers
#define GPIO_OUTPUT_2MHz (0b10)
#define GPIO_OUTPUT_PUSH_PULL (0 << 2)
GPIOA -> CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
GPIOA -> CRL |= GPIO_OUTPUT_2MHz | GPIO_OUTPUT_PUSH_PULL;

// Manipulate the output

/* to toggle */
GPIOA -> ODR ^= (1 << pinNummer);

/* to set */
GPIOA -> BSRR = (1 << pinNummer);

/* to reset */
GPIOA -> BRR = (1 << pinNummer);
//or
GPIOA -> BSRR = (1 << (pinNummer + 16));


RCC->APB2ENR |= 0x10; //enable GPIOC clock
GPIOC->CRH = (GPIOC->CRH & 0xFF0FFFF) | 0x00100000; //PC13 output pull-push, 10MHz speed

GPIOC-> BSRR = 0x00002000; //pc13=1, leave others unchanged
GPIOC->BSRR = 0x20000000; //pc13=0, 其他不变
GPIOC->BSRR = 0x20002000; //pc13=1, 其他不变,设置时,忽略清除

GPIOC->BRR = 0x2000; //pc13=0, 其他不变
GPIOC->ODR = 0x00002000; //pc13=1,并且其他所有都设置为0
GPIOC->ODR |= 0x00002000; //pc13=1, 其他不变
GPIOC->ODR = 0x00000000; //pc13=0, 其他位也强制为0
GPIOC->ODR &= ~0x00002000; //pc12=0, 其他位不变


RCC->APB2ENR |= RCC_APB2ENR_IOPCEN //enable APB2_clock GPIOC
GPIOC->CRH |= GPIO_CRH_MODE13_1 //PC13 output
GPIOC->CRH &= ~GPIO_CRH_CNF13 //PC13 push pull


RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;

GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13_0;

GPIOC->BSRR = GPIO_BSRR_BR13;
sleep(1);
GPIOC->BSRR = GPIO_BSRR_BS13;


RCC->APB2ENR |=
GPIOC->CRH &= ~GPIO_CRH_CNF13;

GPIOC->CRH |= GPIO_CRH_MODE13_0; //set C13 as a general purporse push-pull output

GPIOC->BSRR |= GPIO_BSRR_BR13; // set C13 0

soft_delay(5000000);

GPIOC->BSRR |= GPIO_BSRR_BS13;


// I/O port C clock enable
RCC->APB2ENR = RCC_APB2ENR_IOPCEN;

// Set PC_13 to output
GPIOC->CRH &= ~GPIO_CRH_CNF13;
GPIOC->CRH |= GPIO_CRH_MODE13_0;

while(1)
{
GPIOC->BSRR = GPIO_BSRR_BS13; // LED off
delay(500);

GPIOC->BRR = GPIO_BRR_BR13; // LED on
delay(500);
}

揭开微控制器GPIO设置的神秘面纱

原文 https://embeddedartistry.com/blog/2018/06/04/demystifying-microcontroller-gpio-settings/ 为微控制器编写软件的任何人都必须配置和管理GPIO(通用输入/输出)引脚。从表面上看,GPIO配置看起来很简单:引脚是输入或输出,并且可以为高或低。 但是,不可避免地,您会遇到带有众多配置选项的高档处理器,或者电气工程师会要求您做某种您不了解的引脚设置(比如,使这条线为Hi-Z)。 本指南旨在帮助您了解现代微控制器上提供的不同引脚配置选项。

背景资料

在深入探讨配置选项之前,了解一些与GPIO和IO信号相关的一般描述和术语会很有用。

三态逻辑

大多数现代GPIO线都实现为三态缓冲器。这意味着GPIO线可以有效地采用三个值:
  1. 逻辑0(接地)
  2. 逻辑1(连接到VCC)
  3. 高阻抗(也称为“浮动/悬空”,“ Hi-Z”,“三态”)

高阻抗

当线路处于高阻抗状态时,输出将从电路中有效移除。这允许多个电路或设备共享相同的输出线,并且通常用于实现通信总线。必要时未能利用高阻抗状态会导致IO争用和短路。

浮动/悬空

当信号的状态不确定时,则称该信号为“浮动”,这意味着该信号既未连接至VCC也不接地。信号的电压将“浮动”以匹配残余电压。 术语“浮动”通常 可以同 高阻抗状态 互换使用。

上拉

上拉电阻是将信号连接到VCC的电阻。当信号浮空时,上拉电阻用于设置默认状态。 回想一下,当输入引脚处于高阻抗模式且不受外部电源驱动时,它会浮在残余电压电平上。上拉电阻通过在信号未被主动驱动时将信号强制施加到VCC来防止引脚浮动。当另一个源将信号驱动为低电平(接地)时,上拉电阻被覆盖,输入引脚将读为0。 许多微控制器提供内部上拉配置选项。有时,需要一个特定的上拉电阻值,这需要使用外部上拉而不是芯片的内部上拉。

下拉

下拉电阻是将信号接地的电阻。下拉信号用于在信号浮动时设置默认状态。当另一个信号源将信号驱动为高电平(连接到VCC)时,下拉电阻被覆盖,输入引脚将读为1。 许多微控制器提供内部下拉配置选项。有时,需要特定的下拉电阻值,这需要使用外部下拉电阻而不是芯片的内部下拉电阻。

电流灌入

“灌电流”表示电流正在流入引脚,节点或信号。对于数字IO,current sink提供了到负载的接地连接。

电流源/拉电流

“拉电流”与current sink相反:电流从引脚,节点或信号中流出。对于数字IO,current source为负载提供电压源。 拉电流 和 灌电流 都具有电流流动,但是方向不同。

输入和输出模式

GPIO引脚的主要配置选项是输入输出

GPIO输入模式

将GPIO配置为输入时,可以将其用于读取电信号的状态。将GPIO配置为输入会使该引脚进入高阻抗状态。 通常,主要通过以下三种方式之一配置GPIO输入:
  1. 高阻抗(默认-如果未驱动,则浮动)
  2. 上拉(内部电阻连接到VCC)
  3. 下拉(内部电阻接地)
大多数GPIO输入引脚还具有内部迟滞功能,可防止引脚上的虚假状态改变。通常,迟滞(hysteresis)是内置功能,而不是可配置的设置。

GPIO输出模式

将GPIO配置为输出时,可以将其用于驱动高电平或低电平。GPIO输出主要有两个配置选项:推挽和漏极开路。

推挽输出

在大多数情况下,推挽是默认的GPIO输出设置。推挽式GPIO具有提供和吸收电流的能力。 使用推挽式GPIO,晶体管连接到VCC或GND以驱动高电平或低电平信号。当输出变低时,信号被主动“拉”到地,当输出变高时,信号被主动“推”到VCC。

开漏输出

与推挽不同,开漏输出只能吸收电流。输出具有两种状态:低阻抗和高阻抗。为了在线路上实现逻辑高输出,使用上拉电阻将漏极开路输出连接到所需的输出电压电平。 您可以将漏极开路的GPIO看作是一个接地或断开的开关。 漏极开路GPIO通常可以以两种不同的模式进行配置:
  • 开漏
  • 带内部上拉的漏极开路
大多数利用漏极开路电路的应用都在漏极开路输出上利用外部上拉电路。通常,内部上拉值不足以用于目标电路。 当多个门或引脚连接在一起时,例如通过i2c总线,开漏输出非常有用。当设备不使用总线时,漏极开路输出处于高阻抗模式,并且电压由上拉电阻上拉至高电平。当设备将输出驱动为低电平时,所有连接的线将绑在一起,因此将变为低电平。 开漏输出的另一个常见用途是让多个外部设备驱动微控制器上的单个低电平有效中断引脚。

集电极开路

“集电极开路”在功能上与“漏极开路”相同。“集电极开路”是指在BJT晶体管输出上的电流吸收器,而“开漏”是指在FET输出上的电流吸收器。 我在元器件的数据说明书上遇到的“集电极开路”比在微控制器数据表上遇到的更多。

GPIO速度

GPIO速度控制压摆率,即信号可以在低/高值(“上升时间”和“下降时间”)之间变化的速率。速度配置选项描述为“速度”,“摆率”,“频率”和“高频模式”。 通过提高GPIO速度,可以提高输出电压的变化率(减少上升时间)。但是,电路的功耗和噪声会随着GPIO速度的增加而增加。默认情况下,除非有特殊原因需要提高GPIO速度,否则应将其保持在低速状态。

高驱动

高驱动GPIO是推挽式引脚,能够提供比典型引脚更大的电流。虽然您必须查看每个芯片的数据表以了解引脚的电流容量,但典型的推挽式GPIO可以提供/吸收大约±8mA的电流,而高驱动引脚可以提供/吸收高达±40mA的电流。 高驱动引脚使您的微控制器可以直接驱动需要高于正常电流的IO,例如LED。使用高驱动引脚可以消除外部电流放大电路的需求,从而有助于简化电气设计并降低成本。

用pyOCD和GDB调试micro:bit

安装pyocd apt install openocd python3-pyocd 安装 arm-none-eabi-gdb $ pyocd-gdbserver –persist -t nrf51 -bh -r
0000843:INFO:board:Target type is nrf51
0001221:INFO:dap:DP IDR = 0x0bb11477
0001270:INFO:dap:AP#0 IDR = 0x04770021
0001303:INFO:rom_table:AP#0 ROM table #0 @ 0xf0000000 (designer=244 part=001)
0001329:INFO:rom_table:[0]
0001329:INFO:rom_table: AP#0 ROM table #1 @ 0xe00ff000 (designer=43b part=471)
0001355:INFO:rom_table: [0]
0001373:INFO:rom_table: [1]
0001390:INFO:rom_table: [2]
0001407:INFO:rom_table:[1]
0001424:INFO:cortex_m:CPU core is Cortex-M0 r0p0
0001444:INFO:dwt:2 hardware watchpoints
0001453:INFO:fpb:4 hardware breakpoints, 0 literal comparators
0001480:INFO:semihost:Telnet: server started on port 4444
0001481:INFO:gdbserver:GDB server started at port:3333 https://os.mbed.com/docs/mbed-os/v6.2/debug-test/debug-microbit.html

DAP调试适配器协议

https://microsoft.github.io/debug-adapter-protocol/ 调试适配器协议(DAP)定义了在开发工具(例如IDE或编辑器)和调试器之间使用的抽象协议。

在IDE或编辑器中添加针对新语言的调试器不仅是一项艰巨的工作,而且令人沮丧的是,由于每个工具都使用不同的API来实现相同的功能,因此无法轻易在多个开发工具上分摊此工作。

调试适配器协议(DAP)背后的思想是将开发工具的调试支持与调试器或运行时进行通信的方式抽象为协议。由于假定现有的调试器或运行时在任何时候都采用此协议是不现实的,因此我们假定中介组件(即所谓的调试适配器)使现有的调试器或运行时适应调试适配器协议。

调试适配器协议使为开发工具实现通用调试器成为可能,该工具可以通过调试适配器与不同的调试器进行通信。调试适配器可以在多个开发工具中重复使用,从而大大减少了在不同工具中支持新调试器的工作。

调试适配器协议对调试器提供商和工具提供商而言都是双赢!
CMSIS-DAP是用于将调试端口连接到USB的调试单元的接口固件。 在主机上执行的调试器通过USB连接到调试单元和运行应用程序软件的设备。 调试单元通过JTAG或SW连接到目标设备。 ARM Cortex处理器提供CoreSight调试和跟踪单元。 CMSIS-DAP支持包含一个或多个Cortex处理器的目标设备。 这里,DAP是Debug Access Port的意思 CMSIS-DAP提供了一种通过USB访问ARM Cortex微控制器的Coresight调试访问端口(DAP)的标准化方法。 CMSIS-DAP通常实现为板载接口芯片,通过开发板与一侧运行在主机上的调试器之间通过JTAG(联合测试操作组)或SWD(串行线调试)提供直接USB连接。 目标设备访问另一台上的Coresight DAP。 为什么需要CMSIS-DAP?
有关引入CMSIS-DAP的原因有很多: 在CMSIS-DAP标准之前,许多USB wigglers都实现了自己的协议。使用这种配置,主机调试器必须了解这些不同的协议,并且必须实现所有这些协议,这会产生很多碎片并重新发明轮子。同时,协议通常是在JTAG级别定义的,这意味着它们很慢。 CMSIS-DAP为调试器提供了标准化的接口,该接口在Coresight DAP级别上定义,允许使用标准接口和快速的无驱动程序实现。
借助新的CMSIS-DAP层,主机调试器可以通过SWD或JTAG调试目标,而无需实现这两个协议
USB连接使用HID驱动程序类。由于每个操作系统都内置了HID驱动程序,因此无需在主机上安装特定的驱动程序。 CMSIS-DAP如何集成?
如前所述,CMSIS-DAP必须在接口芯片上实现。该芯片提供了主机计算机(例如,通过USB)和必须调试的目标(通过SWD或JTAG)之间的链接。 CMSIS-DAP标准概述
数据包在主机调试器和接口芯片之间交换。基本上,主机发送命令,调试单元发送命令响应。

主机可以发出不同类型的命令:

通用命令:请求信息并控制调试单元。也用于连接/断开调试单元。
常见的SWD / JTAG命令:例如用于设置时钟速度
SWD特定命令:配置SWD模式的参数
JTAG特定命令:配置JTAG设备链
传输命令:读/写CoreSight寄存器。这些命令与传输方式无关(SWD或JTAG)
示例:通过CMSIS-DAP读取内存
假设调试器需要读取内存中特定位置的值。主机必须发送以下命令:

传输命令:写入CSW寄存器(控制/状态字寄存器)。这将配置传输(32位/ 16位/ 8位传输)
传输命令:使用存储单元的地址写入TAR寄存器(传输地址寄存器)
传输命令:读取DRW寄存器(数据读取/写入寄存器)以读取先前指定位置的值
结论
CMSIS-DAP为调试器提供了标准化的接口。它可能会成为调试器和调试单元将要实现的实际标准。

JTAG/SWD口作为GPIO使用而不能调试

JTAG/SWD口作为GPIO使用 导致无法找到JTAG/W设备, 也就无法下载和调试程序 解决办法: 存储器采用固定的存储器映射,代码区域起始地址为 0x0000 0000(通过 ICode/DCode 总线访问),而 数据区域起始地址为 0x2000 0000(通 过 系 统 总 线 访 问)。Cortex-M4F CPU 始终通过 ICode 总线获取复位向量,这意味着只有代码区域(通常为 Flash)可以提供自举空间。STM32F4xx 微控制器实施一种特殊机制,可以从其它存储器(如内部 SRAM)进行自举。
在 STM32F4xx 中,可通过 BOOT[1:0] 引脚选择三种不同的自举模式 boot0 = 0, 主Flash boot0=1, boot1=0 系统存储器 boot0=1, boot1=1 嵌入式SRAM 复位后,在 SYSCLK 的第四个上升沿锁存 BOOT 引脚的值。复位后,用户可以通过设置BOOT1 和 BOOT0 引脚来选择需要的自举模式。BOOT0 为专用引脚,而 BOOT1 则与 GPIO 引脚共用。一旦完成对 BOOT1 的采样,相应GPIO 引脚即进入空闲状态,可用于其它用途。器件退出待机模式时,还会对 BOOT 引脚重新采样。因此,当器件处于待机模式时,这些引脚必须保持所需的自举模式配置。这样的启动延迟结束后,CPU 将从地址 0x0000 0000 获取栈顶值,然后从始于 0x0000 0004 的自举存储器开始执行代码。 注意:

如果器件从 SRAM 自举,在应用程序初始化代码中,需要使用 NVIC 异常及中断向量表和偏移寄存器来重新分配 SRAM 中的向量表。 64 KB CCM (内核耦合存储器)数据 RAM 不属于总线矩阵, 只能通过 CPU 对其进行访问(CPU D总线) 选择自举引脚后,应用程序软件可以将某些存储器设定为从代码空间进行访问(这样,可通过ICode 总线而非系统总线执行代码)。这样的修改通过在 SYSCFG 控制器中编程 SYSCFG 存储器重映射寄存器 (SYSCFG_MEMRMP) 来实现。
  1. 使用两个位来配置可在地址 0x0000 0000 访问的存储器区域。从而通过软件选择物理重映射,而旁路 BOOT 引脚。
  2. 这两个位的复位值和复位时 BOOT 引脚的设置相同。当 BOOT 引脚设为 10 [(BOOT1,BOOT0)= (1,0)] 从主 Flash 中自举时,寄存器值为 0x00. 也就是boot引脚的值,被忽略,用寄存器的值代替。
灵活的静态存储控制器 (FSMC) 当把 FSMC 重映射到地址 0x0000 0000 时,只有 FSMC 的 Bank1 的前两个区域(NOR/PSRAM 1和 NOR/PSRAM 2)可被重映射到低端地址。在重映射模式下,CPU 可以通过 ICode 总线(而不是 System 总线)访问外部存储器来提高性能。
偏移地址:0x00
复位值:0x0000 000X(X 和 BOOT 引脚的设置相同) STM32F4xx 内核集成了串行 /JTAG 调试端口 (SWJ-DP) 默认调试接口是 JTAG 接口。如果调试工具想要切换到 SW-DP, 它必须在 TMS/TCK(分别映射到 SWDIO 和 SWCLK)
上提供专用的 JTAG 序列, 用于禁止 JTAG-DP 并使能 SW-DP。这样便可仅使用 SWCLK和 SWDIO 引脚来激活 SWDP。
该序列为:
  1. 输出超过 50 个 TCK 周期的 TMS (SWDIO) = 1 信号
  2. 输出 16 个 TMS (SWDIO) 信号 0111100111100111 (MSB)
  3. 输出超过 50 个 TCK 周期的 TMS (SWDIO) = 1 信号
复位(SYSRESETn 或 PORESETn)后,会将用于 SWJ-DP 的全部 5 个引脚指定为专用引
脚,可供调试工具立即使用(请注意,除非由调试工具明确编程,否则不分配跟踪输出)。
但是,STM32F4xx MCU 可以禁止部分或全部 SWJ-DP 端口,进而释放相关引脚以用作通
用 IO (GPIO)。 调试时,主机执行以下操作:
注意:
● 在系统复位状态下,分配所有 SWJ 引脚 (JTAG-DP + SW-DP)。
● 在系统复位状态下,调试主机发送 JTAG 序列,以从 JTAG-DP 切换到 SW-DP。
● 仍然在系统复位状态下,调试主机在复位地址处设置断点。
● 释放复位信号,内核停止在复位地址处。
● 从此所有调试通信均使用 SW-DP 完成。然后通过用户软件将其它 JTAG 引脚重新分配为 GPIO。