今天在做一个测试的时候Keil报这个错误:

1
Warning: L6305W: Image does not have an entry point. (Not specified or not set due to multiple choices.)

我的代码文件只有一个启动文件,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
                PRESERVE8
THUMB

; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY

__Vectors DCD 0 ;__initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
__Vectors_End

AREA |.text|, CODE, READONLY

; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
LDR R0, =my_main
BX R0
ENDP

my_main PROC
MOV R0, #0
loop ADD R0, R0, #1
B loop
ENDP

; Dummy Exception Handlers (infinite loops which can be modified)

NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
HardFault_Handler\
PROC
EXPORT HardFault_Handler [WEAK]
B .
ENDP
ALIGN
END

分散加载文件如下:

1
2
3
4
5
6
7
8
9
LR_IROM1 0x08000000 0x00080000  {    ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00010000 { ; RW data
.ANY (+RW +ZI)
}
}

搜索了一下,解决办法是在Linker - Misc controls中加入这个选项--entry Reset_Handler,试了一下,确实可行

  继续思考,我这个代码其实就是把官方的启动文件中的对__main的调用改成了我自己实现的一个函数my_main,是否是因为默认检测的入口点叫__main
  于是我把选项改为--entry my_main,编译报错如下:

1
Error: L6320W: Ignoring --entry command. Cannot find argument 'my_main'.

找不到,然后我把my_main符号导出了一下,如下:

1
2
3
4
5
6
            EXPORT my_main
my_main PROC
MOV R0, #0
loop ADD R0, R0, #1
B loop
ENDP

再次编译,可以通过,运行正常。
  于是我又做了一个实验,把--entry my_main选项删除,把代码中my_main函数名改成__main,如下:

1
2
3
4
5
6
7
8
9
10
11
12
Reset_Handler   PROC
EXPORT Reset_Handler [WEAK]
LDR R0, =__main
BX R0
ENDP

EXPORT __main
__main PROC
MOV R0, #0
loop ADD R0, R0, #1
B loop
ENDP

结果不行,看来我的猜测不正确,具体为啥以后再来研究吧。