97_Keile 嵌入式开发勘误笔记

嵌入式开发勘误笔记

问题编号:ERR-001

问题描述

在使用 Keil ARM Compiler V6(版本 V6.13.1)编译 N32H482 项目时,出现以下错误:

复制代码
../app/iap/iap.c(34): error: unknown type name '路'
路              #define SET_MSP(dwValue)        __ASM volatile ("msr msp, "#dwValue)
../app/iap/iap.c(34): error: expected identifier or '('
../app/iap/iap.c(66): warning: implicit declaration of function 'SET_MSP'
../app/iap/iap.c(67): error: use of undeclared identifier 'pfTarget'

根本原因

  1. 编码问题 :源文件(iap.c)中存在不可见的特殊字符或 BOM(Byte Order Mark),导致编译器解析错误。
  2. 宏定义重复/冲突
    • 存在一个空的 #define SET_MSP(dwValue) 定义
    • 紧接着又有一个带特殊字符前缀的 #define SET_MSP(dwValue) 定义
    • 编译器将特殊字符(显示为"路")误识别为类型名
  3. 编译器版本差异:AC5 和 AC6 的内联汇编语法不同,宏定义未正确适配。

解决方案

方案一:清理宏定义并适配 AC6(推荐)

将宏定义区域修改为:

c 复制代码
// AC5 (ARM Compiler V5) 语法:
// #define SET_MSP(dwValue)  __ASM volatile ("msr msp, "#dwValue)

// AC6 (ARM Compiler V6) 语法(当前使用 V6.13.1):
#define SET_MSP(dwValue)  __asm volatile ("msr msp, %0" : : "r" (dwValue))

void (*pfTarget)(void);
方案二:统一文件编码
  1. 用 Notepad++ 或 VS Code 打开 iap.c
  2. 将编码转换为 UTF-8 without BOM
  3. 或转为 ANSI/GB2312 编码
  4. 删除所有乱码字符,重新输入代码
方案三:Keil 工程设置

Project → Options for Target → C/C++ → Misc Controls 中添加:

复制代码
-finput-charset=UTF-8 -fexec-charset=GBK

关键知识点

编译器 内联汇编语法 SET_MSP 写法
AC5 (V5.x) __ASM volatile ("指令") __ASM volatile ("msr msp, "#dwValue)
AC6 (V6.x) __asm volatile ("指令" : 输出 : 输入) __asm volatile ("msr msp, %0" : : "r" (dwValue))

预防措施

  1. 统一编码规范:工程中所有源文件统一使用 UTF-8 without BOM 或 GB2312 编码
  2. Keil 编辑器设置:Edit → Configuration → Editor → Encoding 设为与工程一致
  3. 避免复制粘贴:从网页/文档复制代码时,注意可能带入不可见字符
  4. 编译器版本适配:使用条件编译区分 AC5/AC6:
c 复制代码
#if defined(__CC_ARM)      // AC5
    #define SET_MSP(dwValue)  __ASM volatile ("msr msp, "#dwValue)
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6000000)  // AC6
    #define SET_MSP(dwValue)  __asm volatile ("msr msp, %0" : : "r" (dwValue))
#endif

问题编号:ERR-002

问题描述

编译 adc_spi.c 时出现警告:

复制代码
warning: implicitly declaring library function 'memset'
warning: implicitly declaring library function 'memcpy'

根本原因

使用了 C 标准库函数 memsetmemcpy,但未包含对应的头文件 <string.h>

解决方案

在文件开头添加:

c 复制代码
#include <string.h>

预防措施

  • 使用任何标准库函数前,确保包含对应的头文件
  • Keil 中可勾选 C/C++ → Warnings → All Warnings 提前发现此类问题

快速检查清单

编译错误时依次检查:

  • 文件编码是否为 UTF-8 without BOM 或 GB2312
  • 是否存在不可见的特殊字符(复制粘贴带入)
  • 宏定义是否重复或冲突
  • 编译器版本(AC5/AC6)适配是否正确
  • 是否缺少必要的头文件包含

记录时间:2026-06-17

适用环境:Keil MDK V5.x / ARM Compiler V6.13.1