STM32F1 标准库源码阅读

CM3 内核文件 #

core_cm3.h #

文件Libraries/CMSIS/CM3/CoreSupport/core_cm3.h
  1#ifndef __CM3_CORE_H__
  2#define __CM3_CORE_H__
  3
  4#ifdef __cplusplus                          // 如果使用 C++ 编译器,使用 C 链接约定
  5    extern "C" {
  6#endif 
  7
  8#define __CM3_CMSIS_VERSION_MAIN  (0x01)    // [31:16] CMSIS HAL 主版本号(Hardware Abstraction Layer)
  9#define __CM3_CMSIS_VERSION_SUB   (0x30)    // [15:0]  CMSIS HAL 子版本号
 10#define __CM3_CMSIS_VERSION       ((__CM3_CMSIS_VERSION_MAIN << 16) | __CM3_CMSIS_VERSION_SUB)    // CMSIS HAL 版本号
 11
 12#define __CORTEX_M                (0x03)    // Cortex 核心
 13
 14#include <stdint.h>                         // 包含标准整数类型
 15
 16#if defined (__ICCARM__)
 17    #include <intrinsics.h>                 // IAR 内置函数
 18#endif
 19
 20#ifndef __NVIC_PRIO_BITS
 21    #define __NVIC_PRIO_BITS    4           // NVIC 优先级寄存器实际可用位,STM32F1 系列有 4 位(16级)
 22#endif
 23
 24
 25/****************************************************************************************************
 26 *                                IO 定义: 对外设寄存器的访问限制 
 27 ***************************************************************************************************/
 28
 29#ifdef __cplusplus
 30    #define  __I     volatile              // 定义'只读'权限
 31#else
 32    #define  __I     volatile const        // 定义'只读'权限
 33#endif
 34#define      __O     volatile              // 定义'只写'权限
 35#define      __IO    volatile              // 定义'读/写'权限
 36
 37
 38
 39/****************************************************************************************************
 40 *                                           寄存器抽象 
 41 ***************************************************************************************************/
 42
 43typedef struct                              // 嵌套向量中断控制器的内存映射结构 Nested Vectored Interrupt Controller (NVIC)
 44{
 45    __IO uint32_t ISER[8];                  // 偏移: 0x000 中断设置使能寄存器  Interrupt Set Enable Register
 46         uint32_t RESERVED0[24];                                 
 47    __IO uint32_t ICER[8];                  // 偏移: 0x080 中断清除使能寄存器  Interrupt Clear Enable Register
 48         uint32_t RSERVED1[24];
 49    __IO uint32_t ISPR[8];                  // 偏移: 0x100 中断设置挂起寄存器  Interrupt Set Pending Register 
 50         uint32_t RESERVED2[24];                                 
 51    __IO uint32_t ICPR[8];                  // 偏移: 0x180 中断清除挂起寄存器  Interrupt Clear Pending Register
 52         uint32_t RESERVED3[24];                                 
 53    __IO uint32_t IABR[8];                  // 偏移: 0x200 中断活动位寄存器    Interrupt Active bit Register
 54         uint32_t RESERVED4[56];                                 
 55    __IO uint8_t  IP[240];                  // 偏移: 0x300 中断优先级寄存器    Interrupt Priority Register (8Bit wide)
 56         uint32_t RESERVED5[644];                                
 57    __O  uint32_t STIR;                     // 偏移: 0xE00 软件触发中断寄存器  Software Trigger Interrupt Register
 58}  NVIC_Type;                                               
 59
 60typedef struct                              // 系统控制块的内存映射结构                System Control Block (SCB)
 61{
 62    __I  uint32_t CPUID;                    // 偏移: 0x00 CPU ID 基地址寄存器          CPU ID Base Register
 63    __IO uint32_t ICSR;                     // 偏移: 0x04 中断控制和状态寄存器         Interrupt Control State Register
 64    __IO uint32_t VTOR;                     // 偏移: 0x08 向量表偏移寄存器             Vector Table Offset Register
 65    __IO uint32_t AIRCR;                    // 偏移: 0x0C 应用中断/复位控制寄存器      Application Interrupt / Reset Control Register
 66    __IO uint32_t SCR;                      // 偏移: 0x10 系统控制寄存器               System Control Register
 67    __IO uint32_t CCR;                      // 偏移: 0x14 配置控制寄存器               Configuration Control Register
 68    __IO uint8_t  SHP[12];                  // 偏移: 0x18 系统处理程序优先级寄存器     System Handlers Priority Registers (4-7, 8-11, 12-15)
 69    __IO uint32_t SHCSR;                    // 偏移: 0x24 系统处理程序控制和状态寄存器 System Handler Control and State Register
 70    __IO uint32_t CFSR;                     // 偏移: 0x28 可配置故障状态寄存器         Configurable Fault Status Register
 71    __IO uint32_t HFSR;                     // 偏移: 0x2C 硬件故障状态寄存器           Hard Fault Status Register
 72    __IO uint32_t DFSR;                     // 偏移: 0x30 调试故障状态寄存器           Debug Fault Status Register
 73    __IO uint32_t MMFAR;                    // 偏移: 0x34 内存管理地址寄存器           Mem Manage Address Register
 74    __IO uint32_t BFAR;                     // 偏移: 0x38 总线故障地址寄存器           Bus Fault Address Register
 75    __IO uint32_t AFSR;                     // 偏移: 0x3C 辅助故障状态寄存器           Auxiliary Fault Status Register
 76    __I  uint32_t PFR[2];                   // 偏移: 0x40 处理器特性寄存器             Processor Feature Register
 77    __I  uint32_t DFR;                      // 偏移: 0x48 调试特性寄存器               Debug Feature Register
 78    __I  uint32_t ADR;                      // 偏移: 0x4C 辅助特性寄存器               Auxiliary Feature Register
 79    __I  uint32_t MMFR[4];                  // 偏移: 0x50 内存模型特性寄存器           Memory Model Feature Register
 80    __I  uint32_t ISAR[5];                  // 偏移: 0x60 指令集架构特性寄存器         ISA Feature Register
 81} SCB_Type;                                                
 82
 83// SCB CPUID 寄存器定义
 84#define SCB_CPUID_IMPLEMENTER_Pos          24                                          // 厂商 ID
 85#define SCB_CPUID_IMPLEMENTER_Msk          (0xFFul << SCB_CPUID_IMPLEMENTER_Pos)
 86#define SCB_CPUID_VARIANT_Pos              20                                          // 主版本号
 87#define SCB_CPUID_VARIANT_Msk              (0xFul << SCB_CPUID_VARIANT_Pos)
 88#define SCB_CPUID_PARTNO_Pos                4                                          // 部件号
 89#define SCB_CPUID_PARTNO_Msk               (0xFFFul << SCB_CPUID_PARTNO_Pos)
 90#define SCB_CPUID_REVISION_Pos              0                                          // 修订号
 91#define SCB_CPUID_REVISION_Msk             (0xFul << SCB_CPUID_REVISION_Pos)
 92
 93// SCB 中断控制状态寄存器定义
 94#define SCB_ICSR_NMIPENDSET_Pos            31                                          // NMI 挂起设置位
 95#define SCB_ICSR_NMIPENDSET_Msk            (1ul << SCB_ICSR_NMIPENDSET_Pos)
 96#define SCB_ICSR_PENDSVSET_Pos             28                                          // PendSV 设置位
 97#define SCB_ICSR_PENDSVSET_Msk             (1ul << SCB_ICSR_PENDSVSET_Pos)
 98#define SCB_ICSR_PENDSVCLR_Pos             27                                          // PendSV 清除位
 99#define SCB_ICSR_PENDSVCLR_Msk             (1ul << SCB_ICSR_PENDSVCLR_Pos)
100#define SCB_ICSR_PENDSTSET_Pos             26                                          // SysTick 挂起设置位
101#define SCB_ICSR_PENDSTSET_Msk             (1ul << SCB_ICSR_PENDSTSET_Pos)
102#define SCB_ICSR_PENDSTCLR_Pos             25                                          // SysTick 挂起清除位
103#define SCB_ICSR_PENDSTCLR_Msk             (1ul << SCB_ICSR_PENDSTCLR_Pos)
104#define SCB_ICSR_ISRPREEMPT_Pos            23                                          // ISR 抢占位
105#define SCB_ICSR_ISRPREEMPT_Msk            (1ul << SCB_ICSR_ISRPREEMPT_Pos)
106#define SCB_ICSR_ISRPENDING_Pos            22                                          // 外部中断挂起位
107#define SCB_ICSR_ISRPENDING_Msk            (1ul << SCB_ICSR_ISRPENDING_Pos)
108#define SCB_ICSR_VECTPENDING_Pos           12                                          // 当前挂起的中断异常编号
109#define SCB_ICSR_VECTPENDING_Msk           (0x1FFul << SCB_ICSR_VECTPENDING_Pos)
110#define SCB_ICSR_RETTOBASE_Pos             11                                          // 返回到基址位
111#define SCB_ICSR_RETTOBASE_Msk             (1ul << SCB_ICSR_RETTOBASE_Pos)
112#define SCB_ICSR_VECTACTIVE_Pos             0                                          // 当前中断异常编号
113#define SCB_ICSR_VECTACTIVE_Msk            (0x1FFul << SCB_ICSR_VECTACTIVE_Pos)
114
115// SCB 向量表偏移寄存器定义
116#define SCB_VTOR_TBLBASE_Pos               29                                          // 向量表基地址位(0:代码区,1:RAM)
117#define SCB_VTOR_TBLBASE_Msk               (0x1FFul << SCB_VTOR_TBLBASE_Pos)
118#define SCB_VTOR_TBLOFF_Pos                 7                                          // 基地址偏移
119#define SCB_VTOR_TBLOFF_Msk                (0x3FFFFFul << SCB_VTOR_TBLOFF_Pos)
120
121// SCB 应用中断和复位控制寄存器定义
122#define SCB_AIRCR_VECTKEY_Pos              16                                          // 向量键,写入 AIRCR 寄存器时必须写入 0x5FA 到 VECTKEY
123#define SCB_AIRCR_VECTKEY_Msk              (0xFFFFul << SCB_AIRCR_VECTKEY_Pos)
124#define SCB_AIRCR_VECTKEYSTAT_Pos          16                                          // 向量键状态
125#define SCB_AIRCR_VECTKEYSTAT_Msk          (0xFFFFul << SCB_AIRCR_VECTKEYSTAT_Pos)
126#define SCB_AIRCR_ENDIANESS_Pos            15                                          // 字节大小端
127#define SCB_AIRCR_ENDIANESS_Msk            (1ul << SCB_AIRCR_ENDIANESS_Pos)
128#define SCB_AIRCR_PRIGROUP_Pos              8                                          // 优先级分组
129#define SCB_AIRCR_PRIGROUP_Msk             (7ul << SCB_AIRCR_PRIGROUP_Pos)
130#define SCB_AIRCR_SYSRESETREQ_Pos           2                                          // 系统复位请求位
131#define SCB_AIRCR_SYSRESETREQ_Msk          (1ul << SCB_AIRCR_SYSRESETREQ_Pos)
132#define SCB_AIRCR_VECTCLRACTIVE_Pos         1                                          // 清除活动向量位
133#define SCB_AIRCR_VECTCLRACTIVE_Msk        (1ul << SCB_AIRCR_VECTCLRACTIVE_Pos)
134#define SCB_AIRCR_VECTRESET_Pos             0                                          // 向量复位位
135#define SCB_AIRCR_VECTRESET_Msk            (1ul << SCB_AIRCR_VECTRESET_Pos)
136
137// SCB 系统控制寄存器定义
138#define SCB_SCR_SEVONPEND_Pos               4                                          // 挂起时发送事件位
139#define SCB_SCR_SEVONPEND_Msk              (1ul << SCB_SCR_SEVONPEND_Pos)
140#define SCB_SCR_SLEEPDEEP_Pos               2                                          // 深度睡眠位
141#define SCB_SCR_SLEEPDEEP_Msk              (1ul << SCB_SCR_SLEEPDEEP_Pos)
142#define SCB_SCR_SLEEPONEXIT_Pos             1                                          // 退出时睡眠位
143#define SCB_SCR_SLEEPONEXIT_Msk            (1ul << SCB_SCR_SLEEPONEXIT_Pos)
144
145// SCB 配置控制寄存器定义
146#define SCB_CCR_STKALIGN_Pos                9                                          // 栈对齐位
147#define SCB_CCR_STKALIGN_Msk               (1ul << SCB_CCR_STKALIGN_Pos)
148#define SCB_CCR_BFHFNMIGN_Pos               8                                          // 总线故障、硬件故障和 NMI 忽略位
149#define SCB_CCR_BFHFNMIGN_Msk              (1ul << SCB_CCR_BFHFNMIGN_Pos)
150#define SCB_CCR_DIV_0_TRP_Pos               4                                          // 除零陷阱位
151#define SCB_CCR_DIV_0_TRP_Msk              (1ul << SCB_CCR_DIV_0_TRP_Pos)
152#define SCB_CCR_UNALIGN_TRP_Pos             3                                          // 非对齐访问陷阱位
153#define SCB_CCR_UNALIGN_TRP_Msk            (1ul << SCB_CCR_UNALIGN_TRP_Pos)
154#define SCB_CCR_USERSETMPEND_Pos            1                                          // 用户级设置挂起位
155#define SCB_CCR_USERSETMPEND_Msk           (1ul << SCB_CCR_USERSETMPEND_Pos)
156#define SCB_CCR_NONBASETHRDENA_Pos          0                                          // 非基级线程使能位
157#define SCB_CCR_NONBASETHRDENA_Msk         (1ul << SCB_CCR_NONBASETHRDENA_Pos)
158
159// SCB 系统处理程序控制和状态寄存器定义
160#define SCB_SHCSR_USGFAULTENA_Pos          18                                          // 用法故障使能位
161#define SCB_SHCSR_USGFAULTENA_Msk          (1ul << SCB_SHCSR_USGFAULTENA_Pos)
162#define SCB_SHCSR_BUSFAULTENA_Pos          17                                          // 总线故障使能位
163#define SCB_SHCSR_BUSFAULTENA_Msk          (1ul << SCB_SHCSR_BUSFAULTENA_Pos)
164#define SCB_SHCSR_MEMFAULTENA_Pos          16                                          // 内存故障使能位
165#define SCB_SHCSR_MEMFAULTENA_Msk          (1ul << SCB_SHCSR_MEMFAULTENA_Pos)
166#define SCB_SHCSR_SVCALLPENDED_Pos         15                                          // SVC 调用挂起位
167#define SCB_SHCSR_SVCALLPENDED_Msk         (1ul << SCB_SHCSR_SVCALLPENDED_Pos)
168#define SCB_SHCSR_BUSFAULTPENDED_Pos       14                                          // 总线故障挂起位
169#define SCB_SHCSR_BUSFAULTPENDED_Msk       (1ul << SCB_SHCSR_BUSFAULTPENDED_Pos)
170#define SCB_SHCSR_MEMFAULTPENDED_Pos       13                                          // 内存故障挂起位
171#define SCB_SHCSR_MEMFAULTPENDED_Msk       (1ul << SCB_SHCSR_MEMFAULTPENDED_Pos)
172#define SCB_SHCSR_USGFAULTPENDED_Pos       12                                          // 用法故障挂起位
173#define SCB_SHCSR_USGFAULTPENDED_Msk       (1ul << SCB_SHCSR_USGFAULTPENDED_Pos)
174#define SCB_SHCSR_SYSTICKACT_Pos           11                                          // SysTick 活动位
175#define SCB_SHCSR_SYSTICKACT_Msk           (1ul << SCB_SHCSR_SYSTICKACT_Pos)
176#define SCB_SHCSR_PENDSVACT_Pos            10                                          // PendSV 活动位
177#define SCB_SHCSR_PENDSVACT_Msk            (1ul << SCB_SHCSR_PENDSVACT_Pos)
178#define SCB_SHCSR_MONITORACT_Pos            8                                          // 监控活动位
179#define SCB_SHCSR_MONITORACT_Msk           (1ul << SCB_SHCSR_MONITORACT_Pos)
180#define SCB_SHCSR_SVCALLACT_Pos             7                                          // SVC 调用活动位
181#define SCB_SHCSR_SVCALLACT_Msk            (1ul << SCB_SHCSR_SVCALLACT_Pos)
182#define SCB_SHCSR_USGFAULTACT_Pos           3                                          // 用法故障活动位
183#define SCB_SHCSR_USGFAULTACT_Msk          (1ul << SCB_SHCSR_USGFAULTACT_Pos)
184#define SCB_SHCSR_BUSFAULTACT_Pos           1                                          // 总线故障活动位
185#define SCB_SHCSR_BUSFAULTACT_Msk          (1ul << SCB_SHCSR_BUSFAULTACT_Pos)
186#define SCB_SHCSR_MEMFAULTACT_Pos           0                                          // 内存故障活动位
187#define SCB_SHCSR_MEMFAULTACT_Msk          (1ul << SCB_SHCSR_MEMFAULTACT_Pos)
188
189// SCB 可配置故障状态寄存器定义
190#define SCB_CFSR_USGFAULTSR_Pos            16                                          // 用法故障状态寄存器
191#define SCB_CFSR_USGFAULTSR_Msk            (0xFFFFul << SCB_CFSR_USGFAULTSR_Pos) 
192#define SCB_CFSR_BUSFAULTSR_Pos             8                                          // 总线故障状态寄存器
193#define SCB_CFSR_BUSFAULTSR_Msk            (0xFFul << SCB_CFSR_BUSFAULTSR_Pos)
194#define SCB_CFSR_MEMFAULTSR_Pos             0                                          // 内存管理故障状态寄存器
195#define SCB_CFSR_MEMFAULTSR_Msk            (0xFFul << SCB_CFSR_MEMFAULTSR_Pos)
196
197// SCB 硬件故障状态寄存器定义
198#define SCB_HFSR_DEBUGEVT_Pos              31                                          // 调试事件位
199#define SCB_HFSR_DEBUGEVT_Msk              (1ul << SCB_HFSR_DEBUGEVT_Pos)
200#define SCB_HFSR_FORCED_Pos                30                                          // 强制故障位
201#define SCB_HFSR_FORCED_Msk                (1ul << SCB_HFSR_FORCED_Pos)
202#define SCB_HFSR_VECTTBL_Pos                1                                          // 向量表故障位
203#define SCB_HFSR_VECTTBL_Msk               (1ul << SCB_HFSR_VECTTBL_Pos)
204
205// SCB 调试故障状态寄存器定义
206#define SCB_DFSR_EXTERNAL_Pos               4                                          // 外部调试请求位
207#define SCB_DFSR_EXTERNAL_Msk              (1ul << SCB_DFSR_EXTERNAL_Pos)
208#define SCB_DFSR_VCATCH_Pos                 3                                          // 向量捕获位
209#define SCB_DFSR_VCATCH_Msk                (1ul << SCB_DFSR_VCATCH_Pos)
210#define SCB_DFSR_DWTTRAP_Pos                2                                          // DWT 陷阱位
211#define SCB_DFSR_DWTTRAP_Msk               (1ul << SCB_DFSR_DWTTRAP_Pos)
212#define SCB_DFSR_BKPT_Pos                   1                                          // 断点位
213#define SCB_DFSR_BKPT_Msk                  (1ul << SCB_DFSR_BKPT_Pos)
214#define SCB_DFSR_HALTED_Pos                 0                                          // 调试器暂停位
215#define SCB_DFSR_HALTED_Msk                (1ul << SCB_DFSR_HALTED_Pos)
216
217/****************************************************************************************************
218 *                                  SysTick 定时器的内存映射结构
219 ***************************************************************************************************/
220typedef struct
221{
222    __IO uint32_t CTRL;                    // SysTick 控制和状态寄存器  SysTick Control and Status Register
223    __IO uint32_t LOAD;                    // SysTick 重载值寄存器      SysTick Reload Value Register
224    __IO uint32_t VAL;                     // SysTick 当前值寄存器      SysTick Current Value Register
225    __I  uint32_t CALIB;                   // SysTick 校准寄存器        SysTick Calibration Register
226} SysTick_Type;
227
228// SysTick 控制/状态寄存器定义
229#define SysTick_CTRL_COUNTFLAG_Pos         16                                          // 计数标志位
230#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)
231#define SysTick_CTRL_CLKSOURCE_Pos          2                                          // 时钟源选择位
232#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)
233#define SysTick_CTRL_TICKINT_Pos            1                                          // 中断使能位
234#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)
235#define SysTick_CTRL_ENABLE_Pos             0                                          // 使能位
236#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)
237
238// SysTick 重载寄存器定义
239#define SysTick_LOAD_RELOAD_Pos             0                                          // 重载值
240#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
241
242// SysTick 当前值寄存器定义
243#define SysTick_VAL_CURRENT_Pos             0                                          // 当前值
244#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)
245
246// SysTick 校准寄存器定义
247#define SysTick_CALIB_NOREF_Pos            31                                          // 无参考时钟位
248#define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)
249#define SysTick_CALIB_SKEW_Pos             30                                          // 校准值偏斜位
250#define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)
251#define SysTick_CALIB_TENMS_Pos             0                                          // 10ms 校准值
252#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)
253
254/****************************************************************************************************
255 *                      仪器化跟踪宏单元 (ITM) 的内存映射结构(用途:调试和跟踪)
256 ***************************************************************************************************/
257typedef struct
258{
259    __O  union  
260    {
261        __O  uint8_t    u8;
262        __O  uint16_t   u16;
263        __O  uint32_t   u32;
264    }  PORT [32];
265         uint32_t RESERVED0[864];
266    __IO uint32_t TER;
267         uint32_t RESERVED1[15];
268    __IO uint32_t TPR;
269         uint32_t RESERVED2[15];
270    __IO uint32_t TCR;
271         uint32_t RESERVED3[29];
272    __IO uint32_t IWR;
273    __IO uint32_t IRR;
274    __IO uint32_t IMCR;
275         uint32_t RESERVED4[43];
276    __IO uint32_t LAR;
277    __IO uint32_t LSR;
278         uint32_t RESERVED5[6];
279    __I  uint32_t PID4;
280    __I  uint32_t PID5;
281    __I  uint32_t PID6;
282    __I  uint32_t PID7;
283    __I  uint32_t PID0;
284    __I  uint32_t PID1;
285    __I  uint32_t PID2;
286    __I  uint32_t PID3;
287    __I  uint32_t CID0;
288    __I  uint32_t CID1;
289    __I  uint32_t CID2;
290    __I  uint32_t CID3;
291} ITM_Type;
292
293// 跟踪特权寄存器定义
294#define ITM_TPR_PRIVMASK_Pos                0
295#define ITM_TPR_PRIVMASK_Msk               (0xFul << ITM_TPR_PRIVMASK_Pos)
296
297// 跟踪控制寄存器定义
298#define ITM_TCR_BUSY_Pos                   23
299#define ITM_TCR_BUSY_Msk                   (1ul << ITM_TCR_BUSY_Pos)
300#define ITM_TCR_ATBID_Pos                  16
301#define ITM_TCR_ATBID_Msk                  (0x7Ful << ITM_TCR_ATBID_Pos)
302#define ITM_TCR_TSPrescale_Pos              8
303#define ITM_TCR_TSPrescale_Msk             (3ul << ITM_TCR_TSPrescale_Pos)
304#define ITM_TCR_SWOENA_Pos                  4
305#define ITM_TCR_SWOENA_Msk                 (1ul << ITM_TCR_SWOENA_Pos)
306#define ITM_TCR_DWTENA_Pos                  3
307#define ITM_TCR_DWTENA_Msk                 (1ul << ITM_TCR_DWTENA_Pos)
308#define ITM_TCR_SYNCENA_Pos                 2
309#define ITM_TCR_SYNCENA_Msk                (1ul << ITM_TCR_SYNCENA_Pos)
310#define ITM_TCR_TSENA_Pos                   1
311#define ITM_TCR_TSENA_Msk                  (1ul << ITM_TCR_TSENA_Pos)
312#define ITM_TCR_ITMENA_Pos                  0
313#define ITM_TCR_ITMENA_Msk                 (1ul << ITM_TCR_ITMENA_Pos)
314
315// 集成写寄存器定义
316#define ITM_IWR_ATVALIDM_Pos                0
317#define ITM_IWR_ATVALIDM_Msk               (1ul << ITM_IWR_ATVALIDM_Pos)
318
319// 集成读寄存器定义
320#define ITM_IRR_ATREADYM_Pos                0
321#define ITM_IRR_ATREADYM_Msk               (1ul << ITM_IRR_ATREADYM_Pos)
322
323// 集成模式控制寄存器定义
324#define ITM_IMCR_INTEGRATION_Pos            0
325#define ITM_IMCR_INTEGRATION_Msk           (1ul << ITM_IMCR_INTEGRATION_Pos)
326
327// 锁状态寄存器定义
328#define ITM_LSR_ByteAcc_Pos                 2
329#define ITM_LSR_ByteAcc_Msk                (1ul << ITM_LSR_ByteAcc_Pos)
330#define ITM_LSR_Access_Pos                  1
331#define ITM_LSR_Access_Msk                 (1ul << ITM_LSR_Access_Pos)
332#define ITM_LSR_Present_Pos                 0
333#define ITM_LSR_Present_Msk                (1ul << ITM_LSR_Present_Pos)
334
335/****************************************************************************************************
336 *               中断类型的的内存映射结构: memory mapped structure for Interrupt Type
337 ***************************************************************************************************/
338typedef struct
339{
340       uint32_t RESERVED0;
341  __I  uint32_t ICTR;                      // 中断控制类型寄存器  Interrupt Control Type Register
342#if ((defined __CM3_REV) && (__CM3_REV >= 0x200))
343  __IO uint32_t ACTLR;                     // 辅助控制寄存器  Auxiliary Control Register
344#else
345       uint32_t RESERVED1;
346#endif
347} InterruptType_Type;
348
349// 中断控制器类型寄存器定义
350#define InterruptType_ICTR_INTLINESNUM_Pos  0                                             // 中断线数量
351#define InterruptType_ICTR_INTLINESNUM_Msk (0x1Ful << InterruptType_ICTR_INTLINESNUM_Pos)
352
353// 辅助控制寄存器定义
354#define InterruptType_ACTLR_DISFOLD_Pos     2                                             // 禁止重叠位
355#define InterruptType_ACTLR_DISFOLD_Msk    (1ul << InterruptType_ACTLR_DISFOLD_Pos)
356#define InterruptType_ACTLR_DISDEFWBUF_Pos  1                                             // 禁止默认写缓冲区位
357#define InterruptType_ACTLR_DISDEFWBUF_Msk (1ul << InterruptType_ACTLR_DISDEFWBUF_Pos)
358#define InterruptType_ACTLR_DISMCYCINT_Pos  0                                             // 禁止多周期中断位
359#define InterruptType_ACTLR_DISMCYCINT_Msk (1ul << InterruptType_ACTLR_DISMCYCINT_Pos)
360
361
362// __MPU_PRESENT 在 stm32f10x.h 中定义
363#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
364/****************************************************************************************************
365 *                              内存保护单元 (MPU) 的内存映射结构
366 ***************************************************************************************************/
367typedef struct
368{
369  __I  uint32_t TYPE;                      // 偏移: 0x00 类型寄存器                MPU Type Register
370  __IO uint32_t CTRL;                      // 偏移: 0x04 控制寄存器                MPU Control Register
371  __IO uint32_t RNR;                       // 偏移: 0x08 区域编号寄存器            MPU Region RNRber Register
372  __IO uint32_t RBAR;                      // 偏移: 0x0C 区域基地址寄存器          MPU Region Base Address Register
373  __IO uint32_t RASR;                      // 偏移: 0x10 区域属性和大小寄存器      MPU Region Attribute and Size Register
374  __IO uint32_t RBAR_A1;                   // 偏移: 0x14 别名1区域基地址寄存器     MPU Alias 1 Region Base Address Register
375  __IO uint32_t RASR_A1;                   // 偏移: 0x18 别名1区域属性和大小寄存器 MPU Alias 1 Region Attribute and Size Register
376  __IO uint32_t RBAR_A2;                   // 偏移: 0x1C 别名2区域基地址寄存器     MPU Alias 2 Region Base Address Register
377  __IO uint32_t RASR_A2;                   // 偏移: 0x20 别名2区域属性和大小寄存器 MPU Alias 2 Region Attribute and Size Register
378  __IO uint32_t RBAR_A3;                   // 偏移: 0x24 别名3区域基地址寄存器     MPU Alias 3 Region Base Address Register
379  __IO uint32_t RASR_A3;                   // 偏移: 0x28 别名3区域属性和大小寄存器 MPU Alias 3 Region Attribute and Size Register
380} MPU_Type;                                                
381
382// MPU Type Register
383#define MPU_TYPE_IREGION_Pos               16                                             // IREGION Position
384#define MPU_TYPE_IREGION_Msk               (0xFFul << MPU_TYPE_IREGION_Pos)
385#define MPU_TYPE_DREGION_Pos                8                                             // DREGION Position
386#define MPU_TYPE_DREGION_Msk               (0xFFul << MPU_TYPE_DREGION_Pos)
387#define MPU_TYPE_SEPARATE_Pos               0                                             // SEPARATE Position
388#define MPU_TYPE_SEPARATE_Msk              (1ul << MPU_TYPE_SEPARATE_Pos)
389
390// MPU Control Register
391#define MPU_CTRL_PRIVDEFENA_Pos             2                                             // PRIVDEFENA Position
392#define MPU_CTRL_PRIVDEFENA_Msk            (1ul << MPU_CTRL_PRIVDEFENA_Pos)
393#define MPU_CTRL_HFNMIENA_Pos               1                                             // HFNMIENA Position
394#define MPU_CTRL_HFNMIENA_Msk              (1ul << MPU_CTRL_HFNMIENA_Pos)
395#define MPU_CTRL_ENABLE_Pos                 0                                             // ENABLE Position
396#define MPU_CTRL_ENABLE_Msk                (1ul << MPU_CTRL_ENABLE_Pos)
397
398// MPU Region Number Register
399#define MPU_RNR_REGION_Pos                  0                                             // REGION Position
400#define MPU_RNR_REGION_Msk                 (0xFFul << MPU_RNR_REGION_Pos)
401
402// MPU Region Base Address Register
403#define MPU_RBAR_ADDR_Pos                   5                                             // ADDR Position
404#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFul << MPU_RBAR_ADDR_Pos)
405#define MPU_RBAR_VALID_Pos                  4                                             // VALID Position
406#define MPU_RBAR_VALID_Msk                 (1ul << MPU_RBAR_VALID_Pos) 
407#define MPU_RBAR_REGION_Pos                 0                                             // REGION Position
408#define MPU_RBAR_REGION_Msk                (0xFul << MPU_RBAR_REGION_Pos)
409
410// MPU Region Attribute and Size Register
411#define MPU_RASR_XN_Pos                    28                                             // XN Position
412#define MPU_RASR_XN_Msk                    (1ul << MPU_RASR_XN_Pos) 
413#define MPU_RASR_AP_Pos                    24                                             // AP Position
414#define MPU_RASR_AP_Msk                    (7ul << MPU_RASR_AP_Pos)
415#define MPU_RASR_TEX_Pos                   19                                             // TEX Position
416#define MPU_RASR_TEX_Msk                   (7ul << MPU_RASR_TEX_Pos)
417#define MPU_RASR_S_Pos                     18                                             // Shareable bit Position
418#define MPU_RASR_S_Msk                     (1ul << MPU_RASR_S_Pos)
419#define MPU_RASR_C_Pos                     17                                             // Cacheable bit Position
420#define MPU_RASR_C_Msk                     (1ul << MPU_RASR_C_Pos)
421#define MPU_RASR_B_Pos                     16                                             // Bufferable bit Position
422#define MPU_RASR_B_Msk                     (1ul << MPU_RASR_B_Pos)
423#define MPU_RASR_SRD_Pos                    8                                             // Sub-Region Disable Position
424#define MPU_RASR_SRD_Msk                   (0xFFul << MPU_RASR_SRD_Pos)
425#define MPU_RASR_SIZE_Pos                   1                                             // Region Size Field Position
426#define MPU_RASR_SIZE_Msk                  (0x1Ful << MPU_RASR_SIZE_Pos)
427#define MPU_RASR_ENA_Pos                    0                                             // Region enable bit Position
428#define MPU_RASR_ENA_Msk                   (0x1Ful << MPU_RASR_ENA_Pos)
429
430#endif
431
432
433/****************************************************************************************************
434 *                              核心调试寄存器的内存映射结构
435 ***************************************************************************************************/
436typedef struct
437{
438    __IO uint32_t DHCSR;                   // Offset: 0x00  Debug Halting Control and Status Register
439    __O  uint32_t DCRSR;                   // Offset: 0x04  Debug Core Register Selector Register
440    __IO uint32_t DCRDR;                   // Offset: 0x08  Debug Core Register Data Register
441    __IO uint32_t DEMCR;                   // Offset: 0x0C  Debug Exception and Monitor Control Register
442} CoreDebug_Type;
443
444// Debug Halting Control and Status Register
445#define CoreDebug_DHCSR_DBGKEY_Pos         16                                             // CoreDebug DHCSR: DBGKEY Position
446#define CoreDebug_DHCSR_DBGKEY_Msk         (0xFFFFul << CoreDebug_DHCSR_DBGKEY_Pos)       // CoreDebug DHCSR: DBGKEY Mask
447#define CoreDebug_DHCSR_S_RESET_ST_Pos     25                                             // CoreDebug DHCSR: S_RESET_ST Position
448#define CoreDebug_DHCSR_S_RESET_ST_Msk     (1ul << CoreDebug_DHCSR_S_RESET_ST_Pos)        // CoreDebug DHCSR: S_RESET_ST Mask
449#define CoreDebug_DHCSR_S_RETIRE_ST_Pos    24                                             // CoreDebug DHCSR: S_RETIRE_ST Position
450#define CoreDebug_DHCSR_S_RETIRE_ST_Msk    (1ul << CoreDebug_DHCSR_S_RETIRE_ST_Pos)       // CoreDebug DHCSR: S_RETIRE_ST Mask
451#define CoreDebug_DHCSR_S_LOCKUP_Pos       19                                             // CoreDebug DHCSR: S_LOCKUP Position
452#define CoreDebug_DHCSR_S_LOCKUP_Msk       (1ul << CoreDebug_DHCSR_S_LOCKUP_Pos)          // CoreDebug DHCSR: S_LOCKUP Mask
453#define CoreDebug_DHCSR_S_SLEEP_Pos        18                                             // CoreDebug DHCSR: S_SLEEP Position
454#define CoreDebug_DHCSR_S_SLEEP_Msk        (1ul << CoreDebug_DHCSR_S_SLEEP_Pos)           // CoreDebug DHCSR: S_SLEEP Mask
455#define CoreDebug_DHCSR_S_HALT_Pos         17                                             // CoreDebug DHCSR: S_HALT Position
456#define CoreDebug_DHCSR_S_HALT_Msk         (1ul << CoreDebug_DHCSR_S_HALT_Pos)            // CoreDebug DHCSR: S_HALT Mask
457#define CoreDebug_DHCSR_S_REGRDY_Pos       16                                             // CoreDebug DHCSR: S_REGRDY Position
458#define CoreDebug_DHCSR_S_REGRDY_Msk       (1ul << CoreDebug_DHCSR_S_REGRDY_Pos)          // CoreDebug DHCSR: S_REGRDY Mask
459#define CoreDebug_DHCSR_C_SNAPSTALL_Pos     5                                             // CoreDebug DHCSR: C_SNAPSTALL Position
460#define CoreDebug_DHCSR_C_SNAPSTALL_Msk    (1ul << CoreDebug_DHCSR_C_SNAPSTALL_Pos)       // CoreDebug DHCSR: C_SNAPSTALL Mask
461#define CoreDebug_DHCSR_C_MASKINTS_Pos      3                                             // CoreDebug DHCSR: C_MASKINTS Position
462#define CoreDebug_DHCSR_C_MASKINTS_Msk     (1ul << CoreDebug_DHCSR_C_MASKINTS_Pos)        // CoreDebug DHCSR: C_MASKINTS Mask
463#define CoreDebug_DHCSR_C_STEP_Pos          2                                             // CoreDebug DHCSR: C_STEP Position
464#define CoreDebug_DHCSR_C_STEP_Msk         (1ul << CoreDebug_DHCSR_C_STEP_Pos)            // CoreDebug DHCSR: C_STEP Mask
465#define CoreDebug_DHCSR_C_HALT_Pos          1                                             // CoreDebug DHCSR: C_HALT Position
466#define CoreDebug_DHCSR_C_HALT_Msk         (1ul << CoreDebug_DHCSR_C_HALT_Pos)            // CoreDebug DHCSR: C_HALT Mask
467#define CoreDebug_DHCSR_C_DEBUGEN_Pos       0                                             // CoreDebug DHCSR: C_DEBUGEN Position
468#define CoreDebug_DHCSR_C_DEBUGEN_Msk      (1ul << CoreDebug_DHCSR_C_DEBUGEN_Pos)         // CoreDebug DHCSR: C_DEBUGEN Mask
469
470// Debug Core Register Selector Register
471#define CoreDebug_DCRSR_REGWnR_Pos         16                                             // CoreDebug DCRSR: REGWnR Position
472#define CoreDebug_DCRSR_REGWnR_Msk         (1ul << CoreDebug_DCRSR_REGWnR_Pos)            // CoreDebug DCRSR: REGWnR Mask
473#define CoreDebug_DCRSR_REGSEL_Pos          0                                             // CoreDebug DCRSR: REGSEL Position
474#define CoreDebug_DCRSR_REGSEL_Msk         (0x1Ful << CoreDebug_DCRSR_REGSEL_Pos)         // CoreDebug DCRSR: REGSEL Mask
475
476// Debug Exception and Monitor Control Register
477#define CoreDebug_DEMCR_TRCENA_Pos         24                                             // CoreDebug DEMCR: TRCENA Position
478#define CoreDebug_DEMCR_TRCENA_Msk         (1ul << CoreDebug_DEMCR_TRCENA_Pos)            // CoreDebug DEMCR: TRCENA Mask
479#define CoreDebug_DEMCR_MON_REQ_Pos        19                                             // CoreDebug DEMCR: MON_REQ Position
480#define CoreDebug_DEMCR_MON_REQ_Msk        (1ul << CoreDebug_DEMCR_MON_REQ_Pos)           // CoreDebug DEMCR: MON_REQ Mask
481#define CoreDebug_DEMCR_MON_STEP_Pos       18                                             // CoreDebug DEMCR: MON_STEP Position
482#define CoreDebug_DEMCR_MON_STEP_Msk       (1ul << CoreDebug_DEMCR_MON_STEP_Pos)          // CoreDebug DEMCR: MON_STEP Mask
483#define CoreDebug_DEMCR_MON_PEND_Pos       17                                             // CoreDebug DEMCR: MON_PEND Position
484#define CoreDebug_DEMCR_MON_PEND_Msk       (1ul << CoreDebug_DEMCR_MON_PEND_Pos)          // CoreDebug DEMCR: MON_PEND Mask
485#define CoreDebug_DEMCR_MON_EN_Pos         16                                             // CoreDebug DEMCR: MON_EN Position
486#define CoreDebug_DEMCR_MON_EN_Msk         (1ul << CoreDebug_DEMCR_MON_EN_Pos)            // CoreDebug DEMCR: MON_EN Mask
487#define CoreDebug_DEMCR_VC_HARDERR_Pos     10                                             // CoreDebug DEMCR: VC_HARDERR Position
488#define CoreDebug_DEMCR_VC_HARDERR_Msk     (1ul << CoreDebug_DEMCR_VC_HARDERR_Pos)        // CoreDebug DEMCR: VC_HARDERR Mask
489#define CoreDebug_DEMCR_VC_INTERR_Pos       9                                             // CoreDebug DEMCR: VC_INTERR Position
490#define CoreDebug_DEMCR_VC_INTERR_Msk      (1ul << CoreDebug_DEMCR_VC_INTERR_Pos)         // CoreDebug DEMCR: VC_INTERR Mask
491#define CoreDebug_DEMCR_VC_BUSERR_Pos       8                                             // CoreDebug DEMCR: VC_BUSERR Position
492#define CoreDebug_DEMCR_VC_BUSERR_Msk      (1ul << CoreDebug_DEMCR_VC_BUSERR_Pos)         // CoreDebug DEMCR: VC_BUSERR Mask
493#define CoreDebug_DEMCR_VC_STATERR_Pos      7                                             // CoreDebug DEMCR: VC_STATERR Position
494#define CoreDebug_DEMCR_VC_STATERR_Msk     (1ul << CoreDebug_DEMCR_VC_STATERR_Pos)        // CoreDebug DEMCR: VC_STATERR Mask
495#define CoreDebug_DEMCR_VC_CHKERR_Pos       6                                             // CoreDebug DEMCR: VC_CHKERR Position
496#define CoreDebug_DEMCR_VC_CHKERR_Msk      (1ul << CoreDebug_DEMCR_VC_CHKERR_Pos)         // CoreDebug DEMCR: VC_CHKERR Mask
497#define CoreDebug_DEMCR_VC_NOCPERR_Pos      5                                             // CoreDebug DEMCR: VC_NOCPERR Position
498#define CoreDebug_DEMCR_VC_NOCPERR_Msk     (1ul << CoreDebug_DEMCR_VC_NOCPERR_Pos)        // CoreDebug DEMCR: VC_NOCPERR Mask
499#define CoreDebug_DEMCR_VC_MMERR_Pos        4                                             // CoreDebug DEMCR: VC_MMERR Position
500#define CoreDebug_DEMCR_VC_MMERR_Msk       (1ul << CoreDebug_DEMCR_VC_MMERR_Pos)          // CoreDebug DEMCR: VC_MMERR Mask
501#define CoreDebug_DEMCR_VC_CORERESET_Pos    0                                             // CoreDebug DEMCR: VC_CORERESET Position
502#define CoreDebug_DEMCR_VC_CORERESET_Msk   (1ul << CoreDebug_DEMCR_VC_CORERESET_Pos)      // CoreDebug DEMCR: VC_CORERESET Mask
503
504
505/****************************************************************************************************
506 *                                  Cortex-M3 硬件的内存映射
507 ***************************************************************************************************/
508#define SCS_BASE            (0xE000E000)                              // System Control Space Base Address
509#define ITM_BASE            (0xE0000000)                              // ITM Base Address
510#define CoreDebug_BASE      (0xE000EDF0)                              // Core Debug Base Address
511#define SysTick_BASE        (SCS_BASE +  0x0010)                      // SysTick Base Address
512#define NVIC_BASE           (SCS_BASE +  0x0100)                      // NVIC Base Address
513#define SCB_BASE            (SCS_BASE +  0x0D00)                      // System Control Block Base Address
514
515#define InterruptType       ((InterruptType_Type *) SCS_BASE)         // Interrupt Type Register
516#define SCB                 ((SCB_Type *)           SCB_BASE)         // SCB configuration struct
517#define SysTick             ((SysTick_Type *)       SysTick_BASE)     // SysTick configuration struct
518#define NVIC                ((NVIC_Type *)          NVIC_BASE)        // NVIC configuration struct
519#define ITM                 ((ITM_Type *)           ITM_BASE)         // ITM configuration struct
520#define CoreDebug           ((CoreDebug_Type *)     CoreDebug_BASE)   // Core Debug configuration struct
521
522#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1)
523  #define MPU_BASE          (SCS_BASE +  0x0D90)                      // Memory Protection Unit
524  #define MPU               ((MPU_Type*)            MPU_BASE)         // Memory Protection Unit
525#endif
526
527
528/****************************************************************************************************
529 *                                          硬件抽象层
530 ***************************************************************************************************/
531#if defined ( __CC_ARM   )
532  #define __ASM            __asm                                      // asm keyword for ARM Compiler
533  #define __INLINE         __inline                                   // inline keyword for ARM Compiler
534
535#elif defined ( __ICCARM__ )
536  #define __ASM           __asm                                       // asm keyword for IAR Compiler
537  #define __INLINE        inline                                      // inline keyword for IAR Compiler. Only avaiable in High optimization mode!
538
539#elif defined   (  __GNUC__  )
540  #define __ASM            __asm                                      // asm keyword for GNU Compiler
541  #define __INLINE         inline                                     // inline keyword for GNU Compiler
542
543#elif defined   (  __TASKING__  )
544  #define __ASM            __asm                                      // asm keyword for TASKING Compiler
545  #define __INLINE         inline                                     // inline keyword for TASKING Compiler
546
547#endif
548
549
550/****************************************************************************************************
551 *                                      编译器特定的内置函数
552 ***************************************************************************************************/
553#if defined ( __CC_ARM   )    // RealView Compiler
554
555// ARM armcc specific functions
556#define __enable_fault_irq                __enable_fiq
557#define __disable_fault_irq               __disable_fiq
558
559#define __NOP                             __nop
560#define __WFI                             __wfi
561#define __WFE                             __wfe
562#define __SEV                             __sev
563#define __ISB()                           __isb(0)
564#define __DSB()                           __dsb(0)
565#define __DMB()                           __dmb(0)
566#define __REV                             __rev
567#define __RBIT                            __rbit
568#define __LDREXB(ptr)                     ((unsigned char ) __ldrex(ptr))
569#define __LDREXH(ptr)                     ((unsigned short) __ldrex(ptr))
570#define __LDREXW(ptr)                     ((unsigned int  ) __ldrex(ptr))
571#define __STREXB(value, ptr)              __strex(value, ptr)
572#define __STREXH(value, ptr)              __strex(value, ptr)
573#define __STREXW(value, ptr)              __strex(value, ptr)
574
575extern uint32_t __get_PSP(void);                       // 返回进程栈指针
576extern void     __set_PSP(uint32_t topOfProcStack);A   // 设置进程栈指针
577extern uint32_t __get_MSP(void);                       // 返回主栈指针
578extern void     __set_MSP(uint32_t topOfMainStack);    // 设置主栈指针
579extern uint32_t __REV16(uint16_t value);               // 反转半字中的字节
580extern int32_t  __REVSH(int16_t value);                // 反转低半字中的字节,并将结果有符号展开
581
582#if (__ARMCC_VERSION < 400000)
583
584extern void     __CLREX(void);
585extern uint32_t __get_BASEPRI(void);
586extern void     __set_BASEPRI(uint32_t basePri);
587extern uint32_t __get_PRIMASK(void);
588extern void     __set_PRIMASK(uint32_t priMask);
589extern uint32_t __get_FAULTMASK(void);
590extern void     __set_FAULTMASK(uint32_t faultMask);
591extern uint32_t __get_CONTROL(void);
592extern void     __set_CONTROL(uint32_t control);
593
594#else
595
596#define __CLREX                           __clrex
597
598static __INLINE uint32_t  __get_BASEPRI(void)
599{
600  register uint32_t __regBasePri         __ASM("basepri");
601  return(__regBasePri);
602}
603
604static __INLINE void __set_BASEPRI(uint32_t basePri)
605{
606  register uint32_t __regBasePri         __ASM("basepri");
607  __regBasePri = (basePri & 0xff);
608}
609
610static __INLINE uint32_t __get_PRIMASK(void)
611{
612  register uint32_t __regPriMask         __ASM("primask");
613  return(__regPriMask);
614}
615
616static __INLINE void __set_PRIMASK(uint32_t priMask)
617{
618  register uint32_t __regPriMask         __ASM("primask");
619  __regPriMask = (priMask);
620}
621
622static __INLINE uint32_t __get_FAULTMASK(void)
623{
624  register uint32_t __regFaultMask       __ASM("faultmask");
625  return(__regFaultMask);
626}
627
628static __INLINE void __set_FAULTMASK(uint32_t faultMask)
629{
630  register uint32_t __regFaultMask       __ASM("faultmask");
631  __regFaultMask = (faultMask & 1);
632}
633
634static __INLINE uint32_t __get_CONTROL(void)
635{
636  register uint32_t __regControl         __ASM("control");
637  return(__regControl);
638}
639
640static __INLINE void __set_CONTROL(uint32_t control)
641{
642  register uint32_t __regControl         __ASM("control");
643  __regControl = control;
644}
645
646#endif
647
648// ICC Compiler
649#elif (defined (__ICCARM__))
650
651#define __enable_irq                              __enable_interrupt
652#define __disable_irq                             __disable_interrupt
653
654static __INLINE void __enable_fault_irq()         { __ASM ("cpsie f"); }
655static __INLINE void __disable_fault_irq()        { __ASM ("cpsid f"); }
656
657#define __NOP                                     __no_operation
658static __INLINE  void __WFI()                     { __ASM ("wfi"); }
659static __INLINE  void __WFE()                     { __ASM ("wfe"); }
660static __INLINE  void __SEV()                     { __ASM ("sev"); }
661static __INLINE  void __CLREX()                   { __ASM ("clrex"); }
662
663extern uint32_t __get_PSP(void);
664extern void     __set_PSP(uint32_t topOfProcStack);
665extern uint32_t __get_MSP(void);
666extern void     __set_MSP(uint32_t topOfMainStack);
667extern uint32_t __REV16(uint16_t value);
668extern uint32_t __RBIT(uint32_t value);
669extern uint8_t  __LDREXB(uint8_t *addr);
670extern uint16_t __LDREXH(uint16_t *addr);
671extern uint32_t __LDREXW(uint32_t *addr);
672extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
673extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
674extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
675
676
677// GNU Compiler
678#elif (defined (__GNUC__))
679
680static __INLINE void __enable_irq()               { __ASM volatile ("cpsie i"); }
681static __INLINE void __disable_irq()              { __ASM volatile ("cpsid i"); }
682
683static __INLINE void __enable_fault_irq()         { __ASM volatile ("cpsie f"); }
684static __INLINE void __disable_fault_irq()        { __ASM volatile ("cpsid f"); }
685
686static __INLINE void __NOP()                      { __ASM volatile ("nop"); }
687static __INLINE void __WFI()                      { __ASM volatile ("wfi"); }
688static __INLINE void __WFE()                      { __ASM volatile ("wfe"); }
689static __INLINE void __SEV()                      { __ASM volatile ("sev"); }
690static __INLINE void __ISB()                      { __ASM volatile ("isb"); }
691static __INLINE void __DSB()                      { __ASM volatile ("dsb"); }
692static __INLINE void __DMB()                      { __ASM volatile ("dmb"); }
693static __INLINE void __CLREX()                    { __ASM volatile ("clrex"); }
694
695extern uint32_t __get_PSP(void);
696extern void     __set_PSP(uint32_t topOfProcStack);
697extern uint32_t __get_MSP(void);
698extern void     __set_MSP(uint32_t topOfMainStack);
699extern uint32_t __get_BASEPRI(void);
700extern void     __set_BASEPRI(uint32_t basePri);
701extern uint32_t __get_PRIMASK(void);
702extern void     __set_PRIMASK(uint32_t priMask);
703extern uint32_t __get_FAULTMASK(void);
704extern void     __set_FAULTMASK(uint32_t faultMask);
705extern uint32_t __get_CONTROL(void);
706extern void     __set_CONTROL(uint32_t control);
707extern uint32_t __REV(uint32_t value);
708extern uint32_t __REV16(uint16_t value);
709extern int32_t  __REVSH(int16_t value);
710extern uint32_t __RBIT(uint32_t value);
711extern uint8_t  __LDREXB(uint8_t *addr);
712extern uint16_t __LDREXH(uint16_t *addr);
713extern uint32_t __LDREXW(uint32_t *addr);
714extern uint32_t __STREXB(uint8_t value, uint8_t *addr);
715extern uint32_t __STREXH(uint16_t value, uint16_t *addr);
716extern uint32_t __STREXW(uint32_t value, uint32_t *addr);
717
718
719// TASKING Compiler
720#elif (defined (__TASKING__))
721
722// CMSIS 函数已在编译器中实现为内置函数
723
724#endif
725
726
727/* ##################################    NVIC 函数  ############################################ */
728// 设置优先级分组
729static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
730{
731  uint32_t reg_value;
732  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);             // 只取后 3 位,即 0 - 7
733  
734  reg_value  =  SCB->AIRCR;                                       // 读取旧的寄存器配置
735  reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); // 清除对应位
736  reg_value  =  (reg_value                       |
737                (0x5FA << SCB_AIRCR_VECTKEY_Pos) |                // [31:16], 写入 AIRCR 寄存器时必须要将 0x5FA 写入 VECTKEY,否则写入会被忽略
738                (PriorityGroupTmp << 8));                         // [10:8], 优先级分组
739  SCB->AIRCR =  reg_value;
740}
741
742// 获取优先级分组
743static __INLINE uint32_t NVIC_GetPriorityGrouping(void)
744{
745  return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos);
746}
747
748// 启用外部中断
749static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
750{
751  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));  // ISER[0] 每一位对应 0 ~ 31 中断
752}
753
754// 禁用外部中断
755static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
756{
757  NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
758}
759
760// 获取外部中断的挂起位
761static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
762{
763  return((uint32_t) ((  NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))  )?1:0));
764}
765
766// 设置外部中断的挂起位
767static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
768{
769  NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
770}
771
772// 清除外部中断的挂起位
773static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
774{
775  NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F));
776}
777
778// 读取外部中断的活动位 (1: 中断程序运行, 0: 未运行)
779static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
780{
781  return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0));
782}
783
784// 设置中断的优先级
785static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
786{
787  if(IRQn < 0) { 
788    // 系统中断,SHP[0] ~ SHP[2] 对应系统异常枚举值 -12 ~ -10,SHP[7](-5),SHP[8](-4),SHP[10](-2),SHP[11](-1),其余未实现
789	// -12 二进制是 1111 0100
790    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); }
791  else {
792    // 外部中断,IP[0] (8位) 对应外部中断枚举值 0 ,以此类推
793    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }
794}
795
796// 读取中断的优先级
797static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
798{
799
800  if(IRQn < 0) {
801    return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS)));  }
802  else {
803    return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)]           >> (8 - __NVIC_PRIO_BITS)));  }
804}
805
806
807// 中断的优先级编码
808static __INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
809{
810  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07);  // 优先级分组,3 位
811  uint32_t PreemptPriorityBits; // 主优先级
812  uint32_t SubPriorityBits;  // 子优先级
813
814  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
815  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
816 
817  return (
818           ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) |
819           ((SubPriority     & ((1 << (SubPriorityBits    )) - 1)))
820         );
821}
822
823/*          优先级分组 = 5,
824825| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
826827	                   __NVIC_PRIO_BITS = 4,高 4 位有效
828[7:6] -> 主优先级,共 2 位(0-3)
829[5:4] -> 子优先级,共 2 位(0-3)                                   */
830
831// 中断的优先级解码,Priority 参数是中断优先级
832static __INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
833{
834  uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); 
835  uint32_t PreemptPriorityBits;
836  uint32_t SubPriorityBits;
837
838  PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp;
839  SubPriorityBits     = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS;
840  
841  *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1);
842  *pSubPriority     = (Priority                   ) & ((1 << (SubPriorityBits    )) - 1);
843}
844
845
846/* ##################################    SysTick 函数  ############################################ */
847#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)
848
849// 初始化和启动 SysTick 计数器及其中断
850static __INLINE uint32_t SysTick_Config(uint32_t ticks)
851{ 
852  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            // 重载值超出范围
853                                                               
854  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      // 设置重载寄存器
855  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  // 为 Cortex-M0 系统中断设置优先级
856  SysTick->VAL   = 0;                                          // 加载 SysTick 计数器值
857  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
858                   SysTick_CTRL_TICKINT_Msk   | 
859                   SysTick_CTRL_ENABLE_Msk;                    // 启用 SysTick 中断和 SysTick 定时器
860  return (0);
861}
862
863#endif
864
865
866/* ##################################  复位函数  ############################################ */
867static __INLINE void NVIC_SystemReset(void)
868{
869  SCB->AIRCR  = ((0x5FA << SCB_AIRCR_VECTKEY_Pos)      | 
870                 (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | 
871                 SCB_AIRCR_SYSRESETREQ_Msk);
872  __DSB();    // 确保内存访问完成
873  while(1);   // 等待直到复位
874}
875
876
877/* ##################################### 调试输入/输出函数 ########################################### */
878extern volatile int ITM_RxBuffer;                     // 用于接收字符的变量
879#define             ITM_RXBUFFER_EMPTY    0x5AA55AA5  // 标识 ITM_RxBuffer 准备好接收下一个字符的值
880
881// 通过 ITM 通道 0 输出一个字符
882static __INLINE uint32_t ITM_SendChar (uint32_t ch)
883{
884  if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      // 跟踪已启用
885      (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      // ITM 已启用
886      (ITM->TER & (1ul << 0)        )                    )     // ITM 端口 #0 已启用
887  {
888    while (ITM->PORT[0].u32 == 0);
889    ITM->PORT[0].u8 = (uint8_t) ch;
890  }  
891  return (ch);
892}
893
894// 通过变量 ITM_RxBuffer 输入一个字符
895static __INLINE int ITM_ReceiveChar (void) {
896  int ch = -1;                               // 没有可用字符
897
898  if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) {
899    ch = ITM_RxBuffer;
900    ITM_RxBuffer = ITM_RXBUFFER_EMPTY;       // 准备好接收下一个字符
901  }
902  
903  return (ch); 
904}
905
906// 检查是否可以通过变量 ITM_RxBuffer 获取字符
907static __INLINE int ITM_CheckChar (void) {
908
909  if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) {
910    return (0);                              // 没有可用字符
911  } else {
912    return (1);                              // 有可用字符 
913  }
914}
915
916
917#ifdef __cplusplus     // 如果使用 C++ 编译器,结束 C 链接约定
918}
919#endif
920
921// __CM3_CORE_H__
922#endif

