Skip to content

Commit 9013910

Browse files
feat: pure C/C++ coding envs for STM32F103C8T6
1 parent e4385da commit 9013910

14 files changed

Lines changed: 2072 additions & 0 deletions

File tree

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "third_party/STM32F1"]
2+
path = third_party/STM32F1
3+
url = https://github.com/STMicroelectronics/STM32CubeF1.git
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build/
2+
.cache/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "STM32 Debug",
6+
"type": "cortex-debug",
7+
"request": "launch",
8+
"servertype": "openocd",
9+
"cwd": "${workspaceRoot}",
10+
"executable": "build/stm32_demo.elf",
11+
"configFiles": [
12+
"interface/stlink.cfg",
13+
"target/stm32f1x.cfg"
14+
],
15+
"runToEntryPoint": "main",
16+
"svdFile": ""
17+
}
18+
]
19+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
cmake_minimum_required(VERSION 3.22)
2+
3+
# ── 工具链(必须在 project() 之前)──────────────────────────────────────────
4+
set(CMAKE_SYSTEM_NAME Generic)
5+
set(CMAKE_SYSTEM_PROCESSOR ARM)
6+
7+
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
8+
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
9+
set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
10+
set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
11+
set(CMAKE_SIZE arm-none-eabi-size)
12+
13+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
14+
# 避免 CMake 做链接测试时报错
15+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
16+
17+
# ── 项目定义 ────────────────────────────────────────────────────────────────
18+
project(stm32_demo C CXX ASM)
19+
set(CMAKE_C_STANDARD 11)
20+
set(CMAKE_CXX_STANDARD 17)
21+
22+
# ── HAL / CMSIS 路径 ────────────────────────────────────────────────────────
23+
set(STM32F1_ROOT ${CMAKE_SOURCE_DIR}/../../../third_party/STM32F1/Drivers)
24+
set(CMSIS_TMPL ${STM32F1_ROOT}/CMSIS/Device/ST/STM32F1xx/Source/Templates)
25+
26+
# ── 源文件 ──────────────────────────────────────────────────────────────────
27+
file(GLOB HAL_SRC
28+
${STM32F1_ROOT}/STM32F1xx_HAL_Driver/Src/*.c
29+
)
30+
31+
list(FILTER HAL_SRC EXCLUDE REGEX ".*_template\\.c$")
32+
33+
add_compile_options(
34+
-mcpu=cortex-m3
35+
-mthumb
36+
-O2
37+
-Wall
38+
-Wextra
39+
-Wno-missing-field-initializers
40+
-ffunction-sections
41+
-fdata-sections
42+
-DUSE_HAL_DRIVER
43+
-DSTM32F103xB
44+
)
45+
46+
add_compile_options(
47+
$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
48+
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
49+
)
50+
51+
# ── 可执行目标 ───────────────────────────────────────────────────────────────
52+
add_executable(${PROJECT_NAME}.elf
53+
main.c
54+
syscall.c
55+
${CMSIS_TMPL}/system_stm32f1xx.c
56+
${CMSIS_TMPL}/gcc/startup_stm32f103xb.s
57+
${HAL_SRC}
58+
)
59+
60+
# ── 头文件路径 ───────────────────────────────────────────────────────────────
61+
target_include_directories(${PROJECT_NAME}.elf PRIVATE
62+
${CMAKE_SOURCE_DIR} # stm32f1xx_hal_conf.h
63+
${STM32F1_ROOT}/CMSIS/Include
64+
${STM32F1_ROOT}/CMSIS/Device/ST/STM32F1xx/Include
65+
${STM32F1_ROOT}/STM32F1xx_HAL_Driver/Inc
66+
)
67+
68+
# ── 链接选项 ─────────────────────────────────────────────────────────────────
69+
target_link_options(${PROJECT_NAME}.elf PRIVATE
70+
-mcpu=cortex-m3
71+
-mthumb
72+
-T${CMAKE_SOURCE_DIR}/STM32F103C8TX_FLASH.ld
73+
-nostartfiles
74+
-specs=nano.specs
75+
-specs=nosys.specs
76+
-Wl,--gc-sections
77+
-Wl,-Map=${PROJECT_NAME}.map
78+
)
79+
80+
# ── 构建后处理:生成 .bin 并打印 size ────────────────────────────────────────
81+
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
82+
COMMAND ${CMAKE_OBJCOPY}
83+
-O binary
84+
$<TARGET_FILE:${PROJECT_NAME}.elf>
85+
${PROJECT_NAME}.bin
86+
COMMAND ${CMAKE_SIZE}
87+
--format=berkeley
88+
$<TARGET_FILE:${PROJECT_NAME}.elf>
89+
COMMENT "Generating ${PROJECT_NAME}.bin"
90+
)
91+
92+
# ── 烧录目标:make flash ─────────────────────────────────────────────────────
93+
add_custom_target(flash
94+
COMMAND openocd
95+
-f interface/stlink.cfg
96+
-f target/stm32f1x.cfg
97+
-c "program ${PROJECT_NAME}.bin verify reset exit 0x08000000"
98+
DEPENDS ${PROJECT_NAME}.elf
99+
COMMENT "Flashing ${PROJECT_NAME}.bin via OpenOCD"
100+
)
101+
102+
# ── 擦除目标:make erase ─────────────────────────────────────────────────────
103+
add_custom_target(erase
104+
COMMAND openocd
105+
-f interface/stlink.cfg
106+
-f target/stm32f1x.cfg
107+
-c "init; halt; stm32f1x mass_erase 0; exit"
108+
COMMENT "Erasing STM32 Flash"
109+
)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/* STM32F103C8T6 链接脚本
2+
* Flash : 64KB @ 0x08000000
3+
* SRAM : 20KB @ 0x20000000
4+
*/
5+
6+
ENTRY(Reset_Handler)
7+
8+
_estack = ORIGIN(RAM) + LENGTH(RAM); /* 栈顶 = SRAM 末尾 */
9+
10+
MEMORY
11+
{
12+
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
13+
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
14+
}
15+
16+
SECTIONS
17+
{
18+
/* ── 中断向量表,必须放最前面 ── */
19+
.isr_vector :
20+
{
21+
KEEP(*(.isr_vector))
22+
} >FLASH
23+
24+
/* ── 代码 + 只读数据 ── */
25+
.text :
26+
{
27+
*(.text*)
28+
*(.rodata*)
29+
_etext = .;
30+
} >FLASH
31+
32+
/* ── 初始化数组(C++ 全局对象构造,C 也保留以防万一)── */
33+
.preinit_array :
34+
{
35+
PROVIDE_HIDDEN(__preinit_array_start = .);
36+
KEEP(*(.preinit_array*))
37+
PROVIDE_HIDDEN(__preinit_array_end = .);
38+
} >FLASH
39+
40+
.init_array :
41+
{
42+
PROVIDE_HIDDEN(__init_array_start = .);
43+
KEEP(*(SORT(.init_array.*)))
44+
KEEP(*(.init_array*))
45+
PROVIDE_HIDDEN(__init_array_end = .);
46+
} >FLASH
47+
48+
.fini_array :
49+
{
50+
PROVIDE_HIDDEN(__fini_array_start = .);
51+
KEEP(*(.fini_array*))
52+
PROVIDE_HIDDEN(__fini_array_end = .);
53+
} >FLASH
54+
55+
/* ── 初始化数据:Flash 存储,运行时复制到 SRAM ── */
56+
_sidata = LOADADDR(.data);
57+
.data :
58+
{
59+
_sdata = .;
60+
*(.data*)
61+
_edata = .;
62+
} >RAM AT >FLASH
63+
64+
/* ── 未初始化数据:SRAM,启动文件负责清零 ── */
65+
.bss :
66+
{
67+
_sbss = .;
68+
*(.bss*)
69+
*(COMMON)
70+
_ebss = .;
71+
} >RAM
72+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include "stm32f1xx_hal.h"
2+
3+
/* ────────────────────────────────────────────────────────────
4+
* Blue Pill 板载 LED
5+
* - 接在 PC13
6+
* - 低电平点亮,高电平熄灭
7+
* ──────────────────────────────────────────────────────────── */
8+
#define LED_PORT GPIOC
9+
#define LED_PIN GPIO_PIN_13
10+
11+
/* ── 函数声明 ─────────────────────────────────────────────── */
12+
static void SystemClock_Config(void);
13+
static void GPIO_Init(void);
14+
15+
/* ── main ────────────────────────────────────────────────── */
16+
int main(void) {
17+
HAL_Init(); /* 初始化 HAL,配置 SysTick 为 1ms 中断 */
18+
SystemClock_Config(); /* 配置系统时钟 */
19+
GPIO_Init(); /* 配置 LED 引脚 */
20+
21+
while (1) {
22+
HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
23+
HAL_Delay(500); /* 500ms,依赖 SysTick */
24+
}
25+
}
26+
27+
/* ── 时钟配置:HSI → PLL → 64MHz ────────────────────────────
28+
*
29+
* HSI = 8MHz
30+
* PLLSRC = HSI / 2 = 4MHz
31+
* PLLMUL = x16 → SYSCLK = 64MHz (HSI 来源最高只能到 64MHz)
32+
*
33+
* APB1 (低速总线) 最高 36MHz → 2 分频 = 32MHz
34+
* APB2 (高速总线) 1 分频 = 64MHz
35+
* ──────────────────────────────────────────────────────────── */
36+
static void SystemClock_Config(void) {
37+
RCC_OscInitTypeDef osc = {0};
38+
osc.OscillatorType = RCC_OSCILLATORTYPE_HSI;
39+
osc.HSIState = RCC_HSI_ON;
40+
osc.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
41+
osc.PLL.PLLState = RCC_PLL_ON;
42+
osc.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; /* 4MHz */
43+
osc.PLL.PLLMUL = RCC_PLL_MUL16; /* 64MHz */
44+
HAL_RCC_OscConfig(&osc);
45+
46+
RCC_ClkInitTypeDef clk = {0};
47+
clk.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
48+
RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
49+
clk.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
50+
clk.AHBCLKDivider = RCC_SYSCLK_DIV1; /* HCLK = 64MHz */
51+
clk.APB1CLKDivider = RCC_HCLK_DIV2; /* APB1 = 32MHz */
52+
clk.APB2CLKDivider = RCC_HCLK_DIV1; /* APB2 = 64MHz */
53+
HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_2);
54+
}
55+
56+
/* ── GPIO 初始化 ─────────────────────────────────────────── */
57+
static void GPIO_Init(void) {
58+
__HAL_RCC_GPIOC_CLK_ENABLE(); /* 使能 GPIOC 时钟,必须先做 */
59+
60+
GPIO_InitTypeDef cfg = {0};
61+
cfg.Pin = LED_PIN;
62+
cfg.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
63+
cfg.Speed = GPIO_SPEED_FREQ_LOW; /* LED 不需要高速 */
64+
HAL_GPIO_Init(LED_PORT, &cfg);
65+
66+
/* 初始状态:高电平(LED 灭)*/
67+
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
68+
}
69+
70+
/* ── SysTick 中断处理(HAL_Delay 依赖此函数)────────────── */
71+
void SysTick_Handler(void) { HAL_IncTick(); }

0 commit comments

Comments
 (0)