The compiler (or linker) issues BLX inst. in Cortex-M3 binary

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

The compiler (or linker) issues BLX inst. in Cortex-M3 binary

4,885 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by thracia on Sat Sep 11 21:26:29 MST 2010
Hi, All,

I notice that if I try to call a function written in ASM source file, from a C function,  the call will be translated into a BLX inst. Since BLX is unsupported by c-m3, a hardware exception occurs.

This is a known problem/bug:
http://www.codesourcery.com/archives/arm-gnu/msg03586.html

I am wondering if there's any other workaround. Or is it going to be fixed soon?

Thank you.
0 项奖励
回复
12 回复数

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dimasusl on Tue Nov 16 09:52:34 MST 2010
Thanks a lot!

I basically thought I was doing something wrong. Of course it is inconvenient to use absolute addresses, I just wanted to try calling a remote function.
[COLOR=#000000]
[/COLOR]
Quote: CodeRedSupport
So you are effectively trying to call using a function pointer. However the code you have written for this is wrong.

One way to fix this is to change:
some_func_ret = some_func_clone()+1;
to
int (*fp)(void);
fp = some_func_clone;
some_func_ret = fp() + 1;
Note that the address you have placed in you linker script is not actually pointing to some_func(). It is actually pointing into the middle of LCD_FilledRect(). You would probably do better simply taking the address within your code.

Regards,
CodeRedSupport

0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Nov 16 08:47:22 MST 2010
So you are effectively trying to call using a function pointer. However the code you have written for this is wrong.

One way to fix this is to change:
some_func_ret = some_func_clone()+1;
to
int (*fp)(void);
fp = some_func_clone;
some_func_ret = fp() + 1;
Note that the address you have placed in you linker script is not actually pointing to some_func(). It is actually pointing into the middle of LCD_FilledRect(). You would probably do better simply taking the address within your code.

Regards,
CodeRedSupport
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dimasusl on Tue Nov 16 06:59:02 MST 2010

Quote: CodeRedSupport
If you need more help, then please post an example project that shows up the problem. To export your project from your workspace, use:

Quickstart Panel - Import and Export - Export projects to archive (zip)

Regards,
CodeRedSupport



I work with project that shows how to work with MPU support in FreeRTOS on LPC1768, so i get this project "as is" and add there function "some_func". This function return value "10" in integer.
Than i defined in .ld "some_func_clone" as absolute address of  "some_func"+1.
In funtion "prvSetupHardware" i call this:
some_func_ret = some_func();     // 10
some_func_ret = some_func_clone()+1;  // 11

In .lss is the same in both variants, but "some_func" calls via bl instruction, and "some_func_clone" via blx. When call "some_func_clone" the hardfault exception is happend.

PS No need to look no sense, it's just an example. In  the end, is expected to cause different functions of the user  applications, which will be uploaded in a separate area of flash memory.
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Nov 16 06:08:08 MST 2010
If you need more help, then please post an example project that shows up the problem. To export your project from your workspace, use:

Quickstart Panel - Import and Export - Export projects to archive (zip)

Regards,
CodeRedSupport
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dimasusl on Tue Nov 16 05:52:23 MST 2010

Quote: CodeRedSupport
I suspect that you just need to set the bottom bit of the address of your function:

[COLOR=#000000]some_func = 0x00008b55;[/COLOR]

Normally the setting of the bottom bit of the address of functions is done automatically, but as you are hardcoding the addres in the linker script, you will need to do it manually. [All Thumb functions have the bottom bit set, even on Thumb only processors.]

Regards,
CodeRedSupport.



I tried to do so, but it did not help. I do not know what else to try:confused:
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Nov 16 05:44:01 MST 2010
I suspect that you just need to set the bottom bit of the address of your function:

[COLOR=#000000]some_func = 0x00008b55;[/COLOR]

Normally the setting of the bottom bit of the address of functions is done automatically, but as you are hardcoding the addres in the linker script, you will need to do it manually. [All Thumb functions have the bottom bit set, even on Thumb only processors.]

Regards,
CodeRedSupport.
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dimasusl on Tue Nov 16 05:38:18 MST 2010

Quote: CodeRedSupport
Sorry, this thread was about calling assembler from C - thus I am not sure that I follow what your problem is. What is your actually problem with calling C from C?



[COLOR=#000000]Sorry that is not on topic.
I just want to call function using absolute address of it.
In my .ld script i define address of some function in flash, for example:
some_func = 0x00008b54;

In main.c:
extern void some_func(insigned int);

When i call this function, hard fault exception happens. [/COLOR]I looked in the .lss file and saw something like this:
   some_func(1);
    6aa4:    f04f 0001     mov.w    r0, #1
    6aa8:    f002 e854     blx    8b54 <some_func>

There are two flags to the compiler present "-mcpu=cortex-m3" and "-mthumb" for correct compile of project. The study of a large number of forums has led to the conclusion that the error here in using the command blx instead bl. I tried the solution offered in other forums, but none has led to a positive result.
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Nov 16 04:47:12 MST 2010

Quote: dimasusl

What may i do, to fix it, when i calling C function from C function?


Sorry, this thread was about calling assembler from C - thus I am not sure that I follow what your problem is. What is your actually problem with calling C from C?
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dimasusl on Tue Nov 16 04:10:32 MST 2010
Hello, CodeRedSupport!
What may i do, to fix it, when i calling C function from C function?

Thanks!


Quote: CodeRedSupport
Actually I suspect that you not marking your assembler as a thumb function. Even though you are assembling for a Thumb-2 only cpu, the gnu assembler seems to default back to ARM state every time it encounters a new function. And as your assembler function is marked as ARM, the linker uses a BLX <offset> instruction (which is not valid on CM3) to branch to it from your C code.

To fix this, simply mark your thumb function source code with the ".thumb_func" [FONT=Times New Roman]attribute immediately before the label.[/FONT]

See this thread for an example:

http://knowledgebase.nxp.com/showthread.php?t=85

Regards,
CodeRedSupport.

0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by thracia on Sun Sep 12 09:09:42 MST 2010
rkiryanov:
Actually I mean BLX imm. Sorry for the confuse.

CodeRedSupport:
That solves my problem!

Thank you!
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Sun Sep 12 04:52:57 MST 2010

Quote: thracia
I notice that if I try to call a function written in ASM source file, from a C function,  the call will be translated into a BLX inst. Since BLX is unsupported by c-m3, a hardware exception occurs.

This is a known problem/bug:
http://www.codesourcery.com/archives/arm-gnu/msg03586.html


Actually I suspect that you not marking your assembler as a thumb function. Even though you are assembling for a Thumb-2 only cpu, the gnu assembler seems to default back to ARM state every time it encounters a new function. And as your assembler function is marked as ARM, the linker uses a BLX <offset> instruction (which is not valid on CM3) to branch to it from your C code.

To fix this, simply mark your thumb function source code with the ".thumb_func" [FONT=Times New Roman]attribute immediately before the label.[/FONT]

See this thread for an example:

http://knowledgebase.nxp.com/showthread.php?t=85

Regards,
CodeRedSupport.
0 项奖励
回复

4,713 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Sun Sep 12 00:11:42 MST 2010

Quote: thracia
Since BLX is unsupported by c-m3



BLX is supported by Cortex-M3, see ARM®v7-M Architecture Reference Manual (DDI0403C), A6.7.19 BLX (register).
0 项奖励
回复