Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: BUG: Keil Inline функция
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kravitz
Баг мягко выражаясь странный ...
Есть inline функция AT91F_PDC_IsTxEmpty из AT91SAM7S256.h от Atmel,
вызывается AT91F_US_SendFrame --> AT91F_PDC_SendFrame --> AT91F_PDC_IsTxEmpty (все inline)

А вот код сгенерированный Keil'ом в котором вместо подстановки тела функции AT91F_PDC_IsTxEmpty,
вызов "несуществующей" функции. Только не говорите что компилятор в данном случае
проигнорировал директиву inline и вызывает AT91F_PDC_IsTxEmpty как обычную функцию.
Во-первых, переход (BL) осуществляется но адресу 0x00000000 что видно в debuger'е, во-вторых, из
map-файла видно, что данной функции в сегменте кода НЕТ.

Максимальный уровень вложенности вызова функции AT91F_PDC_IsTxEmpty в программе = 5
main() --> menu() --> message() --> AT91F_US_SendFrame() --> ...

BAD

Код
----------- ASSEMBLER CODE LISTING

 152:    AT91F_US_SendFrame( AT91C_BASE_US0, debug_message, len, 0, 0 );
00202DA4  E1A00001  MOV         R0,R1; len
00202DA8  E1A01C00  MOV         R1,R0,LSL #24; len
00202DAC  E1A01C21  MOV         R1,R1,LSR #24
00202DB0  ---- Variable 'szBuffer' assigned to Register 'R1' ----
00202DB0  E59F30A0  LDR         R3,[PC,+160]; PoolRef @0x202E58
00202DB4  ---- Variable 'pUSART' assigned to Register 'R3' ----
00202DB4  E59F2098  LDR         R2,[PC,+152]; PoolRef @0x202E54; debug_message
00202DB8  ---- Variable 'pBuffer' assigned to Register 'R2' ----
00202DB8  E3A00000  MOV         R0,#0x0
00202DBC  ---- Variable 'pNextBuffer' assigned to Register 'R0' ----
2712: __inline unsigned int AT91F_US_SendFrame(
00202DBC           ; SCOPE-START
2719:  return AT91F_PDC_SendFrame(
00202DBC  E1A06003  MOV         R6,R3; pUSART
00202DC0  E2866C01  ADD         R6,R6,#0x0100; pUSART
00202DC4  ---- Variable 'pPDC' assigned to Register 'R6' ----
00202DC4  E1A05002  MOV         R5,R2; pBuffer
00202DC8  ---- Variable 'pBuffer' assigned to Register 'R5' ----
00202DC8  E1A04001  MOV         R4,R1; szBuffer
00202DCC  ---- Variable 'szBuffer' assigned to Register 'R4' ----
00202DCC  E1A07000  MOV         R7,R0; pNextBuffer
00202DD0  ---- Variable 'pNextBuffer' assigned to Register 'R7' ----
 385: __inline unsigned int AT91F_PDC_SendFrame(
00202DD0           ; SCOPE-START
 392:  if (AT91F_PDC_IsTxEmpty(pPDC)) {
00202DD0  E1A00006  MOV         R0,R6; pPDC
00202DD4  EBF7F489  BL          AT91F_PDC_IsTxEmpty?A ; Targ=0x0          !!! ERROR !!!
00202DD8  E3500000  CMP         R0,#0x0000; AT91F_PDC_IsTxEmpty?A
00202DDC  0A000008  BEQ         L_705 ; Targ=0x202E04

----------- KEIL DEBUGER + SIMULATOR

  152:           AT91F_US_SendFrame( AT91C_BASE_US0, debug_message, len, 0, 0 );
0x00202DA4  E1A00001  MOV       R0,R1
0x00202DA8  E1A01C00  MOV       R1,R0,LSL #24
0x00202DAC  E1A01C21  MOV       R1,R1,LSR #24
0x00202DB0  E59F30A0  LDR       R3,[PC,#0x00A0]
0x00202DB4  E59F2098  LDR       R2,[PC,#0x0098]
0x00202DB8  E3A00000  MOV       R0,#0x00000000
0x00202DBC  E1A06003  MOV       R6,R3
0x00202DC0  E2866C01  ADD       R6,R6,#0x00000100
0x00202DC4  E1A05002  MOV       R5,R2
0x00202DC8  E1A04001  MOV       R4,R1
0x00202DCC  E1A07000  MOV       R7,R0
0x00202DD0  E1A00006  MOV       R0,R6
0x00202DD4  EBF7F489  BL        0x00000000          !!! ERROR !!!
0x00202DD8  E3500000  CMP       R0,#0x00000000
0x00202DDC  0A000008  BEQ       0x00202E04


А вот если уменьшить максимальный уровень вложенности до 4х
main() --> message() --> AT91F_US_SendFrame() --> ...
код генерируется правильный:

GOOD

Код
----------- ASSEMBLER CODE LISTING

152:    AT91F_US_SendFrame( AT91C_BASE_US0, debug_message, len, 0, 0 );
00202D98  E1A00001  MOV         R0,R1; len
00202D9C  E1A02C00  MOV         R2,R0,LSL #24; len
00202DA0  E1A02C22  MOV         R2,R2,LSR #24
00202DA4  ---- Variable 'szBuffer' assigned to Register 'R2' ----
00202DA4  E59F3110  LDR         R3,[PC,+272]; PoolRef @0x202EBC
00202DA8  ---- Variable 'pUSART' assigned to Register 'R3' ----
00202DA8  E59F0108  LDR         R0,[PC,+264]; PoolRef @0x202EB8; debug_message
00202DAC  ---- Variable 'pBuffer' assigned to Register 'R0' ----
00202DAC  E3A08000  MOV         R8,#0x0
00202DB0  ---- Variable 'pNextBuffer' assigned to Register 'R8' ----
2712: __inline unsigned int AT91F_US_SendFrame(
00202DB0           ; SCOPE-START
2719:  return AT91F_PDC_SendFrame(
00202DB0  E1A01003  MOV         R1,R3; pUSART
00202DB4  E2811C01  ADD         R1,R1,#0x0100; pUSART
00202DB8  ---- Variable 'pPDC' assigned to Register 'R1' ----
00202DB8  E1A03000  MOV         R3,R0; pBuffer
00202DBC  ---- Variable 'pBuffer' assigned to Register 'R3' ----
00202DBC  E1A00002  MOV         R0,R2; szBuffer
00202DC0  ---- Variable 'szBuffer' assigned to Register 'R0' ----
00202DC0  E1A04008  MOV         R4,R8; pNextBuffer
 385: __inline unsigned int AT91F_PDC_SendFrame(
00202DC4           ; SCOPE-START
 392:  if (AT91F_PDC_IsTxEmpty(pPDC)) {
00202DC4  E1A05001  MOV         R5,R1; pPDC
00202DC8  ---- Variable 'pPDC' assigned to Register 'R5' ----
 304: __inline int AT91F_PDC_IsTxEmpty ( // \return return 1 if transfer is complete
00202DC8           ; SCOPE-START
 307:  return !(pPDC->PDC_TCR);
00202DC8  E1A02005  MOV         R2,R5; pPDC
00202DCC  E592200C  LDR         R2,[R2,#0xC]
00202DD0  E3520000  CMP         R2,#0x0000
00202DD4  1A000001  BNE         L_717 ; Targ=0x202DE0
00202DD8  E3A05001  MOV         R5,#0x1
00202DDC  EA000000  B           L_718 ; Targ=0x202DE4
00202DE0          L_717:
00202DE0  E3A05000  MOV         R5,#0x0
00202DE4          L_718:
00202DE4  ---- Variable 'AT91F_PDC_IsTxEmpty?A?Rtv' assigned to Register 'R5' ----
 308: }

----------- DEBUGER

  152:           AT91F_US_SendFrame( AT91C_BASE_US0, debug_message, len, 0, 0 );
0x00202D98  E1A00001  MOV       R0,R1
0x00202D9C  E1A02C00  MOV       R2,R0,LSL #24
0x00202DA0  E1A02C22  MOV       R2,R2,LSR #24
0x00202DA4  E59F3110  LDR       R3,[PC,#0x0110]
0x00202DA8  E59F0108  LDR       R0,[PC,#0x0108]
0x00202DAC  E3A08000  MOV       R8,#0x00000000
0x00202DB0  E1A01003  MOV       R1,R3
0x00202DB4  E2811C01  ADD       R1,R1,#0x00000100
0x00202DB8  E1A03000  MOV       R3,R0
0x00202DBC  E1A00002  MOV       R0,R2
0x00202DC0  E1A04008  MOV       R4,R8
0x00202DC4  E1A05001  MOV       R5,R1
0x00202DC8  E1A02005  MOV       R2,R5
0x00202DCC  E592200C  LDR       R2,[R2,#0x000C]
0x00202DD0  E3520000  CMP       R2,#0x00000000
0x00202DD4  1A000001  BNE       0x00202DE0
0x00202DD8  E3A05001  MOV       R5,#0x00000001
0x00202DDC  EA000000  B         0x00202DE4
0x00202DE0  E3A05000  MOV       R5,#0x00000000
kravitz
В завершение темы smile.gif, прикрепляю patch от Keil Software для устранения данного Bug'а. Получил сегодня, текст письма ниже.

Цитата
Hello,

The atteched patch should cure the problem in which CARM doesn't expand
inline functions properly.

Just unzip the file into C:\keil\ARM\BIN


Best Regards,
Brian Clough
Technical Support Analyst
Keil Software, Inc.

Email Address:  support.us@keil.com


Нажмите для просмотра прикрепленного файла
Evgeny_CD
Цитата(kravitz @ Oct 10 2005, 11:28)
В завершение темы  smile.gif, прикрепляю patch от Keil Software для устранения данного Bug'а.
А патч с клизьмами совместим?
Make_Pic
Цитата(Evgeny_CD @ Oct 10 2005, 13:24)
Цитата(kravitz @ Oct 10 2005, 11:28)
В завершение темы  smile.gif, прикрепляю patch от Keil Software для устранения данного Bug'а.
А патч с клизьмами совместим?
*



Я думаю да, т.к. код исполняемых файлов пилюлями не корректируется. Ищите пилюлю на местном ftp/
kravitz
Cовместим, хотя клизма именно компилятору совсем и не обязательна.
(третий раз правлю сообщение, основательно заработался smile.gif )
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.