内核头文件主要定义了以下内容:

core_cm3.c #

文件Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
  1// 该头文件定义了一系列固定位宽的整数类型,如 int8_t 、uint8_t 、int16_t 等
  2#include <stdint.h>
  3
  4// 定义编译器特定的符号
  5#if defined ( __CC_ARM   )     // __CC_ARM 是 armcc 编译器的内置预定义宏
  6  #define __ASM            __asm
  7  #define __INLINE         __inline
  8
  9#elif defined ( __ICCARM__ )
 10  #define __ASM           __asm
 11  #define __INLINE        inline
 12
 13#elif defined   (  __GNUC__  ) // arm gcc 编译器
 14  #define __ASM            __asm
 15  #define __INLINE         inline
 16
 17#elif defined   (  __TASKING__  )
 18  #define __ASM            __asm
 19  #define __INLINE         inline
 20
 21#endif
 22
 23
 24/* ###################  编译器特定的函数  ########################### */
 25
 26#if defined ( __CC_ARM   )
 27
 28// 获取进程堆栈指针
 29__ASM uint32_t __get_PSP(void)
 30{
 31  mrs r0, psp    // 从 PSP 寄存器读取值到 R0 寄存器
 32  bx lr          // 函数返回(bx 指令跳转到 lr 寄存器中的地址处,lr 寄存器保存的是函数调用处的下一条指令地址)
 33}
 34
 35// 设置进程堆栈指针
 36__ASM void __set_PSP(uint32_t topOfProcStack)
 37{
 38  msr psp, r0    // 将 r0 的值写入 PSP 寄存器(对于有参数的函数,第一个参数(32位或更小)通过 r0 寄存器传递)
 39  bx lr
 40}
 41
 42// 获取主堆栈指针
 43__ASM uint32_t __get_MSP(void)
 44{
 45  mrs r0, msp
 46  bx lr
 47}
 48
 49// 设置主堆栈指针
 50__ASM void __set_MSP(uint32_t mainStackPointer)
 51{
 52  msr msp, r0
 53  bx lr
 54}
 55
 56// 反转半字中的字节,0x12345678 --> 0x34127856
 57__ASM uint32_t __REV16(uint16_t value)
 58{
 59  rev16 r0, r0    // r0 既用作传递函数第一个参数,也用作保存返回值
 60  bx lr
 61}
 62
 63// 反转低半字中的字节,并将结果有符号展开,0x33448899 --> 0xFFFF9988
 64__ASM int32_t __REVSH(int16_t value)
 65{
 66  revsh r0, r0
 67  bx lr
 68}
 69
 70
 71// ARM Compiler 4 之前的版本
 72#if (__ARMCC_VERSION < 400000)
 73
 74// 清除由 ldrex 创建的独占锁
 75__ASM void __CLREX(void)
 76{
 77  clrex
 78}
 79
 80// 获取 basepri 寄存器的值
 81__ASM uint32_t  __get_BASEPRI(void)
 82{
 83  mrs r0, basepri
 84  bx lr
 85}
 86
 87// 设置 basepri 寄存器的值 (屏蔽优先级低于 basepri 的中断)
 88__ASM void __set_BASEPRI(uint32_t basePri)
 89{
 90  msr basepri, r0
 91  bx lr
 92}
 93
 94// 获取 primask 寄存器的值
 95__ASM uint32_t __get_PRIMASK(void)
 96{
 97  mrs r0, primask
 98  bx lr
 99}
