UID 1
精华
积分 76361
威望 点
宅币 个
贡献 次
宅之契约 份
最后登录 1970-1-1
在线时间 小时
需要的东西:
1、gcc arm toolchain
2、gnu make
3、notepad++ (不喜欢的话你可以选择记事本开发。其实用Office Word也不是不行,但要记得保存为纯文本)
4、STM32F10x的官方头文件声明定义 和PDF
5、ST-LINK Utility 负责完成单片机程序的下载,但你可能需要一个USB接口的ST-LINK来完成此事。
ST-Util下载:https://pan.bai
du.com/s/11bQ7K27hhFxzPnFP
ES3cjw (访问密码:c556)
SHA256:6A200CEAACCBE99B3014F5E61204C40BD550D9E03184BA2988536FAB90D363F3
gcc ARM Toolchain是用于跨平台编译bin的一系列工具,包裹gcc ld objcopy等。我们开发STM32F10x的程序的过程,就是先写好源码,然后用gcc将源码编译为中间文件.o,再用ld把我们的.o链接为elf文件。这elf文件你可以理解为“Linux的exe”。完成链接后,再用objcopy把elf里面的纯代码部分提取出来,也就是纯二进制指令。我们要的是这个纯二进制指令,因为STM32F10x它是单片机,它并不是天生就知道如何识别elf、exe这些复杂的格式的。
为什么gcc不直接把源代码编译为二进制指令呢?这是为了便于模块化编程。当你有多个源码文件的时候,gcc把每个源码文件编译为.o,然后链接器负责把这些多个的源码文件组装到一起,完成互相之间的依赖关系的处理。这也是编译原理的基础。
gcc arm toolchain的下载地址:
https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
打开链接后你会看到它提供了很多种版本的下载方式。其中Windows 32bit的版本有三个,其中有一个带了个“sha1”的后缀,另一个带了“sha2”的后缀。这个是因为这个exe安装器是带了数字签名的,而sha1和sha2是它的数字签名加密算法。使用数字签名是为了保证你下载它的时候黑客不能轻易往里面植入病毒。你可以按照自己的喜好选择其中一个,然后下载下来安装。
gnu make这玩意儿就是Linux里面常见的makefile脚本执行工具,使用它配置编译过程非常方便。它有Windows版本可以给你用。
gnuwin32make的下载地址:
http://gnuwin32.sourceforge.net/packages/make.htm
把gcc arm toolchain和gnuWin32 make安装好以后我们就可以开始搭建编译环境了。
首先我们假定以后就在D盘上保存我们的源码了。我在D盘建立了stm32_proj文件夹用于存储所有和stm32f10x开发相关的东西。
我们以后就打算用makefile来设置编译过程了。为了让makefile能调用gcc arm toolchain里面的工具,我们需要配置一下环境变量。不过我并不想修改我这个系统的全局的环境变量。所以我在D:\stm32_proj里面创建了一个名为env.bat的新的cmd脚本用于调用gnu arm toolchain里面的工具和make。@echo off
set TL_PATH=C:\Program Files (x86)\GNU Tools ARM Embedded\6 2017-q2-update\bin\
set GNU_MAKE=C:\Program Files (x86)\GnuWin32\bin
set PATH=%TL_PATH%;%GNU_MAKE%;%PATH%
cmd /K cd /d %~dp0 复制代码 其中的“6 2017-q2-update”是我的gcc arm toolchain的版本,你要换成你自己的版本。执行完这个脚本后你就会看到CMD的窗口了。在这个里面你就可以调用gcc的工具和makefile了。
这“症状”就是环境变量配置成功了的标志,也就是这个cmd脚本里面的环境变量是OK的,可以调用各种编译工具了。
接下来我们需要的是STM32F10x的官方头文件定义。
点击这里进去下载stsw-stm32054.zip:
http://www.st.com/en/embedded-software/stsw-stm32054.html
懒得去官网下载stsw-stm32054.zip的话,我这里提供下载。但处于各种各样的原因,请回帖再下载。(所以如果是我就去官网下载了,又不难)这玩意儿提供了STM32F10x系列全套的外设的驱动,包括ADC、BKP、CAN、CEC、CRC、DAC、调试工具、DMA、EXTI、FLASH、FSMC、GPIO、I2C、IWDG、电源控制、RCC、实时时钟、SDIO、SPI、计时器、USART、WWDG等。
但它提供的这些外设的驱动写得不咋地,设置一个GPIO针的电平所需的代码就超过了1页,各种程度上都还是自己直接写寄存器比较好。
而为了便于轻松地访问它的寄存器,使用它提供的头文件声明就好。也就是它的stm32f10x.h。
这个stm32f10x.h就在刚才下载的stsw-stm32054.zip里面的STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x目录下。
stm32f10x.h依赖core_cm3.h和system_stm32f10x.h。
core_cm3.h在STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\CoreSupport这里。
我在D:\stm32_proj里面创建了一个叫“common”的目录用来存储每次都可能用到的东西。我在common目录里创建了include目录,然后把刚才提到的stm32f10x.h、core_cm3.h和system_stm32f10x.h都存进去。
这个CMSIS是什么呢?它是Cortex Microcontroller Software Interface Standard,翻译过来是“Cortex单片机软件接口标准”,而“Cortex”的翻译是“皮质”……它应该只是个名字而已。
STM32F10x系列单片机用的是ARM Cortex-M3指令集,支持THUMB,所以自然也是要遵守CMSIS标准的。
根据PDF和CMSIS标准,它的ROM flash的开头部分是一个中断向量表,而且这个中断向量表的第0个项是初始栈顶的值。而STM32F10x根据它的规格,有“低密度”(ROM和RAM都比较小)、“中密度”(ROM和RAM大一些)、“高密度”(ROM和RAM很大)、“超高密度”(RAM和ROM更大……)等不同的规格。这些不同规格的单片机在CMSIS钦定的中断表的后面追加了很多自己特色的中段表项,所以我们还得根据情况来填写这个中断表。
stm32f10x.h这个头文件同时支持多个规格的单片机,但你需要在宏定义里面定义自己的编译目标。以下是它的内容的片段:/* Uncomment the line below according to the target STM32 device used in your
application
*/
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
/* #define STM32F10X_LD */ /*!< STM32F10X_LD: STM32 Low density devices */
/* #define STM32F10X_LD_VL */ /*!< STM32F10X_LD_VL: STM32 Low density Value Line devices */
/* #define STM32F10X_MD */ /*!< STM32F10X_MD: STM32 Medium density devices */
/* #define STM32F10X_MD_VL */ /*!< STM32F10X_MD_VL: STM32 Medium density Value Line devices */
/* #define STM32F10X_HD */ /*!< STM32F10X_HD: STM32 High density devices */
/* #define STM32F10X_HD_VL */ /*!< STM32F10X_HD_VL: STM32 High density value line devices */
/* #define STM32F10X_XL */ /*!< STM32F10X_XL: STM32 XL-density devices */
/* #define STM32F10X_CL */ /*!< STM32F10X_CL: STM32 Connectivity line devices */
#endif
/* Tip: To avoid modifying this file each time you need to switch between these
devices, you can define the device in your toolchain compiler preprocessor.
- Low-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 16 and 32 Kbytes.
- Low-density value line devices are STM32F100xx microcontrollers where the Flash
memory density ranges between 16 and 32 Kbytes.
- Medium-density devices are STM32F101xx, STM32F102xx and STM32F103xx microcontrollers
where the Flash memory density ranges between 64 and 128 Kbytes.
- Medium-density value line devices are STM32F100xx microcontrollers where the
Flash memory density ranges between 64 and 128 Kbytes.
- High-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 256 and 512 Kbytes.
- High-density value line devices are STM32F100xx microcontrollers where the
Flash memory density ranges between 256 and 512 Kbytes.
- XL-density devices are STM32F101xx and STM32F103xx microcontrollers where
the Flash memory density ranges between 512 and 1024 Kbytes.
- Connectivity line devices are STM32F105xx and STM32F107xx microcontrollers.
*/
#if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_XL) && !defined (STM32F10X_CL)
#error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
#endif 复制代码 我的stm32单片机是STM32F103C8T6,所以根据PDF,我应该定义STM32F10X_MD。
有关中段表的详细内容我们看STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm文件夹里面的几个汇编的文件。
我不想引用这几个汇编文件,我要自己用C造轮子。根据它的汇编的文件的内容我发现:绝大多数中断的处理程序,默认都是死循环。然后它导出了弱符号。也就是说只要你自己实现了同名的中断处理函数,那么链接器就会认你的中断处理函数,用它来取代默认的死循环。
其中第1个中断表项是“重启中断”,事实上它定义了你的整个bin的入口点。
因为中断表必须在整个镜像的开始,所以我们需要想办法让gcc toolchain里面的链接器把中断表放到二进制的最开头的位置。解决办法是借助分段机制,把这种需要固定位置的东西装到特殊的段里面,这样我们就可以让链接器把不同的段按照要求放到不同的位置,再完成各种符号依赖的链接。
所以我在源码里面自己定义了一个段“.isr_vector”用来存储中断表。在中断表的后面,我定义了“.after_vectors”段,用于存放默认中断处理向量的内容:死循环。然后就是.text段了,负责存储源代码。
下面是我写好的startup.c和startup.h,有需要的随便下载。
startup.h
(14.83 KB, 下载次数: 3)
startup.c
(22.33 KB, 下载次数: 4)
我们暂且把这个startup称作启动器。那么写好启动器后就是重点了:如何写一个示例程序。
我在启动器里面加了一个对void main();的依赖,并且在“重启中断”里面引用了它。顺带一提重启中断的处理函数,我是把它写成了裸函数,并且在里面调用汇编初始化堆和栈了。
也就是说,只要链接了我的启动器,然后再链接你的主程序,main就是入口了。
我的板子其实买的是源地工作室的STM32F103最小开发板,如下图所示:
它这个的GPIO的C13连接了一个LED,我们通过控制这个GPIO口的电平状态来设置灯的亮与灭的状态,从而实现闪灯程序。也就是说只要运行的效果就是它闪灯了,那么就意味着它没问题了。
在stm32f10x.h里面定义了GPIO的寄存器结构定义,以及A、B、C、D、E、F、G共7组GPIO的寄存器的地址。通过向GPIOC->ODR的第13个bit写入1来实现C13高电平,然后向GPIOC->ODR的第13个bit写入0来实现C13低电平。
STM32F10x系列单片机有bit band区域用于让你能更方便地操作单个bit的值。借助它,你可以免去读取数据->修改->写入的麻烦流程,只需要一步写入就可以修改某个地址的单个bit。
它把每32个bit映射为1个bit,我们只需要向bit band里面写入一个uint32_t的1,那么对应的内存地址的某个bit的值就会变成1。同理我们向bit band对应区域写个0,那么对应bit也会变成0。#include<inttypes.h>
#include"stm32f10x.h"
#define Periph_BB(addr, bit) *(volatile uint32_t*)(PERIPH_BB_BASE + ((uint32_t)(addr) - PERIPH_BASE) * 32 + (bit) * 4)
static void delay(int count)
{
while(--count)
asm("");
}
void main()
{
RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN; // 打开GPIOA和GPIOC
GPIOC->CRH = (GPIOC->CRH & ~(GPIO_CRH_MODE13 | GPIO_CRH_CNF13)) | GPIO_CRH_MODE13_1; // 设置GPIOC13的工作模式:2 MHz,push-pull
while(1)
{
Periph_BB(&GPIOC->ODR, 13) = 1; // 灯灭
delay(262571);
Periph_BB(&GPIOC->ODR, 13) = 0; // 灯亮
delay(0xfff);
}
} 复制代码 注意delay这个函数它是靠跑空循环来实现延时,而gcc会把它优化掉。所以我用一个“asm("");”来避免它被优化掉。事实证明这是有效的,gcc把delay这个函数内联了,但确实没有去掉空循环。
参考:https://stackoverflow.com/questi ... ut-a-busy-wait-loop
可以在IDA里面看到它真的生成了空循环。
接下来是编译过程。为了方便我并没有每次都用那个env.bat去打开控制台窗口然后CD进我的工程。我在工程目录下写了个build.bat用于编译。它会在设置好环境变量后执行make,然后pause,方便看到输出。GCC_PREFIX ?= arm-none-eabi-
CC = $(GCC_PREFIX)gcc
LD = $(GCC_PREFIX)ld
OBJCOPY = $(GCC_PREFIX)objcopy
CFLAGS=-Wall -Wno-main -mcpu=cortex-m3 -mthumb -Os -I../common/include -DSTM32F10X_MD -DUSE_SWD_JTAG -DRELEASE_BUILD
LDFLAGS=-nostdlib -T link.ld
LDLIBS=
foo.bin: foo.elf
$(OBJCOPY) -O binary $^ $@
foo.elf: startup.o foo.o
$(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
.PHONY:clean
clean:
del foo foo.o 复制代码 其中-Wall表示开启全部警告,然后-Wno-main表示“就算我main函数写得不清真也请别警告我”。-mcpu指定了CPU类型,-mthumb指定了thumb指令。-Os表示优先优化体积。
-I指定包含目录为之前设置的common目录里的include目录。后面三个宏定义是之前说好的stm32f10x.h头文件要求的定义,用于指定单片机型号。
链接器参数-nostdlib意为无标准库,-T指定了链接器脚本。
链接器脚本负责告诉链接器,不同的段如何排列,以及重定向相关的内存布局信息等。MEMORY
{
ROM (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
SECTIONS
{
.isr_vector : ALIGN(4)
{
*(.isr_vector)
*(.after_vectors)
}
.text : ALIGN(2)
{
*(.text)
*(.text*)
*(.rodata)
*(.rodata*)
}
.bss :
{
*(.bss)
*(.bss*)
}
} 复制代码 这样编译得到的foo.bin就是我们需要写入到STM32的ROM里面的东西了。
然后用ST-LINK Utility来完成写入操作,就可以启动它看看了。
走调试器单步测试,没有问题。与此同时我也看到了它的灯在闪烁了。
所以,要点有以下几个:
1、中断表必须放在前面,中断表的结构在PDF里面。
2、链接器脚本要写好,它负责帮你把中断表放在前面。
3、完成链接后,用objcopy提取二进制指令就可以写入了。此时你也得到了你想要的bin。
4、用ST-LINK Utility就可以完成二进制指令的写入,以及stm32f10x等各种单片机的调试了。
5、用IDA可以查看编译器是不是真的乖乖地给你生成了你想要的二进制指令。你需要设置处理器为ARM Little-Endian,版本是ARMv7,其它的随默认。然后内存布局写对就行。
配置好的stm32_proj文件夹与示例程序下载:
stm32_proj_foo.zip
(6.93 MB, 下载次数: 4)
另外在IDA调试的时候我想让它把前面那个中断表当作一个uing32_t数组来显示,但一个个按D键下来也是十分累人的。后面我找到一个帖子,说只要选中指定区域,然后执行一个python脚本就行。
参考:https://reverseengineering.stack ... to-words-in-ida-pro
这个脚本的内容如下:ea = SelStart()
end = SelEnd()
print "Making DWORDs from 0x%X - 0x%X" % (ea, end)
MakeUnknown(ea, (end-ea), DOUNK_SIMPLE)
while ea < end:
MakeDword(ea)
ea += 4 复制代码 在选择区块的时候要从下往上选,不然IDA会在你鼠标拖了0x40行左右的时候突然给你飞到底,让你全选;而你要是再想往回拖,IDA又给你突然拖到顶让你一个字节也选不上,只有在反应非常敏捷的情况下非常小心翼翼地拖才能准确拖到指定位置……这UI设计该拉出去毙了。。
复制上面那段python代码的时候注意底部的两行是用TAB缩进的。
startup.h的源码:startup.c的源码:#include"startup.h"
extern void main();
__attribute__((section(".isr_vector"), used))
Handler_t __Vectors[] =
{
(Handler_t)_initial_sp, // Top of Stack
Reset_Handler, // Reset Handler
NMI_Handler, // NMI Handler
HardFault_Handler, // Hard Fault Handler
MemManage_Handler, // MPU Fault Handler
BusFault_Handler, // Bus Fault Handler
UsageFault_Handler, // Usage Fault Handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVC_Handler, // SVCall Handler
DebugMon_Handler, // Debug Monitor Handler
0, // Reserved
PendSV_Handler, // PendSV Handler
SysTick_Handler, // SysTick Handler
#if defined(STM32F10X_LD)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_2_IRQHandler, // ADC1_2
USB_HP_CAN1_TX_IRQHandler, // USB High Priority or CAN1 TX
USB_LP_CAN1_RX0_IRQHandler, // USB Low Priority or CAN1 RX0
CAN1_RX1_IRQHandler, // CAN1 RX1
CAN1_SCE_IRQHandler, // CAN1 SCE
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_IRQHandler, // TIM1 Break
TIM1_UP_IRQHandler, // TIM1 Update
TIM1_TRG_COM_IRQHandler, // TIM1 Trigger and Commutation
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
0, // Reserved
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
0, // Reserved
0, // Reserved
SPI1_IRQHandler, // SPI1
0, // Reserved
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
0, // Reserved
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
USBWakeUp_IRQHandler, // USB Wakeup from suspend
#elif defined(STM32F10X_MD)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_2_IRQHandler, // ADC1_2
USB_HP_CAN1_TX_IRQHandler, // USB High Priority or CAN1 TX
USB_LP_CAN1_RX0_IRQHandler, // USB Low Priority or CAN1 RX0
CAN1_RX1_IRQHandler, // CAN1 RX1
CAN1_SCE_IRQHandler, // CAN1 SCE
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_IRQHandler, // TIM1 Break
TIM1_UP_IRQHandler, // TIM1 Update
TIM1_TRG_COM_IRQHandler, // TIM1 Trigger and Commutation
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C2 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
USBWakeUp_IRQHandler, // USB Wakeup from suspend
#elif defined(STM32F10X_HD)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_2_IRQHandler, // ADC1 & ADC2
USB_HP_CAN1_TX_IRQHandler, // USB High Priority or CAN1 TX
USB_LP_CAN1_RX0_IRQHandler, // USB Low Priority or CAN1 RX0
CAN1_RX1_IRQHandler, // CAN1 RX1
CAN1_SCE_IRQHandler, // CAN1 SCE
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_IRQHandler, // TIM1 Break
TIM1_UP_IRQHandler, // TIM1 Update
TIM1_TRG_COM_IRQHandler, // TIM1 Trigger and Commutation
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C2 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
USBWakeUp_IRQHandler, // USB Wakeup from suspend
TIM8_BRK_IRQHandler, // TIM8 Break
TIM8_UP_IRQHandler, // TIM8 Update
TIM8_TRG_COM_IRQHandler, // TIM8 Trigger and Commutation
TIM8_CC_IRQHandler, // TIM8 Capture Compare
ADC3_IRQHandler, // ADC3
FSMC_IRQHandler, // FSMC
SDIO_IRQHandler, // SDIO
TIM5_IRQHandler, // TIM5
SPI3_IRQHandler, // SPI3
UART4_IRQHandler, // UART4
UART5_IRQHandler, // UART5
TIM6_IRQHandler, // TIM6
TIM7_IRQHandler, // TIM7
DMA2_Channel1_IRQHandler, // DMA2 Channel1
DMA2_Channel2_IRQHandler, // DMA2 Channel2
DMA2_Channel3_IRQHandler, // DMA2 Channel3
DMA2_Channel4_5_IRQHandler, // DMA2 Channel4 & Channel5
#elif defined(STM32F10X_XL)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_2_IRQHandler, // ADC1 & ADC2
USB_HP_CAN1_TX_IRQHandler, // USB High Priority or CAN1 TX
USB_LP_CAN1_RX0_IRQHandler, // USB Low Priority or CAN1 RX0
CAN1_RX1_IRQHandler, // CAN1 RX1
CAN1_SCE_IRQHandler, // CAN1 SCE
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_TIM9_IRQHandler, // TIM1 Break and TIM9
TIM1_UP_TIM10_IRQHandler, // TIM1 Update and TIM10
TIM1_TRG_COM_TIM11_IRQHandler, // TIM1 Trigger and Commutation and TIM11
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C2 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
USBWakeUp_IRQHandler, // USB Wakeup from suspend
TIM8_BRK_TIM12_IRQHandler, // TIM8 Break and TIM12
TIM8_UP_TIM13_IRQHandler, // TIM8 Update and TIM13
TIM8_TRG_COM_TIM14_IRQHandler, // TIM8 Trigger and Commutation and TIM14
TIM8_CC_IRQHandler, // TIM8 Capture Compare
ADC3_IRQHandler, // ADC3
FSMC_IRQHandler, // FSMC
SDIO_IRQHandler, // SDIO
TIM5_IRQHandler, // TIM5
SPI3_IRQHandler, // SPI3
UART4_IRQHandler, // UART4
UART5_IRQHandler, // UART5
TIM6_IRQHandler, // TIM6
TIM7_IRQHandler, // TIM7
DMA2_Channel1_IRQHandler, // DMA2 Channel1
DMA2_Channel2_IRQHandler, // DMA2 Channel2
DMA2_Channel3_IRQHandler, // DMA2 Channel3
DMA2_Channel4_5_IRQHandler, // DMA2 Channel4 & Channel5
#elif defined(STM32F10X_CL)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_2_IRQHandler, // ADC1 and ADC2
CAN1_TX_IRQHandler, // CAN1 TX
CAN1_RX0_IRQHandler, // CAN1 RX0
CAN1_RX1_IRQHandler, // CAN1 RX1
CAN1_SCE_IRQHandler, // CAN1 SCE
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_IRQHandler, // TIM1 Break
TIM1_UP_IRQHandler, // TIM1 Update
TIM1_TRG_COM_IRQHandler, // TIM1 Trigger and Commutation
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C1 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC alarm through EXTI line
OTG_FS_WKUP_IRQHandler, // USB OTG FS Wakeup through EXTI line
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
TIM5_IRQHandler, // TIM5
SPI3_IRQHandler, // SPI3
UART4_IRQHandler, // UART4
UART5_IRQHandler, // UART5
TIM6_IRQHandler, // TIM6
TIM7_IRQHandler, // TIM7
DMA2_Channel1_IRQHandler, // DMA2 Channel1
DMA2_Channel2_IRQHandler, // DMA2 Channel2
DMA2_Channel3_IRQHandler, // DMA2 Channel3
DMA2_Channel4_IRQHandler, // DMA2 Channel4
DMA2_Channel5_IRQHandler, // DMA2 Channel5
ETH_IRQHandler, // Ethernet
ETH_WKUP_IRQHandler, // Ethernet Wakeup through EXTI line
CAN2_TX_IRQHandler, // CAN2 TX
CAN2_RX0_IRQHandler, // CAN2 RX0
CAN2_RX1_IRQHandler, // CAN2 RX1
CAN2_SCE_IRQHandler, // CAN2 SCE
OTG_FS_IRQHandler, // USB OTG FS
#elif defined(STM32F10X_LD_VL)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_IRQHandler, // ADC1
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_TIM15_IRQHandler, // TIM1 Break and TIM15
TIM1_UP_TIM16_IRQHandler, // TIM1 Update and TIM16
TIM1_TRG_COM_TIM17_IRQHandler, // TIM1 Trigger and Commutation and TIM17
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
0, // Reserved
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
0, // Reserved
0, // Reserved
SPI1_IRQHandler, // SPI1
0, // Reserved
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
0, // Reserved
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
CEC_IRQHandler, // HDMI-CEC
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
TIM6_DAC_IRQHandler, // TIM6 and DAC underrun
TIM7_IRQHandler, // TIM7
#elif defined(STM32F10X_MD_VL)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_IRQHandler, // ADC1
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_TIM15_IRQHandler, // TIM1 Break and TIM15
TIM1_UP_TIM16_IRQHandler, // TIM1 Update and TIM16
TIM1_TRG_COM_TIM17_IRQHandler, // TIM1 Trigger and Commutation and TIM17
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C2 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
CEC_IRQHandler, // HDMI-CEC
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
TIM6_DAC_IRQHandler, // TIM6 and DAC underrun
TIM7_IRQHandler, // TIM7
#elif defined(STM32F10X_HD_VL)
WWDG_IRQHandler, // Window Watchdog
PVD_IRQHandler, // PVD through EXTI Line detect
TAMPER_IRQHandler, // Tamper
RTC_IRQHandler, // RTC
FLASH_IRQHandler, // Flash
RCC_IRQHandler, // RCC
EXTI0_IRQHandler, // EXTI Line 0
EXTI1_IRQHandler, // EXTI Line 1
EXTI2_IRQHandler, // EXTI Line 2
EXTI3_IRQHandler, // EXTI Line 3
EXTI4_IRQHandler, // EXTI Line 4
DMA1_Channel1_IRQHandler, // DMA1 Channel 1
DMA1_Channel2_IRQHandler, // DMA1 Channel 2
DMA1_Channel3_IRQHandler, // DMA1 Channel 3
DMA1_Channel4_IRQHandler, // DMA1 Channel 4
DMA1_Channel5_IRQHandler, // DMA1 Channel 5
DMA1_Channel6_IRQHandler, // DMA1 Channel 6
DMA1_Channel7_IRQHandler, // DMA1 Channel 7
ADC1_IRQHandler, // ADC1
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
EXTI9_5_IRQHandler, // EXTI Line 9..5
TIM1_BRK_TIM15_IRQHandler, // TIM1 Break and TIM15
TIM1_UP_TIM16_IRQHandler, // TIM1 Update and TIM16
TIM1_TRG_COM_TIM17_IRQHandler, // TIM1 Trigger and Commutation and TIM17
TIM1_CC_IRQHandler, // TIM1 Capture Compare
TIM2_IRQHandler, // TIM2
TIM3_IRQHandler, // TIM3
TIM4_IRQHandler, // TIM4
I2C1_EV_IRQHandler, // I2C1 Event
I2C1_ER_IRQHandler, // I2C1 Error
I2C2_EV_IRQHandler, // I2C2 Event
I2C2_ER_IRQHandler, // I2C2 Error
SPI1_IRQHandler, // SPI1
SPI2_IRQHandler, // SPI2
USART1_IRQHandler, // USART1
USART2_IRQHandler, // USART2
USART3_IRQHandler, // USART3
EXTI15_10_IRQHandler, // EXTI Line 15..10
RTCAlarm_IRQHandler, // RTC Alarm through EXTI Line
CEC_IRQHandler, // HDMI-CEC
TIM12_IRQHandler, // TIM12
TIM13_IRQHandler, // TIM13
TIM14_IRQHandler, // TIM14
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
TIM5_IRQHandler, // TIM5
SPI3_IRQHandler, // SPI3
UART4_IRQHandler, // UART4
UART5_IRQHandler, // UART5
TIM6_DAC_IRQHandler, // TIM6 and DAC underrun
TIM7_IRQHandler, // TIM7
DMA2_Channel1_IRQHandler, // DMA2 Channel1
DMA2_Channel2_IRQHandler, // DMA2 Channel2
DMA2_Channel3_IRQHandler, // DMA2 Channel3
DMA2_Channel4_5_IRQHandler, // DMA2 Channel4 & Channel5
DMA2_Channel5_IRQHandler, // DMA2 Channel5
#else
#error "missing vectors"
#endif
};
Handler Default_Handler(void)
{
while(1){}
}
register int _reg_sp asm("sp");
void Reset_Handler()
{
do
{
main();
_reg_sp = (int)_initial_sp;
}while(1);
} 复制代码