Keil5配置GCC編譯器編譯STM32工程

Keil通常使用ARMCC編譯MCU工程代碼。偶然據說Keil也是支持內嵌GCC編譯器的。因而嘗試了網上博客所述的一些方法,最終找到了一篇博客html

http://blog.csdn.net/lan120576664/article/details/46806991ide

按照文中所述,發現仍存在一些其餘錯誤,後來又查找了其餘相關資料,在這做以總結函數

1、下載GCC編譯器
https://launchpad.net/gcc-arm-embedded/this

2、安裝GCC
GCC解壓到keil的安裝目錄下面。以下圖 spa


3、配置Keil
以下圖所示進行相關設置:.net

Prefix:arm-none-eabi-
Folder:D:\keil_MDK\Keil_v5\ARM\GCC\ (注:這裏是剛剛安裝的GCC所在位置)debug


4、配置工程設置
1.配置CC編譯規則
注意勾選一下選項,填寫規則3d

Misc Controls : -mcpu=cortex-m3 -mthumb -fdata-sections -ffunction-sections
注:
1.這裏我用的cortex-m3,若是你是m4內核就改爲4)
2.-mthumb的意義是:使用這個編譯選項生成的目標文件是Thumb的
3.-fdata-sections和-ffunction-sections和下文鏈接規則一塊兒說code


2.配置Assembler編譯規則
相似前一項orm

Misc Controls : -mcpu=cortex-m3 -mthumb


3.配置Linker鏈接規則
這裏要添加鏈接腳本,通常能夠在官方提供的固件庫包找到相似的

Misc Controls : -Wl,–gc-sections
注:
1.注意這個gc前面是兩個短小的「–」,因爲博客的問題直接複製會出錯
2.-wl, 表示後面的參數 –gc-sections 傳遞給連接器
3.-fdata-sections和-ffunction-sections和–gc-sections的說明以下
-ffunction-sections和-fdata-sections會使編譯器爲每一個function和data item分配獨立的section。 –gc-sections會使鏈接器刪除沒有被使用的section。
鏈接操做以section做爲最小的處理單元,只要一個section中有某個符號被引用,該section就會被放入output中。這些選項一塊兒使用會從最終的輸出文件中刪除全部未被使用的function和data, 只包含用到的unction和data。

具體細節能夠參考另外一位博主的文章http://blog.csdn.net/pengfei240/article/details/55228228

 

4.stm32f10x_flash_extsram.ld內容
/*
Default linker script for STM32F10x_1024K_1024K
Copyright RAISONANCE S.A.S. 2008
*/

/* include the common STM32F10x sub-script */

/* Common part of the linker scripts for STM32 devices*/


/* default stack sizes.

These are used by the startup in order to allocate stacks for the different modes.
*/

__Stack_Size = 1024 ;

PROVIDE ( _Stack_Size = __Stack_Size ) ;

__Stack_Init = _estack - __Stack_Size ;

/*"PROVIDE" allows to easily override these values from an object file or the commmand line.*/
PROVIDE ( _Stack_Init = __Stack_Init ) ;

/*
There will be a link error if there is not this amount of RAM free at the end.
*/
_Minimum_Stack_Size = 0x100 ;


/* include the memory spaces definitions sub-script */
/*
Linker subscript for STM32F10x definitions with 1024K Flash and 1024K External SRAM */

/* Memory Spaces Definitions */

MEMORY
{
RAM (xrw) : ORIGIN = 0x68000000, LENGTH = 1024K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB2 (rx) : ORIGIN = 0x00000000, LENGTH = 0
EXTMEMB3 (rx) : ORIGIN = 0x00000000, LENGTH = 0
}

/* higher address of the user mode stack */
_estack = 0x68100000;

 

/* include the sections management sub-script for FLASH mode */

/* Sections Definitions */

SECTIONS
{
/* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, which goes to FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH

/* for some STRx devices, the beginning of the startup code is stored in the .flashtext section, which goes to FLASH */
.flashtext :
{
. = ALIGN(4);
*(.flashtext) /* Startup code */
. = ALIGN(4);
} >FLASH


/* the program code is stored in the .text section, which goes to Flash */
.text :
{
. = ALIGN(4);

*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)

. = ALIGN(4);
_etext = .;
/* This is used by the startup in order to initialize the .data secion */
_sidata = _etext;
} >FLASH

 