100
101// 设置 primask 寄存器的值 (屏蔽除 NMI 和 HardFault 外的所有中断)
102__ASM void __set_PRIMASK(uint32_t priMask)
103{
104  msr primask, r0
105  bx lr
106}
107
108// 获取 faultmask 寄存器的值
109__ASM uint32_t  __get_FAULTMASK(void)
110{
111  mrs r0, faultmask
112  bx lr
113}
114
115// 设置 faultmask 寄存器的值 (屏蔽除 NMI 外的所有中断)
116__ASM void __set_FAULTMASK(uint32_t faultMask)
117{
118  msr faultmask, r0
119  bx lr
120}
121
122// 获取 control 寄存器的值
123__ASM uint32_t __get_CONTROL(void)
124{
125  mrs r0, control
126  bx lr
127}
128
129// 设置 control 寄存器的值 ( control 寄存器用于特权模式的切换、主栈/进程栈的切换)
130__ASM void __set_CONTROL(uint32_t control)
131{
132  msr control, r0
133  bx lr
134}
135
136#endif
137
138
139
140#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
141#pragma diag_suppress=Pe940
142
143uint32_t __get_PSP(void)
144{
145  __ASM("mrs r0, psp");
146  __ASM("bx lr");
147}
148
149void __set_PSP(uint32_t topOfProcStack)
150{
151  __ASM("msr psp, r0");
152  __ASM("bx lr");
153}
154
155uint32_t __get_MSP(void)
156{
157  __ASM("mrs r0, msp");
158  __ASM("bx lr");
159}
160
161void __set_MSP(uint32_t topOfMainStack)
162{
163  __ASM("msr msp, r0");
164  __ASM("bx lr");
165}
166
167uint32_t __REV16(uint16_t value)
168{
169  __ASM("rev16 r0, r0");
170  __ASM("bx lr");
171}
172
173uint32_t __RBIT(uint32_t value)
174{
175  __ASM("rbit r0, r0");
176  __ASM("bx lr");
177}
178
179uint8_t __LDREXB(uint8_t *addr)
180{
181  __ASM("ldrexb r0, [r0]");
182  __ASM("bx lr"); 
183}
184
185uint16_t __LDREXH(uint16_t *addr)
186{
187  __ASM("ldrexh r0, [r0]");
188  __ASM("bx lr");
189}
190
191uint32_t __LDREXW(uint32_t *addr)
192{
193  __ASM("ldrex r0, [r0]");
194  __ASM("bx lr");
195}
196
197uint32_t __STREXB(uint8_t value, uint8_t *addr)
198{
199  __ASM("strexb r0, r0, [r1]");
200  __ASM("bx lr");
201}
202
203uint32_t __STREXH(uint16_t value, uint16_t *addr)
204{
205  __ASM("strexh r0, r0, [r1]");
206  __ASM("bx lr");
207}
208
209uint32_t __STREXW(uint32_t value, uint32_t *addr)
210{
211  __ASM("strex r0, r0, [r1]");
212  __ASM("bx lr");
213}
214
215#pragma diag_default=Pe940
216
217
218#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
219
220// naked 属性告诉编译器不生成任何序言/尾声代码,即程序员必须自己处理 寄存器保存/恢复, 栈指针调整 , 函数返回
221uint32_t __get_PSP(void) __attribute__( ( naked ) );
222uint32_t __get_PSP(void)
223{
224  uint32_t result=0;
225
226  __ASM volatile ("MRS %0, psp\n\t" 
227                  "MOV r0, %0 \n\t"
228                  "BX  lr     \n\t"  : "=r" (result) );
229  return(result);
230}
231
232void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
233void __set_PSP(uint32_t topOfProcStack)
234{
235  __ASM volatile ("MSR psp, %0\n\t"
236                  "BX  lr     \n\t" : : "r" (topOfProcStack) );
237}
238
239uint32_t __get_MSP(void) __attribute__( ( naked ) );
240uint32_t __get_MSP(void)
241{
242  uint32_t result=0;
243
244  __ASM volatile ("MRS %0, msp\n\t" 
245                  "MOV r0, %0 \n\t"
246                  "BX  lr     \n\t"  : "=r" (result) );
247  return(result);
248}
249
250void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
251void __set_MSP(uint32_t topOfMainStack)
252{
253  __ASM volatile ("MSR msp, %0\n\t"
254                  "BX  lr     \n\t" : : "r" (topOfMainStack) );
255}
256
257uint32_t __get_BASEPRI(void)
258{
259  uint32_t result=0;
260  
261  __ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
262  return(result);
263}
264
265void __set_BASEPRI(uint32_t value)
266{
267  __ASM volatile ("MSR basepri, %0" : : "r" (value) );
268}
269
270uint32_t __get_PRIMASK(void)
271{
272  uint32_t result=0;
273
274  __ASM volatile ("MRS %0, primask" : "=r" (result) );
275  return(result);
276}
277
278void __set_PRIMASK(uint32_t priMask)
279{
280  __ASM volatile ("MSR primask, %0" : : "r" (priMask) );
281}
282
283uint32_t __get_FAULTMASK(void)
284{
285  uint32_t result=0;
286  
287  __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
288  return(result);
289}
290
291void __set_FAULTMASK(uint32_t faultMask)
292{
293  __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
294}
295
296uint32_t __get_CONTROL(void)
297{
298  uint32_t result=0;
299
300  __ASM volatile ("MRS %0, control" : "=r" (result) );
301  return(result);
302}
303
304void __set_CONTROL(uint32_t control)
305{
306  __ASM volatile ("MSR control, %0" : : "r" (control) );
307}
308
309uint32_t __REV(uint32_t value)
310{
311  uint32_t result=0;
312  
313  __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
314  return(result);
315}
316
317uint32_t __REV16(uint16_t value)
318{
319  uint32_t result=0;
320  
321  __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
322  return(result);
323}
324
325int32_t __REVSH(int16_t value)
326{
327  uint32_t result=0;
328  
329  __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
330  return(result);
331}
332
333uint32_t __RBIT(uint32_t value)
334{
335  uint32_t result=0;
336  
337   __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
338   return(result);
339}
340
341uint8_t __LDREXB(uint8_t *addr)
342{
343    uint8_t result=0;
344  
345   __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
346   return(result);
347}
348
349uint16_t __LDREXH(uint16_t *addr)
350{
351    uint16_t result=0;
352  
353   __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
354   return(result);
355}
356
357uint32_t __LDREXW(uint32_t *addr)
358{
359    uint32_t result=0;
360  
361   __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
362   return(result);
363}
364
365uint32_t __STREXB(uint8_t value, uint8_t *addr)
366{
367   uint32_t result=0;
368  
369   __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
370   return(result);
371}
372
373uint32_t __STREXH(uint16_t value, uint16_t *addr)
374{
375   uint32_t result=0;
376  
377   __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
378   return(result);
379}
380
381uint32_t __STREXW(uint32_t value, uint32_t *addr)
382{
383   uint32_t result=0;
384  
385   __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
386   return(result);
387}
388
389
390#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
391/* TASKING carm specific functions */
392
393/*
394 * The CMSIS functions have been implemented as intrinsics in the compiler.
395 * Please use "carm -?i" to get an up to date list of all instrinsics,
396 * Including the CMSIS ones.
397 */
398
399#endif

