
书: https://pan.baidu.com/s/1A6ZLSPMbCiZ-L4eRucUvXQ?pwd=kt7i
一些笔记分享给大家:
一、嵌入式C语言特性
- “
volatile
关键字是嵌入式编程的护身符——告诉编译器‘此变量可能被硬件异步修改’,禁止优化(如while(REG)
循环不被删除)。” - “位操作比乘除更高效:
PORT |= (1<<3)
置位第3位,PORT &= ~(1<<3)
清零第3位。”
二、编译器与底层优化
- “
register
建议编译器将变量放入寄存器,但现代优化器已能自动处理,仅适用于极端性能场景。” - **“内联汇编语法:casm volatile(“mov r0, %0” : : “r”(value)); // ARM架构示例
volatile
阻止编译器重排,"r"
约束表示使用通用寄存器。”**
三、内存管理
- “栈溢出是嵌入式系统最常见崩溃原因——静态分配(如
static uint8_t buffer[1024]
)比动态内存更安全。” - **“链接脚本(.ld文件)控制内存布局:textMEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K }定义Flash起始地址和大小。”**
四、硬件交互
- **“寄存器映射的两种方式:
- 指针强制转换:
*(volatile uint32_t*)0x40021000 = 0x01;
- 结构体封装:ctypedef struct { uint32_t CR; uint32_t DR; } UART_TypeDef; #define UART1 ((UART_TypeDef*)0x40011000) “`”**
- 指针强制转换:
五、中断与异常
- **“中断服务函数(ISR)需短小精悍:
- 避免阻塞操作(如
printf
); - 使用
volatile
共享变量与主程序通信。”**
- 避免阻塞操作(如
- “
__attribute__((interrupt("IRQ")))
指定ARM中断函数,编译器自动保存/恢复现场。”
六、RTOS适配
- **“任务栈大小估算:
- 基础开销(上下文保存) + 局部变量 + 函数调用深度 × 栈帧大小。”**
- “避免在任务中忙等待:用RTOS提供的信号量/消息队列替代
while(!flag)
。”
七、调试与性能
- **“利用
__FILE__
和__LINE__
宏定位崩溃点:c#define ASSERT(x) if(!(x)) { log_error(“%s:%d”, __FILE__, __LINE__); } “`”** - “GCC的
-O2
优化可能改变代码行为:调试阶段建议用-O0
保留符号信息。”
八、跨平台兼容
- **“数据类型陷阱:
int
长度依赖编译器(ARM通常32位);- 优先使用
stdint.h
的uint8_t
/int32_t
等明确类型。”**
九、低功耗设计
- **“休眠模式下的外设管理:
- 关闭时钟(
RCC->APB1ENR &= ~RCC_APB1ENR_TIM2EN
); - 配置IO口为模拟输入减少漏电。”**
- 关闭时钟(
十、代码规范
- **“防御性编程范例:cvoid write_flash(uint32_t addr, uint8_t* data, uint32_t len) { if(addr < FLASH_START || addr + len > FLASH_END) return; // 实际写入操作 } “`”**