Build started: Project: project *** Using Compiler 'V6.23', folder: 'D:\Keil_v5\ARM\ARMCLANG\Bin' Build target 'Target_1' Note: source file '.\Start\startup_stm32f10x_md.s' - object file renamed from '.\Objects\startup_stm32f10x_md.o' to '.\Objects\startup_stm32f10x_md_1.o'. Note: source file '.\Start\startup_stm32f10x_md.s' - object file renamed from '.\Objects\startup_stm32f10x_md.o' to '.\Objects\startup_stm32f10x_md_1.o'. Note: source file '.\Start\core_cm3.c' - object file renamed from '.\Objects\core_cm3.o' to '.\Objects\core_cm3_1.o'. Note: source file '.\Start\startup_stm32f10x_md.s' - object file renamed from '.\Objects\startup_stm32f10x_md.o' to '.\Objects\startup_stm32f10x_md_2.o'. Note: source file '.\Start\startup_stm32f10x_md.s' - object file renamed from '.\Objects\startup_stm32f10x_md.o' to '.\Objects\startup_stm32f10x_md_2.o'. Note: source file '.\Start\system_stm32f10x.c' - object file renamed from '.\Objects\system_stm32f10x.o' to '.\Objects\system_stm32f10x_1.o'. Start/core_cm3.c(445): error: non-ASM statement in naked function is not supported 445 | uint32_t result=0; | ^ Start/core_cm3.c(442): note: attribute is here 442 | uint32_t __get_PSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(465): error: parameter references not allowed in naked functions 465 | "BX lr \n\t" : : "r" (topOfProcStack) ); | ^ Start/core_cm3.c(461): note: attribute is here 461 | void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(479): error: non-ASM statement in naked function is not supported 479 | uint32_t result=0; | ^ Start/core_cm3.c(476): note: attribute is here 476 | uint32_t __get_MSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(499): error: parameter references not allowed in naked functions 499 | "BX lr \n\t" : : "r" (topOfMainStack) ); | ^ Start/core_cm3.c(495): note: attribute is here 495 | void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); | ^ 4 errors generated. compiling core_cm3.c... Start/core_cm3.c(445): error: non-ASM statement in naked function is not supported 445 | uint32_t result=0; | ^ Start/core_cm3.c(442): note: attribute is here 442 | uint32_t __get_PSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(465): error: parameter references not allowed in naked functions 465 | "BX lr \n\t" : : "r" (topOfProcStack) ); | ^ Start/core_cm3.c(461): note: attribute is here 461 | void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(479): error: non-ASM statement in naked function is not supported 479 | uint32_t result=0; | ^ Start/core_cm3.c(476): note: attribute is here 476 | uint32_t __get_MSP(void) __attribute__( ( naked ) ); | ^ Start/core_cm3.c(499): error: parameter references not allowed in naked functions 499 | "BX lr \n\t" : : "r" (topOfMainStack) ); | ^ Start/core_cm3.c(495): note: attribute is here 495 | void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); | ^ 4 errors generated. compiling core_cm3.c... compiling main.c...
时间: 2025-07-20 21:19:46 浏览: 5
<think>我们正在解决Keil编译过程中core_cm3.c文件出现的naked函数相关的编译错误。具体问题是使用Keil V6.23编译器时,在core_cm3.c文件中,naked函数内部出现了非汇编语句以及参数引用,导致编译错误。
根据ARM编译器的规范,`__naked`函数(也称为裸函数)必须满足以下要求:
1. 函数体内只能包含内联汇编语句(inline assembly)。
2. 不能有非汇编语句(如C语句)。
3. 不能引用参数(因为参数是通过寄存器传递的,而裸函数不会自动保存和恢复寄存器)。
4. 不能声明局部变量(因为编译器不会为裸函数生成栈帧管理代码)。
因此,在core_cm3.c文件中,如果naked函数内部包含了C语句或者引用了参数,就会导致编译错误。
### 解决方案
通常,core_cm3.c文件是CMSIS(Cortex Microcontroller Software Interface Standard)的一部分,由ARM提供。在Keil V6.23编译器中,对裸函数的检查更加严格,因此需要检查core_cm3.c文件中的裸函数实现是否符合上述规范。
我们可以采取以下步骤:
1. **检查core_cm3.c文件中的裸函数**:找到报错的函数,查看其实现。常见的裸函数包括中断服务例程(ISR)的封装,例如`PendSV_Handler`、`SysTick_Handler`等。
2. **修改裸函数**:确保函数体内只有内联汇编语句,并且不引用任何参数。如果函数需要访问参数,则必须通过汇编指令来访问,并且要手动处理寄存器的保存和恢复。
3. **使用正确的内联汇编语法**:Keil编译器使用`__asm`关键字来嵌入汇编代码。
### 示例修改
假设在core_cm3.c中有一个裸函数如下(这是示例,实际函数可能不同):
```c
__naked void SysTick_Handler(void)
{
/* 错误的:包含了C语句 */
SysTick_Count++;
__asm
{
BX LR
}
}
```
这个函数中包含了C语句`SysTick_Count++;`,这是不允许的。我们需要将其改为纯汇编,或者将C代码的操作移到非裸函数中。
但是,在中断服务例程中,我们通常需要保存和恢复上下文。因此,正确的做法是使用汇编来保存上下文,然后调用一个C函数,最后恢复上下文并返回。
修改后的示例:
```c
__naked void SysTick_Handler(void)
{
__asm
{
PUSH {R0, LR} // 保存寄存器
BL SysTick_Handler_C // 调用C函数
POP {R0, PC} // 恢复寄存器并返回
}
}
void SysTick_Handler_C(void)
{
SysTick_Count++;
}
```
然而,请注意,core_cm3.c中的函数通常是标准化的,我们不应该直接修改它,因为这会破坏标准库的兼容性。因此,更好的做法是:
1. **更新CMSIS库**:检查是否有新版本的CMSIS库,该库可能已经修复了此问题。
2. **使用Keil提供的补丁**:Keil可能会针对此编译器版本发布补丁。
3. **如果问题依旧,则考虑临时修改core_cm3.c**:在确认修改不会影响其他功能的情况下,可以按照上述方法修改裸函数。
### 具体步骤
1. 打开core_cm3.c文件,找到报错的裸函数。
2. 将函数体改为纯汇编,或者将非汇编代码移到一个新的C函数中,然后在裸函数中通过汇编调用该C函数。
3. 注意保存和恢复寄存器,确保不会破坏程序状态。
### 注意事项
- 修改标准库文件需要谨慎,因为可能会影响其他项目或导致后续升级问题。
- 建议在修改前备份原文件。
### 引用
根据ARM CMSIS文档,裸函数必须严格遵守上述规则[^1]。
§§相关问题§§
1. 如何更新Keil的CMSIS库?
2. 裸函数中如何正确使用内联汇编?
3. 除了修改core_cm3.c,还有没有其他方法解决这个编译错误?</think>### 解决Keil V6.23编译器在core_cm3.c中的naked函数错误
#### 问题分析
在Keil V6.23编译器中,`core_cm3.c`文件的`naked`函数报错通常由以下原因导致:
1. **非汇编语句存在**:`__naked`函数要求函数体必须**完全由汇编指令组成**,任何C代码语句(如变量声明、函数调用)都会触发错误[^1]。
2. **参数引用问题**:`naked`函数**不能直接访问参数**,因为编译器不会生成标准的函数序言/尾声代码来处理参数传递[^2]。
3. **编译器严格性升级**:V6.23版本加强了对`naked`函数的合规性检查,旧版本可能忽略的违规操作在新版本中会报错。
#### 解决方案
##### 方法1:修改core_cm3.c源码(推荐)
找到报错的`naked`函数(如`__get_PSP`、`__set_CONTROL`等),按规范重写:
```c
__naked uint32_t __get_PSP(void) {
__asm {
MRS R0, PSP // 所有操作通过寄存器完成
BX LR // 直接返回
}
}
// 错误示例(含C语句):
// uint32_t result;
// __asm { MRS result, PSP } // 非法!
// return result; // 非法!
```
##### 方法2:编译器选项降级(临时方案)
在Keil设置中暂时降低优化等级:
1. Project → Options for Target → C/C++选项卡
2. 将`Optimization`从`-O3`降为`-O1`
3. 勾选`No Auto Includes`避免隐式包含
##### 方法3:更新CMSIS库
1. 从[ARM官网](https://developer.arm.com/tools-and-software/embedded/cmsis)下载最新CMSIS
2. 替换项目中的`CoreSupport`和`DeviceSupport`文件夹
3. 重新编译验证
#### 关键编程规范
1. **寄存器操作**:所有数据必须通过寄存器(如`R0-R3`)传递,返回值存于`R0`。
2. **禁止C语句**:函数体内不能出现`if`、`return`等C语句。
3. **栈帧管理**:手动保存/恢复寄存器(如`PUSH {R4, LR}` / `POP {R4, PC}`)。
#### 验证步骤
```c
// 修改后测试代码
void test_naked() {
uint32_t psp = __get_PSP(); // 应无编译错误
__set_CONTROL(0);
}
```
> 编译通过后需进行硬件调试,验证寄存器操作的正确性。
阅读全文
相关推荐

