STM32F10x 设备文件 #

GCC 启动文件 #

文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/startup/gcc_ride7/startup_stm32f10x_hd.s
  1.syntax unified            // 使用统一汇编语言(Unified Assembly Language, UAL)
  2.cpu cortex-m3             // 指定架构 Cortex-M3
  3.fpu softvfp               // 使用软件浮点运算,CM3 没有硬件浮点单元
  4.thumb                     // 使用 thumb 指令集
  5
  6.global  g_pfnVectors      // 声明一个全局符号 g_pfnVectors(向量表)
  7.global  Default_Handler   // 声明一个全局符号 Default_Handler(复位函数)
  8
  9/* .word 语法
 10 * .word 0x20001000        ;  分配一个字的空间,值为 0x20001000
 11 * .word Reset_Handler     ;  为 Reset_Handler 分配一个字的空间,Reset_Handler 为符号地址,可存储一个字 */
 12
 13.word  _sidata             // .data 段在 FLASH 中的起始地址,该值在链接脚本中定义(.data 包含已初始化的全局/静态变量)
 14.word  _sdata              // .data 段在  SRAM 中的起始地址,该值在链接脚本中定义
 15.word  _edata              // .data 段在  SRAM 中的结束地址,该值在链接脚本中定义
 16.word  _sbss               //  .bss 段在  SRAM 中的起始地址,该值在链接脚本中定义( .bss 包含未初始化的全局/静态变量)
 17.word  _ebss               //  .bss 段在  SRAM 中的结束地址,该值在链接脚本中定义
 18
 19
 20.equ  BootRAM, 0xF1E0F85F          // 定义 BootRAM = 0xF1E0F85F,用于 SRAM 启动
 21
 22
 23.section  .text.Reset_Handler      // 告诉汇编器将本行之后的代码或数据放入 .text.Reset_Handler 段中,直到遇到下一个 .section
 24.weak  Reset_Handler               // 声明 Reset_Handler 为弱符号,允许用户重写
 25.type  Reset_Handler, %function    // 指定 Reset_Handler 为函数类型
 26
 27Reset_Handler:  
 28    movs  r1, #0                   // r1 = 0
 29    b  LoopCopyDataInit            // 跳转到 LoopCopyDataInit 处
 30
 31CopyDataInit:
 32    ldr  r3, =_sidata              // r3 = _sidata(.data 段在 FLASH 中的起始地址)
 33    ldr  r3, [r3, r1]              // r3 = *(r3 + r1) = *(_sidata + r1)
 34    str  r3, [r0, r1]              // 存储 r3 -> *(r0 +r1),即 *(_sidata + r1) -> *(_sdata + r1)
 35    adds  r1, r1, #4               // r1 = r1 + 4,此处执行完继续向下执行 LoopCopyDataInit
 36    
 37LoopCopyDataInit:
 38    ldr  r0, =_sdata               // r0 = _sdata(.data 段在 SRAM 中的起始地址)
 39    ldr  r3, =_edata               // r3 = _edata(.data 段在 SRAM 中的结束地址)
 40    adds  r2, r0, r1               // r2 = r0 + r1 = _sdata + r1
 41    cmp  r2, r3                    // 比较 r2 和 r3 的值 --> 比较 _sdata+r1 和 _edata 的值
 42    bcc  CopyDataInit              // 如果 _sdata + r1 < _edata 则跳转到 CopyDataInit
 43    ldr  r2, =_sbss                // r2 = _sbss(.bss 段在 SRAM 中的起始地址)
 44    b  LoopFillZerobss             // 跳转到 LoopFillZerobss
 45
 46FillZerobss:
 47    movs  r3, #0                   // r3 = 0
 48    str  r3, [r2], #4              // 存储 r3 -> *r2 然后 r2 = r2 + 4 , 即存储 0 -> *_sbss 然后 _sbss = _sbss + 4
 49    
 50LoopFillZerobss:
 51    ldr  r3, = _ebss               // r3 = _ebss(.bss 段在 SRAM 中的结束地址)
 52    cmp  r2, r3                    // 比较 r2 和 r3 --> 比较 _sbss 和 _ebss
 53    bcc  FillZerobss               // 如果 _sbss < _ebss 则跳转到 FillZerobss
 54    bl  SystemInit                 // 跳转到 SystemInit 函数,并将返回地址(下一条指令的地址)保存在 LR 寄存器中
 55    bl  main                       // 跳转到       main 函数,并将返回地址(下一条指令的地址)保存在 LR 寄存器中
 56    bx  lr                         // 从 main 返回后,跳回 LR 存器地址(通常不会执行到这里)
 57
 58.size  Reset_Handler, .-Reset_Handler  // 设置 Reset_Handler 的大小为当前位置(.)减去 Reset_Handler 的起始地址
 59                                       // 显式指定符号的大小信息(边界),以便链接器可以检查符号引用是否超出范围
 60
 61
 62.section  .text.Default_Handler,"ax",%progbits  // 将 Default_Handler 代码放在 .text.Default_Handler 段中,"ax" 表示可分配+可执行
 63Default_Handler:
 64Infinite_Loop:                                  // 当处理器收到未预期的中断时执行的代码,进入死循环
 65    b  Infinite_Loop                            // 跳转到 Infinite_Loop
 66.size  Default_Handler, .-Default_Handler       // 设置 Default_Handler 的大小为当前位置(.)减去 Default_Handler 的起始地址
 67
 68
 69
 70.section  .isr_vector,"a",%progbits     // 告诉汇编器将本行之后的代码或数据(向量表)放入 .isr_vector 段,"a" 表示可分配,直到遇到下一个 .section
 71.type  g_pfnVectors, %object            // 指定 g_pfnVectors 为数据对象类型
 72.size  g_pfnVectors, .-g_pfnVectors     // 设置 g_pfnVectors 的大小,为什么 .size 指令不放向量表后面????存疑。
 73
 74    
 75g_pfnVectors:
 76    .word  _estack                        // 初始栈指针地址
 77    .word  Reset_Handler                  // 复位处理程序
 78    .word  NMI_Handler
 79    .word  HardFault_Handler
 80    .word  MemManage_Handler
 81    .word  BusFault_Handler
 82    .word  UsageFault_Handler
 83    .word  0
 84    .word  0
 85    .word  0
 86    .word  0
 87    .word  SVC_Handler
 88    .word  DebugMon_Handler
 89    .word  0
 90    .word  PendSV_Handler
 91    .word  SysTick_Handler
 92    .word  WWDG_IRQHandler
 93    .word  PVD_IRQHandler
 94    .word  TAMPER_IRQHandler
 95    .word  RTC_IRQHandler
 96    .word  FLASH_IRQHandler
 97    .word  RCC_IRQHandler
 98    .word  EXTI0_IRQHandler
 99    .word  EXTI1_IRQHandler
