Skip to content

Commit 3bc13ce

Browse files
Merge pull request #8 from Awesome-Embedded-Learning-Studio/feat/uart_example
update embeded example with UART
2 parents 5bcaeda + e7924ec commit 3bc13ce

41 files changed

Lines changed: 4321 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
---
2+
# .clang-format 配置文件
3+
# 用于 clangd 格式化和代码检查
4+
# 生成日期: 2026-02-15
5+
6+
# 基础风格: LLVM (简洁现代)
7+
BasedOnStyle: LLVM
8+
9+
# 缩进设置
10+
IndentWidth: 4
11+
UseTab: Never
12+
ColumnLimit: 100
13+
14+
# 大括号风格: 附加式 { 在语句末尾
15+
BreakBeforeBraces: Attach
16+
17+
# 指针/引用星号位置: 左侧 (int* a)
18+
PointerAlignment: Left
19+
DerivePointerAlignment: false
20+
21+
# 命名风格 (仅供参考,不影响已有代码)
22+
# 可以让 clangd 警告不符合命名规范的代码
23+
# 需要配合 clang-tidy 使用
24+
25+
# 函数声明: 返回类型和函数名在同一行
26+
AlwaysBreakAfterReturnType: None
27+
AlwaysBreakTemplateDeclarations: No
28+
29+
# 结构体初始化: 按位置赋值
30+
# C++11UnifiedBraceList: false 使用传统风格
31+
32+
# 预处理器缩进: 与代码对齐
33+
IndentPPDirectives: AfterHash
34+
35+
# 其他实用设置
36+
37+
# 在二元运算符后换行
38+
BreakBeforeBinaryOperators: None
39+
40+
# 在三元运算符后换行
41+
BreakBeforeTernaryOperators: true
42+
43+
# 连续赋值时的对齐
44+
AlignConsecutiveAssignments: false
45+
AlignConsecutiveDeclarations: false
46+
47+
# 转换类型周围的空格
48+
SpaceAfterCStyleCast: false
49+
50+
# 逻辑运算符周围的空格
51+
SpaceAfterLogicalNot: false
52+
53+
# 模板列表中的空格
54+
SpaceAfterTemplateKeyword: true
55+
56+
# 控制语句括号内的空格: if (x) 而非 if (x )
57+
SpaceBeforeParens: ControlStatements
58+
SpaceInEmptyParentheses: false
59+
60+
# 圆括号内的空格
61+
SpacesInParentheses: false
62+
SpacesInSquareBrackets: false
63+
64+
# 容器类型周围的空格
65+
SpacesInContainerLiterals: false
66+
67+
# lambda 相关
68+
SpaceBeforeAssignmentOperators: true
69+
SpaceBeforeCpp11BracedList: false
70+
71+
# 对齐
72+
AlignAfterOpenBracket: Align
73+
AlignEscapedNewlines: Left
74+
AlignOperands: true
75+
AlignTrailingComments: true
76+
77+
# 允许函数参数在同一行
78+
AllowAllArgumentsOnNextLine: true
79+
AllowAllConstructorInitializersOnNextLine: true
80+
AllowAllParametersOfDeclarationOnNextLine: true
81+
82+
# 允许短函数在一行
83+
AllowShortBlocksOnASingleLine: Never
84+
AllowShortCaseLabelsOnASingleLine: false
85+
AllowShortFunctionsOnASingleLine: Inline
86+
AllowShortIfStatementsOnASingleLine: Never
87+
AllowShortLoopsOnASingleLine: false
88+
89+
# 自动对齐注释
90+
ReflowComments: true
91+
92+
# 最大连续空行数
93+
MaxEmptyLinesToKeep: 1
94+
95+
# 命名空间缩进
96+
NamespaceIndentation: None
97+
98+
# 访问修饰符缩进
99+
IndentAccessModifiers: false
100+
IndentCaseLabels: true
101+
102+
# 换行符设置
103+
LineEnding: LF
104+
105+
# C/C++ 语言设置
106+
Language: Cpp
107+
Standard: c++17
108+
109+
# 包含块排序
110+
SortIncludes: true
111+
IncludeBlocks: Preserve
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/uart_logger.elf",
11+
"configFiles": [
12+
"interface/stlink.cfg",
13+
"target/stm32f1x.cfg"
14+
],
15+
"runToEntryPoint": "main",
16+
"svdFile": ""
17+
}
18+
]
19+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"clangd.arguments": [
3+
"--query-driver=/usr/sbin/arm-none-eabi-g++,/usr/sbin/arm-none-eabi-gcc"
4+
]
5+
}
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(uart_logger C CXX ASM)
19+
set(CMAKE_C_STANDARD 23)
20+
set(CMAKE_CXX_STANDARD 23)
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_subdirectory(system)
53+
54+
# ── 可执行目标 ───────────────────────────────────────────────────────────────
55+
add_executable(${PROJECT_NAME}.elf
56+
main.cpp
57+
${CMSIS_TMPL}/system_stm32f1xx.c
58+
${CMSIS_TMPL}/gcc/startup_stm32f103xb.s
59+
${HAL_SRC}
60+
)
61+
62+
target_link_libraries(${PROJECT_NAME}.elf PRIVATE
63+
-Wl,--whole-archive
64+
system
65+
-Wl,--no-whole-archive
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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
3+
#include <array>
4+
#include <cstddef>
5+
6+
namespace base {
7+
8+
/// Lock-free single-producer single-consumer circular buffer.
9+
/// Designed for ISR-to-main communication: push() in ISR, pop() in main loop.
10+
/// N must be a power of 2 for bitmask-based index wrapping (zero modulo overhead).
11+
template <size_t N>
12+
class CircularBuffer {
13+
static_assert(N > 0 && (N & (N - 1)) == 0, "N must be a power of 2");
14+
15+
public:
16+
bool push(std::byte b) noexcept {
17+
if (full()) {
18+
return false;
19+
}
20+
buf_[mask(head_)] = b;
21+
head_ = next(head_);
22+
return true;
23+
}
24+
25+
bool pop(std::byte& out) noexcept {
26+
if (empty()) {
27+
return false;
28+
}
29+
out = buf_[mask(tail_)];
30+
tail_ = next(tail_);
31+
return true;
32+
}
33+
34+
bool empty() const noexcept { return head_ == tail_; }
35+
bool full() const noexcept { return next(head_) == tail_; }
36+
size_t size() const noexcept {
37+
return head_ >= tail_ ? head_ - tail_ : N - tail_ + head_;
38+
}
39+
40+
private:
41+
static constexpr size_t mask(size_t v) noexcept { return v & (N - 1); }
42+
static constexpr size_t next(size_t v) noexcept { return (v + 1) & (2 * N - 1); }
43+
44+
std::array<std::byte, N> buf_{};
45+
// Volatile: head written by ISR, tail read by ISR; tail written by main, head read by main.
46+
volatile size_t head_ = 0;
47+
volatile size_t tail_ = 0;
48+
};
49+
50+
} // namespace base
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
namespace base {
4+
template <typename SingletonClass> class SimpleSingleton {
5+
public:
6+
SimpleSingleton() = default;
7+
~SimpleSingleton() = default;
8+
9+
static SingletonClass& instance() {
10+
static SingletonClass _instance;
11+
return _instance;
12+
}
13+
14+
private:
15+
/* Never Shell A Single Instance Copyable And Movable */
16+
SimpleSingleton(const SimpleSingleton&) = delete;
17+
SimpleSingleton(SimpleSingleton&&) = delete;
18+
SimpleSingleton& operator=(const SimpleSingleton&) = delete;
19+
SimpleSingleton& operator=(SimpleSingleton&&) = delete;
20+
};
21+
} // namespace base

0 commit comments

Comments
 (0)