/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;

*(.data)
*(.data.*)

. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >RAM

 

/* This is the uninitialized data section */
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;

*(.bss)
*(COMMON)

. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
} >RAM

PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );

/* This is the user stack section
This is just to check that there is enough RAM left for the User mode stack
It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;

. = . + _Minimum_Stack_Size ;

. = ALIGN(4);
_eusrstack = . ;
} >RAM

 

/* this is the FLASH Bank1 */
/* the C or assembly source must explicitly place the code or data there
using the "section" attribute */
.b1text :
{
*(.b1text) /* remaining code */
*(.b1rodata) /* read-only data (constants) */
*(.b1rodata*)
} >FLASHB1

/* this is the EXTMEM */
/* the C or assembly source must explicitly place the code or data there
using the "section" attribute */

/* EXTMEM Bank0 */
.eb0text :
{
*(.eb0text) /* remaining code */
*(.eb0rodata) /* read-only data (constants) */
*(.eb0rodata*)
} >EXTMEMB0

/* EXTMEM Bank1 */
.eb1text :
{
*(.eb1text) /* remaining code */
*(.eb1rodata) /* read-only data (constants) */
*(.eb1rodata*)
} >EXTMEMB1

/* EXTMEM Bank2 */
.eb2text :
{
*(.eb2text) /* remaining code */
*(.eb2rodata) /* read-only data (constants) */
*(.eb2rodata*)
} >EXTMEMB2

/* EXTMEM Bank0 */
.eb3text :
{
*(.eb3text) /* remaining code */
*(.eb3rodata) /* read-only data (constants) */
*(.eb3rodata*)
} >EXTMEMB3

 

/* after that it's only debugging information. */

/* remove the debugging information from the standard libraries */
DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}

/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
5、啓動代碼,使用GCC專用的.S文件
使用GCC編譯器須要的啓動代碼不一樣與AMRCC,不過官方已經有提供了相關代碼,以下圖:


6、編譯運行
1.core_cm3.c錯誤

出現兩個錯誤,通過在搜索發現原來是官方提供的core_cm3.c有bug形成的
將其中
736行改成:

__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
1
753行改成:

__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
1
這樣就不會有錯誤了。

2.標準的C 庫函數錯誤

如上圖所示出現兩個錯誤,根據原文所述若是有使用標準的C 函數,如sprintf,則要包含syscall.c 這個文件。因而我查找了標準庫文件發現沒有提供,後來又查找了HAL庫的文件,找到了syscall.c以下圖

添加後只剩下一個錯誤

以下:

ld.exe: section .ARM.exidx loaded at [080053dc,080053e3] overlaps section .data loaded at [080053dc,08005d83]
1
這裏發現.ARM.exidx與.data段重疊了,可是.ARM.exidx段到底是什麼?
在這篇文章中找到了答案http://www.cnblogs.com/tfanalysis/p/3652788.html
最終,個人解決辦法是在stm32f10x_flash_extsram.ld鏈接腳本文件第75行添加如下代碼

/* 添加.ARM.exidx段 */
.ARM.exidx : {
. = ALIGN(4);
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
. = ALIGN(4);
} >FLASH
1
2
3
4
5
6
修改後再次編譯發現沒有錯誤。
注:
1.鏈接腳本規則能夠參考這篇博客http://blog.csdn.net/cat_lover/article/details/50727988
2.我的理解鏈接腳本相似用ARMCC,ARMLINK編譯鏈接時寫的.sct格式分散加載文件

7、編譯成功

注:採用GCC編譯器後沒法使用「Go To Definition Of 」跳轉到相應的函數這個功能。 附上工程:http://download.csdn.net/download/weixin_39871788/10166971--------------------- 做者:Quarder 來源:CSDN 原文:https://blog.csdn.net/weixin_39871788/article/details/78858791 版權聲明:本文爲博主原創文章,轉載請附上博文連接!

相關文章
相關標籤/搜索