100    .word  EXTI2_IRQHandler
101    .word  EXTI3_IRQHandler
102    .word  EXTI4_IRQHandler
103    .word  DMA1_Channel1_IRQHandler
104    .word  DMA1_Channel2_IRQHandler
105    .word  DMA1_Channel3_IRQHandler
106    .word  DMA1_Channel4_IRQHandler
107    .word  DMA1_Channel5_IRQHandler
108    .word  DMA1_Channel6_IRQHandler
109    .word  DMA1_Channel7_IRQHandler
110    .word  ADC1_2_IRQHandler
111    .word  USB_HP_CAN1_TX_IRQHandler
112    .word  USB_LP_CAN1_RX0_IRQHandler
113    .word  CAN1_RX1_IRQHandler
114    .word  CAN1_SCE_IRQHandler
115    .word  EXTI9_5_IRQHandler
116    .word  TIM1_BRK_IRQHandler
117    .word  TIM1_UP_IRQHandler
118    .word  TIM1_TRG_COM_IRQHandler
119    .word  TIM1_CC_IRQHandler
120    .word  TIM2_IRQHandler
121    .word  TIM3_IRQHandler
122    .word  TIM4_IRQHandler
123    .word  I2C1_EV_IRQHandler
124    .word  I2C1_ER_IRQHandler
125    .word  I2C2_EV_IRQHandler
126    .word  I2C2_ER_IRQHandler
127    .word  SPI1_IRQHandler
128    .word  SPI2_IRQHandler
129    .word  USART1_IRQHandler
130    .word  USART2_IRQHandler
131    .word  USART3_IRQHandler
132    .word  EXTI15_10_IRQHandler
133    .word  RTCAlarm_IRQHandler
134    .word  USBWakeUp_IRQHandler
135    .word  TIM8_BRK_IRQHandler
136    .word  TIM8_UP_IRQHandler
137    .word  TIM8_TRG_COM_IRQHandler
138    .word  TIM8_CC_IRQHandler
139    .word  ADC3_IRQHandler
140    .word  FSMC_IRQHandler
141    .word  SDIO_IRQHandler
142    .word  TIM5_IRQHandler
143    .word  SPI3_IRQHandler
144    .word  UART4_IRQHandler
145    .word  UART5_IRQHandler
146    .word  TIM6_IRQHandler
147    .word  TIM7_IRQHandler
148    .word  DMA2_Channel1_IRQHandler
149    .word  DMA2_Channel2_IRQHandler
150    .word  DMA2_Channel3_IRQHandler
151    .word  DMA2_Channel4_5_IRQHandler
152    .word  0    // 以下为保留中断向量位置,填充为0
153    .word  0
154    .word  0
155    .word  0
156    .word  0
157    .word  0
158    .word  0
159    .word  0
160    .word  0
161    .word  0
162    .word  0
163    .word  0
164    .word  0
165    .word  0
166    .word  0
167    .word  0
168    .word  0
169    .word  0
170    .word  0
171    .word  0
172    .word  0
173    .word  0
174    .word  0
175    .word  0
176    .word  0
177    .word  0
178    .word  0
179    .word  0
180    .word  0
181    .word  0
182    .word  0
183    .word  0
184    .word  0
185    .word  0
186    .word  0
187    .word  0
188    .word  0
189    .word  0
190    .word  0
191    .word  0
192    .word  0
193    .word  0
194    .word  0
195    .word  0
196    .word  BootRAM    // 偏移:0x1E0;
197                      // BootRAM = 0xF1E0F85F = 0xF85F 0xF1E0 = LDR.W PC, [PC, #-0x1E0] -> 即 PC = *(PC - 0x1E0)
198
199
200// .weak 表示弱定义符号,用户函数可覆盖 
201// .thumb_set 将一个符号定义为另一个符号的别名 (alias),并且明确指定该别名是 Thumb 指令集的符号
202.weak  NMI_Handler
203.thumb_set NMI_Handler,Default_Handler   // 设置 NMI_Handler 为 Default_Handler 的弱别名
204
205.weak  HardFault_Handler
206.thumb_set HardFault_Handler,Default_Handler
207
208.weak  MemManage_Handler
209.thumb_set MemManage_Handler,Default_Handler
210
211.weak  BusFault_Handler
212.thumb_set BusFault_Handler,Default_Handler
213
214.weak  UsageFault_Handler
215.thumb_set UsageFault_Handler,Default_Handler
216
217.weak  SVC_Handler
218.thumb_set SVC_Handler,Default_Handler
219
220.weak  DebugMon_Handler
221.thumb_set DebugMon_Handler,Default_Handler
222
223.weak  PendSV_Handler
224.thumb_set PendSV_Handler,Default_Handler
225
226.weak  SysTick_Handler
227.thumb_set SysTick_Handler,Default_Handler
228
229.weak  WWDG_IRQHandler
230.thumb_set WWDG_IRQHandler,Default_Handler
231
232.weak  PVD_IRQHandler
233.thumb_set PVD_IRQHandler,Default_Handler
234
235.weak  TAMPER_IRQHandler
236.thumb_set TAMPER_IRQHandler,Default_Handler
237
238.weak  RTC_IRQHandler
239.thumb_set RTC_IRQHandler,Default_Handler
240
241.weak  FLASH_IRQHandler
242.thumb_set FLASH_IRQHandler,Default_Handler
243
244.weak  RCC_IRQHandler
245.thumb_set RCC_IRQHandler,Default_Handler
246
247.weak  EXTI0_IRQHandler
248.thumb_set EXTI0_IRQHandler,Default_Handler
249
250.weak  EXTI1_IRQHandler
251.thumb_set EXTI1_IRQHandler,Default_Handler
252
253.weak  EXTI2_IRQHandler
254.thumb_set EXTI2_IRQHandler,Default_Handler
255
256.weak  EXTI3_IRQHandler
257.thumb_set EXTI3_IRQHandler,Default_Handler
258
259.weak  EXTI4_IRQHandler
260.thumb_set EXTI4_IRQHandler,Default_Handler
261
262.weak  DMA1_Channel1_IRQHandler
263.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
264
265.weak  DMA1_Channel2_IRQHandler
266.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
267
268.weak  DMA1_Channel3_IRQHandler
269.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
270
271.weak  DMA1_Channel4_IRQHandler
272.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
273
274.weak  DMA1_Channel5_IRQHandler
275.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
276
277.weak  DMA1_Channel6_IRQHandler
278.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
279
280.weak  DMA1_Channel7_IRQHandler
281.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
282
283.weak  ADC1_2_IRQHandler
284.thumb_set ADC1_2_IRQHandler,Default_Handler
285
286.weak  USB_HP_CAN1_TX_IRQHandler
287.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
288
289.weak  USB_LP_CAN1_RX0_IRQHandler
290.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
291
292.weak  CAN1_RX1_IRQHandler
293.thumb_set CAN1_RX1_IRQHandler,Default_Handler
294
295.weak  CAN1_SCE_IRQHandler
296.thumb_set CAN1_SCE_IRQHandler,Default_Handler
297
298.weak  EXTI9_5_IRQHandler
299.thumb_set EXTI9_5_IRQHandler,Default_Handler
300
301.weak  TIM1_BRK_IRQHandler
302.thumb_set TIM1_BRK_IRQHandler,Default_Handler
303
304.weak  TIM1_UP_IRQHandler
305.thumb_set TIM1_UP_IRQHandler,Default_Handler
306
307.weak  TIM1_TRG_COM_IRQHandler
308.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
309
310.weak  TIM1_CC_IRQHandler
311.thumb_set TIM1_CC_IRQHandler,Default_Handler
312
313.weak  TIM2_IRQHandler
314.thumb_set TIM2_IRQHandler,Default_Handler
315
316.weak  TIM3_IRQHandler
317.thumb_set TIM3_IRQHandler,Default_Handler
318
319.weak  TIM4_IRQHandler
320.thumb_set TIM4_IRQHandler,Default_Handler
321
322.weak  I2C1_EV_IRQHandler
323.thumb_set I2C1_EV_IRQHandler,Default_Handler
324
325.weak  I2C1_ER_IRQHandler
326.thumb_set I2C1_ER_IRQHandler,Default_Handler
327
328.weak  I2C2_EV_IRQHandler
329.thumb_set I2C2_EV_IRQHandler,Default_Handler
330
331.weak  I2C2_ER_IRQHandler
332.thumb_set I2C2_ER_IRQHandler,Default_Handler
333
334.weak  SPI1_IRQHandler
335.thumb_set SPI1_IRQHandler,Default_Handler
336
337.weak  SPI2_IRQHandler
338.thumb_set SPI2_IRQHandler,Default_Handler
339
340.weak  USART1_IRQHandler
341.thumb_set USART1_IRQHandler,Default_Handler
342
343.weak  USART2_IRQHandler
344.thumb_set USART2_IRQHandler,Default_Handler
345
346.weak  USART3_IRQHandler
347.thumb_set USART3_IRQHandler,Default_Handler
348
349.weak  EXTI15_10_IRQHandler
350.thumb_set EXTI15_10_IRQHandler,Default_Handler
351
352.weak  RTCAlarm_IRQHandler
353.thumb_set RTCAlarm_IRQHandler,Default_Handler
354
355.weak  USBWakeUp_IRQHandler
356.thumb_set USBWakeUp_IRQHandler,Default_Handler
357
358.weak  TIM8_BRK_IRQHandler
359.thumb_set TIM8_BRK_IRQHandler,Default_Handler
360
361.weak  TIM8_UP_IRQHandler
362.thumb_set TIM8_UP_IRQHandler,Default_Handler
363
364.weak  TIM8_TRG_COM_IRQHandler
365.thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler
366
367.weak  TIM8_CC_IRQHandler
368.thumb_set TIM8_CC_IRQHandler,Default_Handler
369
370.weak  ADC3_IRQHandler
371.thumb_set ADC3_IRQHandler,Default_Handler
372
373.weak  FSMC_IRQHandler
374.thumb_set FSMC_IRQHandler,Default_Handler
375
376.weak  SDIO_IRQHandler
377.thumb_set SDIO_IRQHandler,Default_Handler
378
379.weak  TIM5_IRQHandler
380.thumb_set TIM5_IRQHandler,Default_Handler
381
382.weak  SPI3_IRQHandler
383.thumb_set SPI3_IRQHandler,Default_Handler
384
385.weak  UART4_IRQHandler
386.thumb_set UART4_IRQHandler,Default_Handler
387
388.weak  UART5_IRQHandler
389.thumb_set UART5_IRQHandler,Default_Handler
390
391.weak  TIM6_IRQHandler
392.thumb_set TIM6_IRQHandler,Default_Handler
393
394.weak  TIM7_IRQHandler
395.thumb_set TIM7_IRQHandler,Default_Handler
396
397.weak  DMA2_Channel1_IRQHandler
398.thumb_set DMA2_Channel1_IRQHandler,Default_Handler
399
400.weak  DMA2_Channel2_IRQHandler
401.thumb_set DMA2_Channel2_IRQHandler,Default_Handler
402
403.weak  DMA2_Channel3_IRQHandler
404.thumb_set DMA2_Channel3_IRQHandler,Default_Handler
405
406.weak  DMA2_Channel4_5_IRQHandler
407.thumb_set DMA2_Channel4_5_IRQHandler,Default_Handler

