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,
824                ↓
825| bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
826                                ↑
827	                   __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

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

  • NVIC,SCB,SysTick,ITM,MPU,CoreDebug 等寄存器内存映射。
  • 优先级分组,中断优先级设置函数,SysTick 配置函数等。
  • 内核访问函数。

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.h 、system_stm32f10x.h 或 stm32f10x_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                   : 定义向量表在 SRAM 中
VECT_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 可通过配置 BOOT0 和 BOOT1 引脚,将从 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 = 0xF1E0F85F , 0xF1E0F85F 这个值实际是汇编指令 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 调试失败的原因之一。