嵌入式


cmsis bug

<p>gcc-arm-none-eabi-4_7-2012q4-20121208 broken for CMSIS Asked by grissiom on 2012-12-28</p> <p>I've upgrade to gcc-arm-none-eabi-4_7-2012q4-20121208 but found it could not compile my projects:</p> <pre><code>arm-none-eabi-gcc -o build/Libraries/CMSIS/CM3/CoreSupport/core_cm3.o -c -mcpu=cortex-m3 -mthumb -ffunction-sections -fdata-sections -std=c99 -Wall -O2 -gdwarf-2 -Os -DUSE_STDPERIPH_DRIVER -DSTM32F10X_HD -DRT_USING_MINILIBC -Iapplications -Irt-thread/applications -I. -Irt-thread -Iapplications -Irt-thread/applications -I. -Irt-thread -Idrivers/lcd -Irt-thread/drivers/lcd -Idrivers -Irt-thread/drivers -Idrivers/touch -Irt-thread/drivers/touch -Idrivers -Irt-thread/drivers -Idrivers -Irt-thread/drivers -ILibraries/STM32F10x_StdPeriph_Driver/inc -Irt-thread/Libraries/STM32F10x_StdPeriph_Driver/inc -ILibraries/CMSIS/CM3/CoreSupport -Irt-thread/Libraries/CMSIS/CM3/CoreSupport -ILibraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x -Irt-thread/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x -Irt-thread/include -Irt-thread/rt-thread/include -Irt-thread/libcpu/arm/cortex-m3 -Irt-thread/rt-thread/libcpu/arm/cortex-m3 -Irt-thread/libcpu/arm/common -Irt-thread/rt-thread/libcpu/arm/common -Irt-thread/components/drivers/include -Irt-thread/rt-thread/components/drivers/include -Irt-thread/components/drivers/include -Irt-thread/rt-thread/components/drivers/include -Irt-thread/components/external/tjpgd1a -Irt-thread/rt-thread/components/external/tjpgd1a -Irt-thread/components/finsh -Irt-thread/rt-thread/components/finsh -Irt-thread/components/libc/minilibc -Irt-thread/rt-thread/components/libc/minilibc -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/include -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/common -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/server -I/win_backyard/projects/rt-thread/RTGUI/components/rtgui/widgets Libraries/CMSIS/CM3/CoreSupport/core_cm3.c /tmp/cc7HfyyL.s: Assembler messages: /tmp/cc7HfyyL.s:508: Error: registers may not be the same -- `strexb r0,r0,[r1]' /tmp/cc7HfyyL.s:533: Error: registers may not be the same -- `strexh r0,r0,[r1]'</code></pre> <p>I've added</p> <pre><code>#include &lt;stdint.h&gt; #define __ASM __asm /*!&lt; asm keyword for GNU Compiler */ #define __INLINE inline /*!&lt; inline keyword for GNU Compiler */ uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0; __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); }</code></pre> <p>to share/gcc-arm-none-eabi/samples/src/minimum/minimum.c and the sample failed to compile as well:</p> <pre><code>arm-none-eabi-gcc minimum.c ../../startup/startup_ARMCM0.S -mthumb -mcpu=cortex-m0 -D__STARTUP_CLEAR_BSS -D__START=main -Os -ffunction-sections -fdata-sections --specs=nano.specs -lc -lc -lnosys -L. -L../../ldscripts -T gcc.ld -Wl,--gc-sections -Wl,-Map=minimum.map -o minimum-CM0.axf /tmp/ccxAzAZy.s: Assembler messages: /tmp/ccxAzAZy.s:22: Error: selected processor does not support Thumb mode `strexb r0,r0,[r1]' make: *** [minimum-CM0.axf] Error 1</code></pre> <p>I think the toolchain is currently broken.</p> <p>Question</p> <p>When compiling applications that contain or use the Cortex Microcontroller Software Interface Standard e.g. CMSIS (<a href="http://www.onarm.com/cmsis/">http://www.onarm.com/cmsis/</a>) you may receive the following errors:</p> <pre><code>/tmp/ccaxp69S.s: Assembler messages: /tmp/ccaxp69S.s:463: Error: registers may not be the same -- `strexb r0,r0,[r1]' /tmp/ccaxp69S.s:488: Error: registers may not be the same -- `strexh r0,r0,[r1]'</code></pre> <p>How do I fix these &quot;registers may not be the same&quot; errors? Where do they come from?</p> <p>Answer</p> <p>Some versions of the CMSIS contain invalid inline assembly of the following form:</p> <pre><code>uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0; asm volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); }</code></pre> <p>The first constraint =r on variable result is not correct, it should be =&amp;r to indicate that the two registers used should not be the same e.g. early-clobber (this is required by the ARM Instruction Set Architecture).</p> <p>To fix the error you must locate the invalid inline assembly and change the =r to =&amp;r for the result register variable.</p> <p>Often it is difficult to determine which source file was used to generate /tmp/ccaxp69S.s, to help with that problem add -save-temps to the compiler invocation to save the intermediate output to the current directory for your review.</p> <p>This entry was last updated on 8 February 2012.</p> <p>Thank both of you for trying our tool chain and share experience.</p> <p>I just checked the M0 arch doc and found that the strexb is supported starting from armv7-m. So it makes sense to generate error message &quot; selected processor does not support Thumb mode...&quot; for cortex-m0.</p> <p>For cortex-m3, it should work and we need to update &quot;=r&quot; to &quot;=&amp;r&quot;. In latest CMSIS, it is already updated. Here is the result of grep:</p> <p>terguo01@sha-win-053 /cygdrive/d/work/cmsis/CMSIS_V3P00 $ grep -r &quot;strexb&quot; * CMSIS/Include/core_cmInstr.h: __ASM volatile (&quot;strexb %0, %2, [%1]&quot; : &quot;=&amp;r&quot; (result) : &quot;r&quot; (addr), &quot;r&quot; (value) );</p> <p>You can upgrade your CMSIS to fix this issue. The latest CMSIS can be found at <a href="http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php">http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php</a>.</p> <p>grissiom (chaos.proton) said on 2012-12-31: #3 Hmm, &quot;=&amp;r&quot; could resolve the problem. But, why Rn and Rt in STREX could not be the same? ARM® v7-M Architecture Reference Manual(Derrata 2010_Q3) said:</p> <p>STREXB<c> <Rd>,<Rt>,[<Rn>] d = UInt(Rd); t = UInt(Rt); n = UInt(Rn); if d IN {13,15} || t IN {13,15} || n == 15 then UNPREDICTABLE; if d == n || d == t then UNPREDICTABLE;</p> <p>But d == t is not a wrong case in the manual.</p> <p>Besides, GCC 4.6 could compile the code. Which one is wrong?</p> <p>BestTerry Guo (terry.guo) said on 2013-01-01: #4 I think we need to clarify something here:</p> <p>1). This is an Assembler error message and nothing related to compiler. The gas 2.21 in 4.6 12Q4 release hasn't such check, so no this message. In this 4.7 release, the gas is upgraded to 2.22 and has such operands check, so we got this error message. And I think 2.22 is right because of item 2). The exact patch is at <a href="http://sourceware.org/ml/binutils/2011-07/msg00191.html">http://sourceware.org/ml/binutils/2011-07/msg00191.html</a>.</p> <p>2). For case with &quot;=r&quot;, the generated instruction is something like &quot;strexb r0,r0,[r1]&quot;. Here the Rn is r1, Rt and Rd is r0. Just as the manual said, the Rd had better to be different from Rt. So the Assembler 2.22 is complaining of two r0 registers, the same Rd and Rt. There is no complain on Rn and Rt. I think it is ok to make Rn and Rt in same register. Here is what I did:</p> <p>terguo01@terry-pc01:launchpad-questions$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -c -Os m0.c terguo01@terry-pc01:launchpad-questions$ arm-none-eabi-objdump -d m0.o</p> <p>m0.o: file format elf32-littlearm</p> <p>Disassembly of section .text:</p> <p>00000000 <__STREXB>: 0: e8c1 1f43 strexb r3, r1, [r1] 4: 4618 mov r0, r3 6: 4770 bx lr terguo01@terry-pc01:launchpad-questions$ cat m0.c unsigned int __STREXB(unsigned int value, unsigned int *addr) { unsigned int result = 0;</p> <p>__asm volatile (&quot;strexb %0, %1, [%1]&quot; : &quot;=&amp;r&quot; (result) : &quot;r&quot; (addr), &quot;r&quot; (value));</p> <p>return result; } terguo01@terry-pc01:launchpad-questions$</p> <p>grissiom (chaos.proton) said on 2013-01-01: #5 Thanks Terry Guo, that solved my question.</p> <p>Michael Fischer (emb4fun) said on 2013-01-01: #6 Hello,</p> <p>I have tested the original example here with my Cortex-M3 example too. I have added the code:</p> <h1>define <strong>ASM </strong>asm</h1> <p>uint32_t __STREXB(uint8_t value, uint8_t *addr) { uint32_t result=0;</p> <p>__ASM volatile (&quot;strexb %0, %2, [%1]&quot; : &quot;=r&quot; (result) : &quot;r&quot; (addr), &quot;r&quot; (value) ); return(result); }</p> <p>And had no problems. I use the latest version under windows from 2012-12-24:</p> <p>arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.7.3 20121207 (releas e) [ARM/embedded-4_7-branch revision 194305] Copyright (C) 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p> <p>I have added the code to my example here: <a href="http://www.emb4fun.de/download/arm/examples/STM32Test.zip">http://www.emb4fun.de/download/arm/examples/STM32Test.zip</a></p> <p>It is strange that I does not get the error.</p> <p>Best regards, Michael</p> <p>Terry Guo (terry.guo) said on 2013-01-01: #7 Hi Michael,</p> <p>Can you please share your command line options on Windows? The original example is compiled with -O2. And with -O2, the tool chain on windows can generate this error in my environment:</p> <p>$ arm-none-eabi-gcc -mthumb -mcpu=cortex-m3 -c m3.c -O2 D:\Cygwin\cygwin\tmp\ccjhexe2.s: Assembler messages: D:\Cygwin\cygwin\tmp\ccjhexe2.s:26: Error: registers may not be the same -- `strexb r0,r0,[r1]'</p> <p>And with -O0, there is no such error for tool chain on Windows and Linux.</p> <p>So far I haven't observed any different behaviors between Windows and Linux tool chain.</p> <p>Best regards, Terry</p> <p>Michael Fischer (emb4fun) said on 2013-01-03: #8 Hello Terry,</p> <p>ups, here the same. I have not test it before with optimization. My example use -O0, with 1,2 or 3 I got the same error message.</p> <p>Best regards, Michael</p>

页面列表

ITEM_HTML