STM32 芯片命名规则 #

STM32
STM32
F
F
103
103
Z
Z
E
E
T
T
6
6
家族
家族
32
32
8 位MCU
8 位MCU
8
8
32 位MCU
32 位MCU
产品类别
产品类别
A
A
基础型
基础型
F
F
汽车级
汽车级
超低功耗
超低功耗
L
L
标准型
标准型
S
S
触摸感应
触摸感应
T
T
无线产品
无线产品
W
W
特定功能
特定功能
051
051
基础型
基础型
103
103
入门级
入门级
103升级版
103升级版
303
303
高性能
高性能
407
407
超低功耗
超低功耗
152
152
引脚数
引脚数
T
T
C
C
36 脚
36 脚
R
R
V
V
Z
Z
48 脚
48 脚
64 脚
64 脚
100 脚
100 脚
144 脚
144 脚
闪存容量
闪存容量
4
4
6
6
16K
16K
8
8
B
B
C
C
32K
32K
64K
64K
128K
128K
256K
256K
D
D
E
E
G
G
384K
384K
512K
512K
1024K
1024K
封装
封装
T
T
U
U
Y
Y
LQFP
LQFP
UFQFPN
UFQFPN
WLCSP
WLCSP
温度
温度
6
6
-40℃~85℃
-40℃~85℃
7
7
-40℃~105℃
-40℃~105℃

启动文件后缀 #

hd
hd
xl
xl
cl
cl
vl
vl
ld
ld
md
md
Low Density
Low Density
High Density
High Density
XL-Density
XL-Density
Value Line
Value Line
低容量
低容量
中容量
中容量
超大容量
超大容量
超值型产品
超值型产品
16 - 32K
16 - 32K
64 - 128K
64 - 128K
F105/107 系列
F105/107 系列
F100 系列
F100 系列
互联型产品
互联型产品
Connectivity Line
Connectivity Line
256 - 512K
256 - 512K
512 - 1024K
512 - 1024K
高容量
高容量
Medium Density
Medium Density

stm32f10x.h #

stm32f10x.h 文件很长,以下截取部分关键代码:

文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/stm32f10x.h
  1#ifndef __STM32F10x_H
  2#define __STM32F10x_H
  3
  4#ifdef __cplusplus
  5    extern "C" {
  6#endif
  7  
  8// 选择目标设备,这里的宏需要用户自己在代码中定义,或者通过编译器参数传递如 -D STM32F10X_HD
  9#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) 
 10    // #define STM32F10X_LD
 11    // #define STM32F10X_LD_VL
 12    // #define STM32F10X_MD
 13    // #define STM32F10X_MD_VL
 14    // #define STM32F10X_HD
 15    // #define STM32F10X_HD_VL
 16    // #define STM32F10X_XL
 17    // #define STM32F10X_CL
 18#endif
 19
 20
 21// 如果没有定义目标设备,这里会报错
 22#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)
 23    #error "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)"
 24#endif
 25
 26
 27// 是否使用标准库外设驱动
 28#if !defined  (USE_STDPERIPH_DRIVER)
 29    #define USE_STDPERIPH_DRIVER
 30#endif
 31
 32
 33// 外部晶振频率,在 system_stm32f10x.c 中,系统初始化函数 SystemInit 会设置时钟,需要 HSE_VALUE
 34#if !defined  HSE_VALUE
 35    #ifdef STM32F10X_CL   
 36        #define HSE_VALUE    ((uint32_t)25000000)  // 25 MHz
 37    #else
 38        #define HSE_VALUE    ((uint32_t)8000000)   // 8 MHz
 39    #endif
 40#endif
 41
 42
 43// 外部晶振启动的等待时间,当 STM32 尝试启动外部晶振时,需要等待晶振稳定
 44#if !defined  (HSE_STARTUP_TIMEOUT) 
 45    #define HSE_STARTUP_TIMEOUT    ((uint16_t)0x0500)  // 这只是大致的一个计数值,约 0.5 秒
 46#endif
 47
 48
 49// 内部晶振频率
 50#if !defined  (HSI_VALUE)   
 51    #define HSI_VALUE    ((uint32_t)8000000)    // 8 MHz
 52#endif
 53
 54
 55// 定义标准库版本 V3.6.4
 56#define __STM32F10X_STDPERIPH_VERSION_MAIN   (0x03) // [31:24] main version
 57#define __STM32F10X_STDPERIPH_VERSION_SUB1   (0x06) // [23:16] sub1 version
 58#define __STM32F10X_STDPERIPH_VERSION_SUB2   (0x04) // [15:8]  sub2 version
 59#define __STM32F10X_STDPERIPH_VERSION_RC     (0x00) // [7:0]   release candidate
 60#define __STM32F10X_STDPERIPH_VERSION        ((__STM32F10X_STDPERIPH_VERSION_MAIN << 24)\
 61                                             |(__STM32F10X_STDPERIPH_VERSION_SUB1 << 16)\
 62                                             |(__STM32F10X_STDPERIPH_VERSION_SUB2 << 8)\
 63                                             |(__STM32F10X_STDPERIPH_VERSION_RC))
 64
 65
 66// CM3 处理器与内核系统组件配置
 67#ifdef STM32F10X_XL
 68    #define __MPU_PRESENT             1      // STM32 超大容量设备包含 MPU
 69#else
 70    #define __MPU_PRESENT             0      // 其它设备不含 MPU
 71#endif
 72
 73#define __CM3_REV                 0x0200     // 内核修订版本 r2p0
 74#define __NVIC_PRIO_BITS          4          // 4 Bits 优先级位宽
 75#define __Vendor_SysTickConfig    0          // 针对特定厂商的 SysTick 配置?不太清楚
 76
 77
 78
 79// CM3 的中断源编号从 1 开始,1 - 15 是系统异常,16 - 255 是外部中断
 80// 枚举值使用负数,是为了区分系统异常与外部中断,提升部分函数效率,如 core_cm3.h 中的 NVIC_SetPriority 函数
 81typedef enum IRQn
 82{
 83/************************  系统异常枚举值   *******************************************************/
 84  NonMaskableInt_IRQn         = -14,    /*!< 2 Non Maskable Interrupt                             */
 85  MemoryManagement_IRQn       = -12,    /*!< 4 Cortex-M3 Memory Management Interrupt              */
 86  BusFault_IRQn               = -11,    /*!< 5 Cortex-M3 Bus Fault Interrupt                      */
 87  UsageFault_IRQn             = -10,    /*!< 6 Cortex-M3 Usage Fault Interrupt                    */
 88  SVCall_IRQn                 = -5,     /*!< 11 Cortex-M3 SV Call Interrupt                       */
 89  DebugMonitor_IRQn           = -4,     /*!< 12 Cortex-M3 Debug Monitor Interrupt                 */
 90  PendSV_IRQn                 = -2,     /*!< 14 Cortex-M3 Pend SV Interrupt                       */
 91  SysTick_IRQn                = -1,     /*!< 15 Cortex-M3 System Tick Interrupt                   */
 92
 93/************************  外部中断枚举值   *******************************************************/
 94  WWDG_IRQn                   = 0,      /*!< Window WatchDog Interrupt                            */
 95  PVD_IRQn                    = 1,      /*!< PVD through EXTI Line detection Interrupt            */
 96  TAMPER_IRQn                 = 2,      /*!< Tamper Interrupt                                     */
 97  RTC_IRQn                    = 3,      /*!< RTC global Interrupt                                 */
 98  FLASH_IRQn                  = 4,      /*!< FLASH global Interrupt                               */
 99  RCC_IRQn                    = 5,      /*!< RCC global Interrupt                                 */
100  EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                 */
101  EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                 */
102  EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                 */
103  EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                 */
104  EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                 */
105  DMA1_Channel1_IRQn          = 11,     /*!< DMA1 Channel 1 global Interrupt                      */
106  DMA1_Channel2_IRQn          = 12,     /*!< DMA1 Channel 2 global Interrupt                      */
107  DMA1_Channel3_IRQn          = 13,     /*!< DMA1 Channel 3 global Interrupt                      */
108  DMA1_Channel4_IRQn          = 14,     /*!< DMA1 Channel 4 global Interrupt                      */
109  DMA1_Channel5_IRQn          = 15,     /*!< DMA1 Channel 5 global Interrupt                      */
110  DMA1_Channel6_IRQn          = 16,     /*!< DMA1 Channel 6 global Interrupt                      */
111  DMA1_Channel7_IRQn          = 17,     /*!< DMA1 Channel 7 global Interrupt                      */
112
113#ifdef STM32F10X_LD
114  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
115  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
116  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
117  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
118  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
119  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
120  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
121  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
122  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
123  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
124  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
125  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
126  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
127  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
128  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
129  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
130  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
131  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
132  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
133  USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
134#endif /* STM32F10X_LD */  
135
136#ifdef STM32F10X_LD_VL
137  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
138  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
139  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
140  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
141  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
142  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
143  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
144  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
145  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
146  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
147  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
148  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
149  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
150  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
151  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
152  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
153  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
154  TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */
155#endif /* STM32F10X_LD_VL */
156
157#ifdef STM32F10X_MD
158  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
159  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
160  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
161  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
162  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
163  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
164  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
165  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
166  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
167  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
168  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
169  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
170  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
171  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
172  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
173  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
174  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
175  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
176  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
177  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
178  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
179  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
180  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
181  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
182  USBWakeUp_IRQn              = 42      /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
183#endif /* STM32F10X_MD */  
184
185#ifdef STM32F10X_MD_VL
186  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
187  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
188  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
189  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
190  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
191  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
192  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
193  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
194  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
195  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
196  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
197  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
198  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
199  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
200  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
201  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
202  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
203  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
204  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
205  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
206  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
207  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
208  TIM7_IRQn                   = 55      /*!< TIM7 Interrupt                                       */
209#endif /* STM32F10X_MD_VL */
210
211#ifdef STM32F10X_HD
212  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
213  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
214  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
215  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
216  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
217  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
218  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
219  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
220  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
221  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
222  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
223  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
224  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
225  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
226  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
227  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
228  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
229  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
230  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
231  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
232  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
233  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
234  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
235  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
236  USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
237  TIM8_BRK_IRQn               = 43,     /*!< TIM8 Break Interrupt                                 */
238  TIM8_UP_IRQn                = 44,     /*!< TIM8 Update Interrupt                                */
239  TIM8_TRG_COM_IRQn           = 45,     /*!< TIM8 Trigger and Commutation Interrupt               */
240  TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
241  ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
242  FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
243  SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
244  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
245  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
246  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
247  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
248  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
249  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
250  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
251  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
252  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
253  DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
254#endif /* STM32F10X_HD */  
255
256#ifdef STM32F10X_HD_VL
257  ADC1_IRQn                   = 18,     /*!< ADC1 global Interrupt                                */
258  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
259  TIM1_BRK_TIM15_IRQn         = 24,     /*!< TIM1 Break and TIM15 Interrupts                      */
260  TIM1_UP_TIM16_IRQn          = 25,     /*!< TIM1 Update and TIM16 Interrupts                     */
261  TIM1_TRG_COM_TIM17_IRQn     = 26,     /*!< TIM1 Trigger and Commutation and TIM17 Interrupt     */
262  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
263  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
264  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
265  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
266  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
267  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
268  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
269  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
270  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
271  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
272  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
273  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
274  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
275  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
276  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
277  CEC_IRQn                    = 42,     /*!< HDMI-CEC Interrupt                                   */
278  TIM12_IRQn                  = 43,     /*!< TIM12 global Interrupt                               */
279  TIM13_IRQn                  = 44,     /*!< TIM13 global Interrupt                               */
280  TIM14_IRQn                  = 45,     /*!< TIM14 global Interrupt                               */
281  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
282  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
283  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
284  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
285  TIM6_DAC_IRQn               = 54,     /*!< TIM6 and DAC underrun Interrupt                      */
286  TIM7_IRQn                   = 55,     /*!< TIM7 Interrupt                                       */
287  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
288  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
289  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
290  DMA2_Channel4_5_IRQn        = 59,     /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
291  DMA2_Channel5_IRQn          = 60      /*!< DMA2 Channel 5 global Interrupt (DMA2 Channel 5 is 
292                                             mapped at position 60 only if the MISC_REMAP bit in 
293                                             the AFIO_MAPR2 register is set)                      */
294#endif /* STM32F10X_HD_VL */
295
296#ifdef STM32F10X_XL
297  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
298  USB_HP_CAN1_TX_IRQn         = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
299  USB_LP_CAN1_RX0_IRQn        = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
300  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
301  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
302  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
303  TIM1_BRK_TIM9_IRQn          = 24,     /*!< TIM1 Break Interrupt and TIM9 global Interrupt       */
304  TIM1_UP_TIM10_IRQn          = 25,     /*!< TIM1 Update Interrupt and TIM10 global Interrupt     */
305  TIM1_TRG_COM_TIM11_IRQn     = 26,     /*!< TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt */
306  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
307  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
308  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
309  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
310  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
311  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
312  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
313  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
314  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
315  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
316  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
317  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
318  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
319  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
320  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
321  USBWakeUp_IRQn              = 42,     /*!< USB Device WakeUp from suspend through EXTI Line Interrupt */
322  TIM8_BRK_TIM12_IRQn         = 43,     /*!< TIM8 Break Interrupt and TIM12 global Interrupt      */
323  TIM8_UP_TIM13_IRQn          = 44,     /*!< TIM8 Update Interrupt and TIM13 global Interrupt     */
324  TIM8_TRG_COM_TIM14_IRQn     = 45,     /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */
325  TIM8_CC_IRQn                = 46,     /*!< TIM8 Capture Compare Interrupt                       */
326  ADC3_IRQn                   = 47,     /*!< ADC3 global Interrupt                                */
327  FSMC_IRQn                   = 48,     /*!< FSMC global Interrupt                                */
328  SDIO_IRQn                   = 49,     /*!< SDIO global Interrupt                                */
329  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
330  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
331  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
332  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
333  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
334  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
335  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
336  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
337  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
338  DMA2_Channel4_5_IRQn        = 59      /*!< DMA2 Channel 4 and Channel 5 global Interrupt        */
339#endif /* STM32F10X_XL */  
340
341#ifdef STM32F10X_CL
342  ADC1_2_IRQn                 = 18,     /*!< ADC1 and ADC2 global Interrupt                       */
343  CAN1_TX_IRQn                = 19,     /*!< USB Device High Priority or CAN1 TX Interrupts       */
344  CAN1_RX0_IRQn               = 20,     /*!< USB Device Low Priority or CAN1 RX0 Interrupts       */
345  CAN1_RX1_IRQn               = 21,     /*!< CAN1 RX1 Interrupt                                   */
346  CAN1_SCE_IRQn               = 22,     /*!< CAN1 SCE Interrupt                                   */
347  EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                        */
348  TIM1_BRK_IRQn               = 24,     /*!< TIM1 Break Interrupt                                 */
349  TIM1_UP_IRQn                = 25,     /*!< TIM1 Update Interrupt                                */
350  TIM1_TRG_COM_IRQn           = 26,     /*!< TIM1 Trigger and Commutation Interrupt               */
351  TIM1_CC_IRQn                = 27,     /*!< TIM1 Capture Compare Interrupt                       */
352  TIM2_IRQn                   = 28,     /*!< TIM2 global Interrupt                                */
353  TIM3_IRQn                   = 29,     /*!< TIM3 global Interrupt                                */
354  TIM4_IRQn                   = 30,     /*!< TIM4 global Interrupt                                */
355  I2C1_EV_IRQn                = 31,     /*!< I2C1 Event Interrupt                                 */
356  I2C1_ER_IRQn                = 32,     /*!< I2C1 Error Interrupt                                 */
357  I2C2_EV_IRQn                = 33,     /*!< I2C2 Event Interrupt                                 */
358  I2C2_ER_IRQn                = 34,     /*!< I2C2 Error Interrupt                                 */
359  SPI1_IRQn                   = 35,     /*!< SPI1 global Interrupt                                */
360  SPI2_IRQn                   = 36,     /*!< SPI2 global Interrupt                                */
361  USART1_IRQn                 = 37,     /*!< USART1 global Interrupt                              */
362  USART2_IRQn                 = 38,     /*!< USART2 global Interrupt                              */
363  USART3_IRQn                 = 39,     /*!< USART3 global Interrupt                              */
364  EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                      */
365  RTCAlarm_IRQn               = 41,     /*!< RTC Alarm through EXTI Line Interrupt                */
366  OTG_FS_WKUP_IRQn            = 42,     /*!< USB OTG FS WakeUp from suspend through EXTI Line Interrupt */
367  TIM5_IRQn                   = 50,     /*!< TIM5 global Interrupt                                */
368  SPI3_IRQn                   = 51,     /*!< SPI3 global Interrupt                                */
369  UART4_IRQn                  = 52,     /*!< UART4 global Interrupt                               */
370  UART5_IRQn                  = 53,     /*!< UART5 global Interrupt                               */
371  TIM6_IRQn                   = 54,     /*!< TIM6 global Interrupt                                */
372  TIM7_IRQn                   = 55,     /*!< TIM7 global Interrupt                                */
373  DMA2_Channel1_IRQn          = 56,     /*!< DMA2 Channel 1 global Interrupt                      */
374  DMA2_Channel2_IRQn          = 57,     /*!< DMA2 Channel 2 global Interrupt                      */
375  DMA2_Channel3_IRQn          = 58,     /*!< DMA2 Channel 3 global Interrupt                      */
376  DMA2_Channel4_IRQn          = 59,     /*!< DMA2 Channel 4 global Interrupt                      */
377  DMA2_Channel5_IRQn          = 60,     /*!< DMA2 Channel 5 global Interrupt                      */
378  ETH_IRQn                    = 61,     /*!< Ethernet global Interrupt                            */
379  ETH_WKUP_IRQn               = 62,     /*!< Ethernet Wakeup through EXTI line Interrupt          */
380  CAN2_TX_IRQn                = 63,     /*!< CAN2 TX Interrupt                                    */
381  CAN2_RX0_IRQn               = 64,     /*!< CAN2 RX0 Interrupt                                   */
382  CAN2_RX1_IRQn               = 65,     /*!< CAN2 RX1 Interrupt                                   */
383  CAN2_SCE_IRQn               = 66,     /*!< CAN2 SCE Interrupt                                   */
384  OTG_FS_IRQn                 = 67      /*!< USB OTG FS global Interrupt                          */
385#endif /* STM32F10X_CL */
386} IRQn_Type;
387
388
389#include "core_cm3.h"
390#include "system_stm32f10x.h"
391#include <stdint.h>
392
393
394// 后面都是外设的寄存器结构体 / 外设地址的定义,很长,就省略了...
395
396省略...
397
398typedef struct
399{
400  __IO uint32_t CRL;
401  __IO uint32_t CRH;
402  __IO uint32_t IDR;
403  __IO uint32_t ODR;
404  __IO uint32_t BSRR;
405  __IO uint32_t BRR;
406  __IO uint32_t LCKR;
407} GPIO_TypeDef;
408
409省略...
410#define FLASH_BASE            ((uint32_t)0x08000000)
411#define SRAM_BASE             ((uint32_t)0x20000000)
412
413#define APB1PERIPH_BASE       PERIPH_BASE
414#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
415#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)
416
417省略...
418
419#define GPIOA_BASE            (APB2PERIPH_BASE + 0x0800)
420#define GPIOB_BASE            (APB2PERIPH_BASE + 0x0C00)
421#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)
422#define GPIOD_BASE            (APB2PERIPH_BASE + 0x1400)
423#define GPIOE_BASE            (APB2PERIPH_BASE + 0x1800)
424#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)
425#define GPIOG_BASE            (APB2PERIPH_BASE + 0x2000)
426
427省略...
428
429#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
430#define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
431#define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
432#define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
433#define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
434#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
435#define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
436
437省略...
438
439#ifdef USE_STDPERIPH_DRIVER
440    #include "stm32f10x_conf.h"
441#endif
442
443省略...

预定义宏 #

STM32F10X_LD         : 按启动文件后缀,选择一个
STM32F10X_MD         : 
STM32F10X_HD         : 
STM32F10X_XL         : 
STM32F10X_CL         : 
STM32F10X_LD_VL      : 
STM32F10X_MD_VL      : 
STM32F10X_HD_VL      :
USE_STDPERIPH_DRIVER : 使用标准库外设驱动
HSE_VALUE            : 外部晶振频率
HSE_STARTUP_TIMEOUT  : 外部晶振启动的等待时间
HSI_VALUE            : 内部晶振频率

一般不直接在 stm32f10x.h 中设置上述宏,而是通过编译器参数传递:

$ arm-none-eabi-gcc -D STM32F10X_HD  -D USE_STDPERIPH_DRIVER  -D HSE_VALUE=8000000

头文件包含 #

#include "core_cm3.h"
#include "system_stm32f10x.h"

#ifdef USE_STDPERIPH_DRIVER
    #include "stm32f10x_conf.h"
#endif

stm32f10x.h 并不调用 core_cm3.hsystem_stm32f10x.hstm32f10x_conf.h 中的任何函数与宏定义。用户程序只需要包含 stm32f10x.h,就可以调用内核/外设函数及宏定义。

system_stm32f10x.h #

文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.h
 1
 2#ifndef __SYSTEM_STM32F10X_H
 3#define __SYSTEM_STM32F10X_H
 4
 5#ifdef __cplusplus
 6 extern "C" {
 7#endif 
 8
 9extern uint32_t SystemCoreClock;             // 内核时钟 HCLK 频率,该变量在 system_stm32f10x.c 中定义,用户应用程序可用它来设置 SysTick 定时器或配置其他参数
10extern void SystemInit(void);                // 设置系统时钟,该函数在启动文件中会被调用
11extern void SystemCoreClockUpdate(void);     // 更新 SystemCoreClock 变量,必须在程序执行期间内核时钟发生变化时调用
12
13#ifdef __cplusplus
14}
15#endif
16
17#endif

system_stm32f10x.c #

文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
  1#include "stm32f10x.h"
  2
  3
  4#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  5    // #define SYSCLK_FREQ_HSE    HSE_VALUE  // 使用 HSE 作为系统时钟源,不进行倍频,最终频率 = HSE_VALUE
  6    #define SYSCLK_FREQ_24MHz  24000000      // 定义 24MHz 系统时钟频率
  7#else
  8    // #define SYSCLK_FREQ_HSE    HSE_VALUE  // 使用 HSE 作为系统时钟源,不进行倍频,最终频率 = HSE_VALUE
  9    // #define SYSCLK_FREQ_24MHz  24000000   // 定义 24MHz 系统时钟频率
 10    // #define SYSCLK_FREQ_36MHz  36000000   // 定义 36MHz 系统时钟频率
 11    // #define SYSCLK_FREQ_48MHz  48000000   // 定义 48MHz 系统时钟频率
 12    // #define SYSCLK_FREQ_56MHz  56000000   // 定义 56MHz 系统时钟频率
 13    #define SYSCLK_FREQ_72MHz  72000000      // 定义 72MHz 系统时钟频率
 14#endif
 15
 16
 17// 如果需要使用安装在STM3210E-EVAL板(STM32高密度和XL密度设备)
 18// 或STM32100E-EVAL板(STM32高密度Value line设备)上的外部SRAM作为数据存储器,请取消注释以下行
 19#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
 20    // #define DATA_IN_ExtSRAM               // 定义使用外部 SRAM
 21#endif
 22
 23
 24// 如果需要将向量表重定位到内部SRAM中,请取消注释以下行
 25// #define VECT_TAB_SRAM                     // 定义向量表在SRAM中
 26#define VECT_TAB_OFFSET  0x0                 // 向量表基址偏移量字段,此值必须是0x200的倍数
 27
 28
 29// 时钟定义
 30#ifdef SYSCLK_FREQ_HSE
 31  uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;
 32#elif defined SYSCLK_FREQ_24MHz
 33  uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz;
 34#elif defined SYSCLK_FREQ_36MHz
 35  uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz;
 36#elif defined SYSCLK_FREQ_48MHz
 37  uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz;
 38#elif defined SYSCLK_FREQ_56MHz
 39  uint32_t SystemCoreClock         = SYSCLK_FREQ_56MHz;
 40#elif defined SYSCLK_FREQ_72MHz
 41  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;
 42#else
 43  uint32_t SystemCoreClock         = HSI_VALUE;    // 使用内部晶振频率作为系统时钟频率,HSI_VALUE 在 stm32f10x.h 被定义
 44#endif
 45
 46
 47__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};   // AHB 预分频器表
 48
 49
 50static void SetSysClock(void);                // 设置系统时钟函数
 51
 52
 53#ifdef SYSCLK_FREQ_HSE
 54    static void SetSysClockToHSE(void);       // 设置系统时钟为 HSE
 55#elif defined SYSCLK_FREQ_24MHz
 56    static void SetSysClockTo24(void);        // 设置系统时钟为 24MHz
 57#elif defined SYSCLK_FREQ_36MHz
 58    static void SetSysClockTo36(void);        // 设置系统时钟为 36MHz
 59#elif defined SYSCLK_FREQ_48MHz
 60    static void SetSysClockTo48(void);        // 设置系统时钟为 48MHz
 61#elif defined SYSCLK_FREQ_56MHz
 62    static void SetSysClockTo56(void);        // 设置系统时钟为 56MHz
 63#elif defined SYSCLK_FREQ_72MHz
 64    static void SetSysClockTo72(void);        // 设置系统时钟为 72MHz
 65#endif
 66
 67
 68// DATA_IN_ExtSRAM 由用户定义,用于指示是否将数据段(全局变量、静态变量等)分配到外部 SRAM 中执行
 69#ifdef DATA_IN_ExtSRAM
 70    static void SystemInit_ExtMemCtl(void);   // 外部存储器控制器初始化
 71#endif
 72
 73
 74void SystemInit (void)
 75{
 76    // 将 RCC 时钟配置重置为默认复位状态(用于调试目的)
 77    // 设置 HSION 位,即使能 HSI (内部时钟源)
 78    RCC->CR |= (uint32_t)0x00000001;
 79
 80    // 复位 SW、HPRE、PPRE1、PPRE2、ADCPRE 和 MCO位
 81#ifndef STM32F10X_CL
 82	RCC->CFGR &= (uint32_t)0xF8FF0000;
 83#else
 84	RCC->CFGR &= (uint32_t)0xF0FF0000;
 85#endif
 86  
 87    // 复位 HSEON、CSSON 和 PLLON 位
 88    RCC->CR &= (uint32_t)0xFEF6FFFF;
 89    // 复位HSEBYP位
 90    RCC->CR &= (uint32_t)0xFFFBFFFF;
 91    // 复位PLLSRC、PLLXTPRE、PLLMUL 和 USBPRE / OTGFSPRE 位
 92    RCC->CFGR &= (uint32_t)0xFF80FFFF;
 93
 94#ifdef STM32F10X_CL
 95	// 复位 PLL2ON 和 PLL3ON 位
 96	RCC->CR &= (uint32_t)0xEBFFFFFF;
 97	// 禁用所有中断并清除挂起位
 98	RCC->CIR = 0x00FF0000;
 99	// 复位CFGR2寄存器
100	RCC->CFGR2 = 0x00000000;
101#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
102	// 禁用所有中断并清除挂起位
103	RCC->CIR = 0x009F0000;
104	// 复位CFGR2寄存器
105	RCC->CFGR2 = 0x00000000;      
106#else
107	// 禁用所有中断并清除挂起位
108	RCC->CIR = 0x009F0000;
109#endif
110    
111#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
112    #ifdef DATA_IN_ExtSRAM
113         SystemInit_ExtMemCtl();      // 初始化外部存储器控制器
114    #endif
115#endif 
116
117    // 配置系统时钟频率、HCLK、PCLK2 和 PCLK1 预分频器
118    // 配置 Flash 等待周期并启用预取缓冲区
119    SetSysClock();
120
121#ifdef VECT_TAB_SRAM
122    SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  // 向量表重定位到内部 SRAM 中
123#else
124    SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 FLASH 中
125#endif 
126}
127
128
129// 根据时钟寄存器值更新 SystemCoreClock 变量
130void SystemCoreClockUpdate (void) {
131	省略...
132}
133
134
135// 设置系统时钟函数,被 SystemInit 函数调用
136static void SetSysClock(void)
137{
138#ifdef SYSCLK_FREQ_HSE
139    SetSysClockToHSE();              // 设置系统时钟为HSE
140#elif defined SYSCLK_FREQ_24MHz
141    SetSysClockTo24();               // 设置系统时钟为24MHz
142#elif defined SYSCLK_FREQ_36MHz
143    SetSysClockTo36();               // 设置系统时钟为36MHz
144#elif defined SYSCLK_FREQ_48MHz
145    SetSysClockTo48();               // 设置系统时钟为48MHz
146#elif defined SYSCLK_FREQ_56MHz
147    SetSysClockTo56();               // 设置系统时钟为56MHz
148#elif defined SYSCLK_FREQ_72MHz
149    SetSysClockTo72();               // 设置系统时钟为72MHz
150#endif                               // 如果上述定义均未启用,则HSI被用作系统时钟源(复位后的默认值)
151}
152
153
154#ifdef DATA_IN_ExtSRAM
155// 初始化外部存储器控制器
156void SystemInit_ExtMemCtl(void) {
157	省略...
158}
159#endif
160
161
162#ifdef SYSCLK_FREQ_HSE
163static void SetSysClockToHSE(void){ 省略.... }
164
165#elif defined SYSCLK_FREQ_24MHz
166static void SetSysClockTo24(void){ 省略.... }
167
168#elif defined SYSCLK_FREQ_36MHz
169static void SetSysClockTo36(void){ 省略.... }
170
171#elif defined SYSCLK_FREQ_48MHz
172static void SetSysClockTo48(void){ 省略.... }
173
174#elif defined SYSCLK_FREQ_56MHz
175static void SetSysClockTo56(void){ 省略.... }
176
177#elif defined SYSCLK_FREQ_72MHz
178static void SetSysClockTo72(void){ 省略.... }
179
180#endif

预定义宏 #

SYSCLK_FREQ_HSE    HSE_VALUE   : 使用 HSE 作为系统时钟源,不进行倍频
SYSCLK_FREQ_24MHz  24000000    : 定义 24MHz 系统时钟频率
SYSCLK_FREQ_36MHz  36000000    : 定义 36MHz 系统时钟频率
SYSCLK_FREQ_48MHz  48000000    : 定义 48MHz 系统时钟频率
SYSCLK_FREQ_56MHz  56000000    : 定义 56MHz 系统时钟频率
SYSCLK_FREQ_72MHz  72000000    : 定义 72MHz 系统时钟频率
VECT_TAB_SRAM                  : 定义向量表在 SRAMVECT_TAB_OFFSET  0x0           : 向量表基址偏移量字段,此值必须是 0x200 的倍数
DATA_IN_ExtSRAM                : 定义使用外部 SRAM

通过编译器参数配置时钟频率:

$ arm-none-eabi-gcc -D HSE_VALUE=8000000 -D SYSCLK_FREQ_48MHz=48000000

用户文件 #

以下文件在标准库的工程模板中可以找到。

标准库配置头文件 #

stm32f10x.h 中包含这个头文件。

文件Project/STM32F10x_StdPeriph_Template/stm32f10x_conf.h
 1#ifndef __STM32F10x_CONF_H
 2#define __STM32F10x_CONF_H
 3
 4#include "stm32f10x_adc.h"
 5#include "stm32f10x_bkp.h"
 6#include "stm32f10x_can.h"
 7#include "stm32f10x_cec.h"
 8#include "stm32f10x_crc.h"
 9#include "stm32f10x_dac.h"
10#include "stm32f10x_dbgmcu.h"
11#include "stm32f10x_dma.h"
12#include "stm32f10x_exti.h"
13#include "stm32f10x_flash.h"
14#include "stm32f10x_fsmc.h"
15#include "stm32f10x_gpio.h"
16#include "stm32f10x_i2c.h"
17#include "stm32f10x_iwdg.h"
18#include "stm32f10x_pwr.h"
19#include "stm32f10x_rcc.h"
20#include "stm32f10x_rtc.h"
21#include "stm32f10x_sdio.h"
22#include "stm32f10x_spi.h"
23#include "stm32f10x_tim.h"
24#include "stm32f10x_usart.h"
25#include "stm32f10x_wwdg.h"
26#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
27
28// 当启用 USE_FULL_ASSERT 后,标准库函数会对输入参数进行严格的检查
29// #define USE_FULL_ASSERT    1
30
31#ifdef  USE_FULL_ASSERT
32    #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
33    void assert_failed(uint8_t* file, uint32_t line);
34#else
35    #define assert_param(expr) ((void)0)
36#endif
37
38#endif

中断函数头文件 #

这会覆盖启动文件中的中断函数。

文件Project/STM32F10x_StdPeriph_Template/stm32f10x_it.h
 1#ifndef __STM32F10x_IT_H
 2#define __STM32F10x_IT_H
 3
 4#ifdef __cplusplus
 5 extern "C" {
 6#endif 
 7
 8#include "stm32f10x.h"
 9
10void NMI_Handler(void);
11void HardFault_Handler(void);
12void MemManage_Handler(void);
13void BusFault_Handler(void);
14void UsageFault_Handler(void);
15void SVC_Handler(void);
16void DebugMon_Handler(void);
17void PendSV_Handler(void);
18void SysTick_Handler(void);
19
20#ifdef __cplusplus
21}
22#endif
23
24#endif

中断函数源文件 #

文件Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c
 1#include "stm32f10x_it.h"
 2
 3void NMI_Handler(void)
 4{
 5}
 6
 7void HardFault_Handler(void)
 8{
 9  while (1)
10  {
11  }
12}
13
14void MemManage_Handler(void)
15{
16  while (1)
17  {
18  }
19}
20
21void BusFault_Handler(void)
22{
23  while (1)
24  {
25  }
26}
27
28void UsageFault_Handler(void)
29{
30  while (1)
31  {
32  }
33}
34
35void SVC_Handler(void)
36{
37}
38
39void DebugMon_Handler(void)
40{
41}
42
43void PendSV_Handler(void)
44{
45}
46
47void SysTick_Handler(void)
48{
49}

文件关系图 #

core_cm3.h
core_cm3.h
core_cm3.c
core_cm3.c
SysTick
SysTick
stm32f10x_adc.h
stm32f10x_adc.h
CM3 内核
CM3 内核
调试组件等
调试组件等
stm32f10x.h
stm32f10x.h
stm32f10x_it.c
stm32f10x_it.c
stm32f10x_conf.h
stm32f10x_conf.h
stm32f10x_it.h
stm32f10x_it.h
stm32f10x_adc.c
stm32f10x_adc.c
stm32f10x_gpio.h
stm32f10x_gpio.h
stm32f10x_gpio.c
stm32f10x_gpio.c
内核外设函数
内核外设函数
设备外设函数
设备外设函数
用户应用程序
用户应用程序
NVIC
NVIC
ADC
ADC
GPIO
GPIO
DMA
DMA
I2C
I2C
其它外设
其它外设
系统时钟配置函数
系统时钟配置函数
system_stm32f10x.h
system_stm32f10x.h
system_stm32f10x.c
system_stm32f10x.c

GCC 链接脚本 #

  1/* 入口点 - 程序启动后执行的第一条指令地址 */
  2ENTRY(Reset_Handler)
  3
  4/* 初始化栈顶地址 = RAM 区起始地址 + RAM 区大小 */
  5_estack = ORIGIN(RAM) + LENGTH(RAM);
  6
  7/* 所需的最小堆大小 */
  8_Min_Heap_Size = 0x1000;
  9
 10/* 所需的最小栈大小 */
 11_Min_Stack_Size = 0x400;
 12
 13/* 指定存储器区域 */
 14MEMORY
 15{
 16    RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K    /* RAM: 可执行(x)、可读(r)、可写(w),起始地址0x20000000,长度64KB */
 17    FLASH (rx)     : ORIGIN = 0x8000000,  LENGTH = 512K   /* FLASH: 只读(r)、可执行(x),起始地址0x08000000,长度512KB */
 18}
 19
 20/* 定义输出段 */
 21SECTIONS
 22{
 23    /* 创建一个 .isr_vector 段,用于存放向量表 */
 24    .isr_vector :
 25    {
 26        . = ALIGN(4);           /* 4 字节对齐,地址是 4 的倍数 */
 27        KEEP(*(.isr_vector))    /* *(.isr_vector) 表示匹配所有 .isr_vector 段;KEEP 表示保留匹配的段(防止被优化掉),.isr_vector 符号在启动文件被中定义(即向量表) */
 28        . = ALIGN(4);
 29    } >FLASH                    /* 输出到 FLASH */
 30
 31  /* 创建一个 .text 段 */
 32  .text :
 33  {
 34    . = ALIGN(4);
 35    *(.text)                    /* 匹配所有 .text 段 */
 36    *(.text*)                   /* 匹配所有以 .text 开头的段 */
 37    *(.glue_7)
 38    *(.glue_7t)
 39    *(.eh_frame)
 40
 41    KEEP (*(.init)) 
 42    KEEP (*(.fini))
 43
 44    . = ALIGN(4);
 45    _etext = .;                 /* 定义 .text 段结束位置的全局符号 */
 46  } >FLASH                      /* 输出到 FLASH */
 47
 48  /* 创建一个 .rodata 段 */
 49  .rodata :
 50  {
 51    . = ALIGN(4);
 52    *(.rodata)
 53    *(.rodata*)
 54    . = ALIGN(4);
 55  } >FLASH                      /* 输出到 FLASH */
 56
 57  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
 58  .ARM : {
 59    __exidx_start = .;
 60    *(.ARM.exidx*)
 61    __exidx_end = .;
 62  } >FLASH
 63
 64  .preinit_array     :
 65  {
 66    PROVIDE_HIDDEN (__preinit_array_start = .);
 67    KEEP (*(.preinit_array*))
 68    PROVIDE_HIDDEN (__preinit_array_end = .);
 69  } >FLASH
 70  .init_array :
 71  {
 72    PROVIDE_HIDDEN (__init_array_start = .);
 73    KEEP (*(SORT(.init_array.*)))
 74    KEEP (*(.init_array*))
 75    PROVIDE_HIDDEN (__init_array_end = .);
 76  } >FLASH
 77  .fini_array :
 78  {
 79    PROVIDE_HIDDEN (__fini_array_start = .);
 80    KEEP (*(SORT(.fini_array.*)))
 81    KEEP (*(.fini_array*))
 82    PROVIDE_HIDDEN (__fini_array_end = .);
 83  } >FLASH
 84
 85  _sidata = LOADADDR(.data);    /* .data 段在 FLASH 中的起始地址 */
 86
 87  /* 创建一个 .data 段 */
 88  .data : 
 89  {
 90    . = ALIGN(4);
 91    _sdata = .;                 /* .data 段在 RAM 中的起始地址 */
 92    *(.data)
 93    *(.data*)
 94
 95    . = ALIGN(4);
 96    _edata = .;                 /* .data 段在 RAM 中的结束地址 */
 97  } >RAM AT> FLASH              /* VMA 在 RAM 区,LMA 在 FLASH 区 */
 98
 99  
100  . = ALIGN(4);
101
102  /* 创建一个 .bss 段 */
103  .bss :
104  {
105    _sbss = .;                  /* .bss 在 RAM 中的起始地址 */
106    __bss_start__ = _sbss;
107    *(.bss)
108    *(.bss*)
109    *(COMMON)
110
111    . = ALIGN(4);
112    _ebss = .;                  /* .bss 在 RAM 中的结束地址 */
113    __bss_end__ = _ebss;
114  } >RAM                        /* 输出到 RAM */
115
116
117  /* 用户堆栈段,用于检查剩余 RAM 是否足够 */
118  ._user_heap_stack :
119  {
120    . = ALIGN(8);
121    PROVIDE ( end = . );
122    PROVIDE ( _end = . );
123    . = . + _Min_Heap_Size;
124    . = . + _Min_Stack_Size;
125    . = ALIGN(8);
126  } >RAM
127
128  /* 丢弃标准库中的某些信息(避免链接不需要的库内容) */
129  /DISCARD/ :
130  {
131    libc.a ( * )                /* 丢弃 libc 库所有内容 */
132    libm.a ( * )                /* 丢弃 libm 库所有内容 */
133    libgcc.a ( * )              /* 丢弃 libgcc 库所有内容 */
134  }
135
136  /* ARM 属性段(通常为空,但保留结构) */
137  .ARM.attributes 0 : { *(.ARM.attributes) }
138}
未初始化的全局变量
未初始化的全局变量
0x0800 0000
0x0800 0000
向量表
向量表
代码
代码
.isr_vector
.isr_vector
.text
.text
常量
常量
已初始化的全局变量
已初始化的全局变量
.rodata
.rodata
.data
.data
.data
.data
_sidata
_sidata
_estack
_estack
已初始化的全局变量
已初始化的全局变量
.bss
.bss
_sdata
_sdata
_edata
_edata
_sbss
_sbss
_ebss
_ebss
ALIGN(4)
ALIGN(4)
0x2000 0000
0x2000 0000
0x2001 0000
0x2001 0000

CM3 为满减栈,压栈时:先移动指针再压入数据。

STM32F1 启动流程 #

上电后, CPU 固定0x00000000 读取初始栈顶地址到 SP ,从 0x00000004 读取入口程序地址到 PC 。 STM32 可通过配置 BOOT0BOOT1 引脚,将从 0x00000000 地址开始的一块区域(别名区)映射到不同存储器的地址空间,以实现从不同存储器启动。

BOOT0BOOT1启动模式
0X从 FLASH 启动
10从系统存储器启动(ISP 编程)
11从 SRAM 启动

从 FLASH 启动 #

从 FLASH 启动时,地址 0x00000000 被映射到 0x08000000 , CPU 就能从 0x00000000 访问 FLASH 中的向量表从而运行程序。

假设初始栈顶地址为 0x20010000(64K) ,入口函数地址为 0x08000400 ,启动流程如下:

0x0000 0000
0x0000 0000
向量表
向量表
0x2001 0000
0x2001 0000
0x0800 0401
0x0800 0401
NMI_Handler 地址
NMI_Handler 地址
0x0800 0000
0x0800 0000
Reset_Handler 代码
Reset_Handler 代码
0x0800 0401
0x0800 0401
代码
代码
0x2001 0000
0x2001 0000
0x2001 0000
0x2001 0000
0x0800 0401
0x0800 0401
① 地址映射
① 地址映射
PC
PC
SP
SP
② 读取栈顶地址
② 读取栈顶地址
③ 读取入口程序地址,并从此处开始执行
③ 读取入口程序地址,并从此处开始执行

入口函数地址 0x08000401 最后一位是 1 表示 thumb 状态,实际地址为 0x08000400

从系统存储器启动 #

从 System Memory 启动时,地址 0x00000000 被映射到 0x1FFF0000 ,此区域存储的是厂商内置的 BootLoader 程序(闭源), 主要功能是从串口下载用户程序到 Flash (ISP 编程)。

从 SRAM 启动 #

从 SRAM 启动时,理论上应该将地址 0x00000000 映射到 0x20000000 ,但对于 STM32F1 系列实际情况并非如此。

对于 STM32F103ZET6 , 从 SRAM 启动时,0x00000000 会被映射到一块内存极小的区域,大约在 0x1FFFF000 附近或略低,仅 16 字节,内容如下:

20005000 200001E1 20000004 20000004

第一个字:初始栈顶地址 0x20005000 (20K)。

第二个字:入口程序地址 0x200001E1 ,最后一位表示 thumb ,实际是 0x200001E0,相对 0x20000000 偏移 0x1E0 。 对于不同容量的产品,其偏移值也有所不同,参考 GCC 的启动文件:

startup_stm32f10x_ld.s:     .word  BootRAM    /*  0x108   */
startup_stm32f10x_md.s:     .word  BootRAM    /*  0x108   */
startup_stm32f10x_hd.s:     .word  BootRAM    /*  0x1E0   */
startup_stm32f10x_xl.s:     .word  BootRAM    /*  0x1E0   */
startup_stm32f10x_cl.s:     .word  BootRAM    /*  0x1E0   */
startup_stm32f10x_ld_vl.s:  .word  BootRAM    /*  0x01CC  */
startup_stm32f10x_md_vl.s:  .word  BootRAM    /*  0x01CC  */
startup_stm32f10x_hd_vl.s:  .word  BootRAM    /*  0x1E0   */

第三和第四个字分别是 NMI 和 HardFault 向量。它们的最低位为 0 (CM3 不支持 ARM 状态),因此当 VTOR 仍为零时,若发生这些异常中的任何一个,处理器将触发双重异常。

根据 GCC 启动文件GCC 链接脚本 ,地址 0x200001E0 位置是向量表中 BootRAM 所在,且 BootRAM = 0xF1E0F85F0xF1E0F85F 这个值实际是汇编指令 LDR.W PC, [PC, #-0x1E0] 的机器码,作用是 PC = *(PC - 0x1E0) ,指令执行后的 PC 指向真正的入口程序地址, 详情参考 这篇帖子

0x0000 0000
0x0000 0000
0x2000 5000
0x2000 5000
0x2000 01E1
0x2000 01E1
0x2000 0004
0x2000 0004
0x???? ????
0x???? ????
0x2000 01E1
0x2000 01E1
0x2000 5000
0x2000 5000
0x2000 5000
0x2000 5000
0x2000 01E1
0x2000 01E1
① 地址映射
① 地址映射
PC
PC
SP
SP
② 读取栈顶地址
② 读取栈顶地址
③ 读取入口程序地址,并从此处开始执行
③ 读取入口程序地址,并从此处开始执行
0x2000 0004
0x2000 0004
④ 指令执行时,PC 指向此处
④ 指令执行时,PC 指向此处
_estack
_estack
Reset_Handler
Reset_Handler
NMI_Handler
NMI_Handler
HardFault_Handler
HardFault_Handler
0x2000 0000
0x2000 0000
向量表
向量表
SRAM
SRAM
0x2001 0000
0x2001 0000
0x1FFF F000
0x1FFF F000
BootRAM
BootRAM
0x2000 01E5
0x2000 01E5
PC
PC
Reset_Handler 代码
Reset_Handler 代码
代码
代码
⑥ 指令执行后,PC 指向此处
⑥ 指令执行后,PC 指向此处
Reset_Handler
Reset_Handler
PC
PC
⑤ 读取(PC-0x1E0)上存储的真正入口地址
⑤ 读取(PC-0x1E0)上存储的真正入口地址
ALIGN(4)
ALIGN(4)
.rodata
.rodata
.data
.data
.bss
.bss
.data
.data
程序中 RAM 起始地址
程序中 RAM 起始地址
程序 RAM
程序 RAM
程序 FLASH
程序 FLASH

正常从 SRAM 启动,应该需要以下设置(未验证):

  1. 配置 BOOT0 、BOOT1 引脚均为高电平。
  2. 设置链接脚本中的 RAM 区起始地址,与 RAM 区大小。
  3. 设置链接脚本中的 FLASH 区的起始地址为 0x20000000,与 FLASH 区大小。
  4. 从上图的流程中可以看出,用户向量表中的 _estack 栈初始地址没有起到作用,初始栈顶被强制设置为 0x20005000 , 所以用户需要在 main 函数调用前设置 SP ,可以使用 core_cm3.c 中的 __set_MSP 函数。
  5. 设置向量表偏移寄存器 SCB->VTOR 的值,可使用 system_stm32f10x.c 中的 VECT_TAB_SRAM 宏,如下:
文件Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
// 如果需要将向量表重定位到内部SRAM中,请取消注释以下行
// #define VECT_TAB_SRAM                     // 定义向量表在SRAM中
#define VECT_TAB_OFFSET  0x0                 // 向量表基址偏移量字段,此值必须是0x200的倍数

void SystemInit (void) {

省略...

#ifdef VECT_TAB_SRAM
    // SRAM_BASE 在 stm32f10x.h 中定义 0x20000000
    SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  // 向量表重定位到内部 SRAM 中
#else
    SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // 向量表重定位到内部 FLASH 中
#endif 
}

对于这种奇怪的启动方式,似乎主要局限于 F103/5/7 系列,较新的芯片应该是正常的,还是参考 这篇帖子

另外,我在野火 STM32 文档中也找到了印证,参考 在SRAM中调试代码 一文。 在此文中,单片机复位后 PC 和 SP 指针初始值异常(如下图),恰好印证了上述的启动流程。

除此之外,野火 STM32 文档中使用的 IDE 是 Keil ,默认是 ARMCC 编译器,该编译器的启动文件中并没有定义 BootRAM , 这也是他们 SRAM 调试失败的原因之一。