当前位置:网站首页>Transformation from AC5 to AC6 (1) - remedy and preparation

Transformation from AC5 to AC6 (1) - remedy and preparation

2022-06-12 07:57:00 Traceless rain

【 Say what's in front of you 】


The time is about 2015 year ,Arm For the first time in  MDK 5.20  Introduced in Arm Compiler 6( The version at that time was 6.9), Officially opened Arm Official compiler from the Fifth Edition (armcc) To the sixth edition (armclang) The prelude to upgrade and replacement ……

The long tail effect of embedded industry is extremely prominent , Not to mention 2022 Years later, many people still insist on MDK4, Even from “Arm stay 2017 In, it was announced to stop maintenance Arm Compiler 5” Count up , Now 5 Years have passed , Insist on using armcc There are still more than a few users .

Arm Compiler 5, That's what everyone said  armcc, Is it weak ? Relatively free tool chain  arm gcc Come on , It's still strong, obviously ; But would you say that it can play very well ? As a “ Theoretically ” Paid compilers , It has even fallen behind the latest release in all respects “ Free and open source ” compiler LLVM Embedded ToolChain For Arm 14.0.0(clang), Not to mention the popular dignitaries nowadays Arm Compiler 6(armclang) 了 .

If I have to give a copy “ be irresponsible for ” Compiler performance comparison , This is my only answer :

arm gcc < armcc < clang < IAR <= armclang 
 

Don't ask me why , Ask is who uses who knows .

If it wasn't for the product Golden Code( Shishan mountain ), As long as you choose Arm Compiler instead of IAR, Since you have to use a paid compiler , Why not Arm Routine maintenance ( A new version is released almost every six months ) Of Arm Compiler 6, And continue to cling Arm Compiler 5 Well ?

Some people say “Arm Compiler 6 Not as good as Arm Compiler 5” Stable . Here are some reasons for my rebuttal , But I don't expect to convince those who have such ideas

  • Arm Compiler 5 Maintenance has been stopped ,Arm Compiler 6 It's still being updated . No, bug The compiler does not exist , A compiler whose life cycle has ended is almost nonexistent bug And not found bug The possibility of ; An actively maintained compiler can fix the problems found in time ;

  • Arm Compiler 5 Only in the past Arm maintain , and Arm Compiler 6 Is based on LLVM(clang) Commercialized improved version of , here LLVM It's an open source project , Maintained by numerous individuals and business organizations , Refer to the past gcc The success of the —— So much “ Great intelligence ” The project being watched , Even if errors are found , I guess so “ Minutes and minutes ” They were taken to “ To ask for credit ” Is that right ?

  • Although I caught it in practice ( Reported and fixed ) Of Arm Compiler 6 bug More than the number of 99% People who , But that's why , I know I have to meet a Arm Compiler 6 Of bug How difficult is it? —— More time , In fact, we don't have a deep understanding of the compiler , Even based on your own understanding of C The wrong cognition of grammar leads to “ Wulong ”. in my opinion , Rather than doubt Arm Compiler 6 unstable , Why don't you doubt yourself C Language understanding .

  • Don't succumb to “ The fear of the unknown ”, Don't take it. “ Stigmatization ” As a cover up “ Laziness and ignorance ” A new fig leaf ( People who are angry at this sentence , Let me give you a : Do you like listening , Welcome to customs , thank you ).

See here , If you decide to continue reading , I just Suppose you are already interested in trying to use Arm Compiler 6 To gradually replace the existing Arm Compiler 5 了 . Based on this premise , We will use the following series of articles to introduce :

  • In the short term :MDK 5.37 abandon armcc Remedial measures

  • Mid - : from armcc towards armclang Conduct Some quick ways to deal with the transition period

  • Face some  armcc Solutions to unique compiler features Well

【 Interim remedies 】


Although the latest MDK  Abandoned Arm Compiler 5, But it still allows us to bring it back by adding it manually , I'm going to 《 Inside story : The old MDK You can also use the new compiler 》 It has been described in detail in the article , No more details here , It is worth adding that :

1、 new MDK You can also manually add an old version of the compiler , Don't be limited by the title of the article

2、Arm Compiler 5 The download link for is as follows :

https://developer.arm.com/downloads/-/legacy-compilers

【 A few peace of mind 】


1、“ Joint overlord ”

We know MDK It's an integrated development environment (Integrated Development Environment), It defaults to native support Arm Compiler 5(armcc)Arm Compiler 6(armclang) and  arm gcc. Although all three compilers are made by Arm Maintained and provided , But the first two are compatible compilers :

  • Use common  armlink

  • Describe the address space layout in the same way ( Distributed loading script scatter script)

  • from Arm Compiler 6.14 Start ,armclang Even began to support armasm The assembly syntax of

In fact, we can think of ,armcc and armclang It's a pair of conjoined brothers , The body is armlink, And the two heads are  armcc  and  armclang. About this feeling , You know .

As a reassuring pill, the conclusion is :

  • original  Arm Compiler 5  All libraries under the project (*.lib) Can be in  Arm Compiler 6  Under direct use

  • Originally by  Arm Compiler 5  Generated object file (*.o) Can be in  Arm Compiler 6  Under direct use

  • original  Arm Compiler 5 Used in the following “ Almost all ” armlink Relevant features can be found in  Arm Compiler 6  Use it directly ( Because it is basically the same armlink, So it hardly exists “ transplant ” That's what I'm saying )


Of course , There are still some exceptions , such as  __attribute__((at( Address )))  grammar , We will make a special topic to introduce coping styles . 


2、“ Idleness is the first productive force ”

because  Arm Compiler 6  Born out of LLVM, So in assembly syntax, it also inherits  clang  Characteristics of —— Use  GNU Assembly Syntax, Instead of Arm Has been trying to promote  Unified Assembly Language(UAL) Assembly syntax .

because Arm Compiler 5 What has been used is UAL Assembly syntax , The vast number of users have accumulated a large number of .s file .

Assembly is a headache —— Who can write a compilation unless he has to ? For many projects , Not to mention that compilation is something few big bulls dare to touch —— Almost “Golden Code( Shishan mountain )” The pronoun of , actually , these “ Historical dust ” The author of may have left his post long ago —— Even if you get me back , I'm afraid that most of the time, even the client himself is a dog biting a hedgehog and can't talk .

Even though Arm He wrote a book named 《Migrating from armasm to the armclang Integrated Assembler》 Documents to “ Teach people to do things ”, But the feedback from the community can be imagined ……

The article links below :

https://developer.arm.com/documentation/100068/0618/Migrating-from-armasm-to-the-armclang-Integrated-Assembler?lang=en

In many “ I don't want to , You beg me ……” In the voice of ,Arm Compiler 6 from 6.14 Version start , Put the UAL The support of has been added back , And in MDK This option is introduced in :

The meanings of these options are as follows :

  • armclang(Auto Select): Use armclang To compile the assembly source code ( Corresponding command line options  -masm=auto), then armclang It will automatically decide to act as according to the grammar style GNU Assembly Syntax To deal with it , Or use UAL Syntax to parse . I recommend this option for hematemesis .

  • armclang (GNU Syntax): Use  armclang  To compile the assembly source code ( Corresponding command line options  -masm=gnu), Then force the use of GNU Assembly grammar style .

  • armclang (Arm Syntax): Use armclang To compile the assembly source code ( Corresponding command line options  -masm=armasm), Then force the use of UAL Assembly grammar style .


Actually , here  armclang  He is also a second dealer —— It also calls  armasm  To complete the compilation , Just before that , It defaults to C The precompiler preprocesses the assembly source code , let me put it another way , torture armasm For many years “ How to use in assembly code C Language macros and preprocessing ” The problem of , It has been cured —— You can use it freely in assembly code #include、 Various macro definitions and #if 了 .


  • armasm(Arm Syntax): Use it directly  armasm  To compile the assembly source code . This option is right for old UAL Source code file compatibility is the best . If you use  armclang(Arm Syntax) Have a problem , Try this option —— Generally, problems can be solved smoothly .

What about? , No need to modify Shishan , Is it a relief ?

3、 Online compilation (Inline Assembly) And embedding C Compilation of code (Embedded Assembly)

Whether you know  Arm Compiler 5 The two supported are C The use of assembly methods in languages , Don't worry about the difference between them , The conclusion is that —— whatever Arm Compiler 5 Under the C The code only uses one of the above two methods , Basically “ Manual intervention is required ” Of .

Here's a panacea :

For this part C Source file , Please use armcc compile , Generate .o Throw it back to  Arm Compiler 6 Directly participate in the link .

Of course , If you are interested in rewriting as described in the previous document , I wish you a good appetite .

As for how to make the rewritten C The code is also compatible  Arm Compiler 5  and  Arm Compiler 6, The following content is indispensable —— It is also the basis for our subsequent series of differentiated transformation .

【 How to detect compilers 】


Generally speaking , When we want to migrate a part of the code across compilers , Of course, it can be changed according to the new grammar , But for many people , Old compilers always give people an indescribable souvenir ,

Then have :

“ I want to make the modified code still compatible with the old compilers ”;

or :

“ It's a pity to delete the old code , I want to stay , What if it works in the future ?”

The idea is . That's what I thought .

Do that , We can't get around a core problem : How to reliably detect the current compiler version ?

Generally speaking , There are two ideas for macro detection in compilers :

  • With the help of a compiler unique feature macro to determine the compiler

  • Use macros common to multiple compilers but with different values to determine

For the first idea , There are two famous macros :__GNUC__  and  __clang__ . In the past , Many people like to use the following code to determine whether the compilation environment is GCC perhaps CLANG

#if defined(__GNUC__)    /*  I think the compiler gcc */#endif
#if defined(__clang__)    /*  I think the compiler is  clang */#endif

However , Unfortunately , Because many compilers are in some way right  GCC  Extensions provide support , Thus macros are also defined __GNUC__, such as  armccarmclangclangIAR The macro is defined …… therefore , It almost lost GCC The value of feature macros , Degenerate to “ The current compiler supports GCC Expand ( But what exactly GCC Expand , It depends on my mood )” The logo of . Actually  __clang__  Macros are similar , because  armclang  The macro is also defined , After all Arm Compiler 6 It's from LLVM Derived from .

Of course , The more common and useful compiler feature macros are __IAR_SYSTEMS_ICC__ , With its help , We can judge whether the current development environment is IAR:

//! \note for IAR#undef __IS_COMPILER_IAR__#if defined(__IAR_SYSTEMS_ICC__)#   define __IS_COMPILER_IAR__                  1#endif

Arm Compiler 5  and  Arm Compiler 6  All are  Arm Compiler, There are many ways to distinguish them , But the official recommended method is to judge the macro  __ARMCC_VERSION  Value . You can see from the name that , This is a self  armcc  It has continued to  armclang  Shared macros for , It saves the compiler version , So we can easily write the following macros :​​​​​​​

//! \note for arm compiler 5#undef __IS_COMPILER_ARM_COMPILER_5__#if ((__ARMCC_VERSION >= 5000000) && (__ARMCC_VERSION < 6000000))#   define __IS_COMPILER_ARM_COMPILER_5__       1#endif//! @}
//! \note for arm compiler 6
#undef __IS_COMPILER_ARM_COMPILER_6__#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)#   define __IS_COMPILER_ARM_COMPILER_6__       1#endif
#undef __IS_COMPILER_ARM_COMPILER__#if defined(__IS_COMPILER_ARM_COMPILER_5__) && __IS_COMPILER_ARM_COMPILER_5__   \||  defined(__IS_COMPILER_ARM_COMPILER_6__) && __IS_COMPILER_ARM_COMPILER_6__
#   define __IS_COMPILER_ARM_COMPILER__         1
#endif

With their help , We can easily judge  __IS_COMPILER_ARM_COMPILER_5__  and  __IS_COMPILER_ARM_COMPILER_6__  Is the value of “1” To determine the current compiler version . We only care about whether the current compiler is Arm Compiler, It doesn't matter which version it is , Can use  __IS_COMPILER_ARM_COMPILER__  To judge .

Suppose our code only considers supporting  gccclangiararmcc and armclang, Then use the exclusion method , We can easily determine whether the current compilation environment is  GCC  or  LLVM 了 :​​​​​​​

#undef  __IS_COMPILER_LLVM__#if defined(__clang__) && !__IS_COMPILER_ARM_COMPILER_6__#   define __IS_COMPILER_LLVM__                 1#else//! \note for gcc#   undef __IS_COMPILER_GCC__#   if defined(__GNUC__) && !(  defined(__IS_COMPILER_ARM_COMPILER__)           \                            ||  defined(__IS_COMPILER_LLVM__)                   \                            ||  defined(__IS_COMPILER_IAR__))#       define __IS_COMPILER_GCC__              1#   endif//! @}#endif

Let's briefly talk about the idea here :

1、 In the exclusion of  Arm Compiler 6  Under the premise of , according to  __clang__  To determine whether the current compiler is  LLVM( namely :__IS_COMPILER_LLVM__);

2、 In the exclusion of  LLVMArm Compiler  and IAR Under the premise of , according to  __GNUC__  To determine whether the current compiler is  GCC
 

For your convenience , Here are some application scenarios of the above macros :

  • How to be in Arm Compiler 6  Next, tell the compiler main() Function without input arguments

By default ( Use default libc),Arm Compiler 6 Will think  main()  Functions are with standard input parameters :

int main (int argc, char *argv[]);

Even if you force main() The function is written without input parameters , The compiler will also prepare the parameters —— The process of preparing parameters is likely to lead to  hardfault( It will involve semihosting The problem of , It's quite a headache , Not for the time being ). To solve this problem , We usually do this :​​​​​​​

#if __IS_COMPILER_ARM_COMPILER_6____asm(".global __ARM_use_no_argv\n\t");#endif

Again because  MicroLib  There is no such problem , Because we can according to (MDK A macro that will be appended )__MICROLIB, To make a small distinction :​​​​​​​

#if __IS_COMPILER_ARM_COMPILER_6__#   ifndef __MICROLIB__asm(".global __ARM_use_no_argv\n\t");#   endif#endif

That is, if and only if we use  Arm Compiler 6, And don't use MicroLib When , Tell the compiler through a special syntax structure :main()  Function has no arguments passed in .

  • How to close Semihosting

Have you ever encountered such a magical scene : In debug mode , The program can run normally ; Once you exit debug mode , The system will crash , After re entering the debugging mode , It is found that the system has entered Hardfault. congratulations , This is probably ( On by default )semihosting  I'm making a mischief . About Semihosting The content of , Too much space , Not discussed in this article . Today we will just talk about how to close it .

Arm Compiler 5 and Arm Compiler 6 close  Semihosting It's different :​​​​​​​

#if __IS_COMPILER_ARM_COMPILER_6__    __asm(".global __use_no_semihosting");#elif __IS_COMPILER_ARM_COMPILER_5__    #pragma import(__use_no_semihosting)#endif

Once closed  Semihosting,Arm Compiler 6  You may report errors like the following :

Error: L6915E: Library reports error: __use_no_semihosting was requested, but _sys_exit was referenced

Simply explain why :Arm Compiler 6  A function that depends on  _sys_exit()  Used to be Semihosting Mode is provided by default , Now you put  Semihosting  Shut down the , So you have to be responsible to the end . I know why , The solution is simple —— This function is missing , We can provide one :​​​​​​​

#if __IS_COMPILER_ARM_COMPILER_6__void _sys_exit(int ret){
       (void)ret;    while(1) {}}#endif

A similar situation will also occur in a place called  _ttywrch()  On the function of , We can do the same :​​​​​​​

/*  by  arm compiler 5  and  arm compiler 6  Add this empty function  */#if __IS_COMPILER_ARM_COMPILER__void _ttywrch(int ch){
       ARM_2D_UNUSED(ch);}#endif

  • How to solve the problem of using  assert.h  Raised questions

Many codes are used  assert()  To intercept the wrong habits , When we use  Arm Compiler 6  And on  MicroLib When , because  MicroLib No right  assert()  The concrete implementation of the underlying function , When we have no definition NDEBUG To close assert() when , You will see the following compilation errors in the link phase :

Error: L6218E: Undefined symbol __aeabi_assert (referred from main.o).

When you know why , The solution is simple : since MicroLib No implementation is provided , We will provide one by ourselves :

​​​​​​​

#if __IS_COMPILER_ARM_COMPILER_6__ && defined(__MICROLIB)void __aeabi_assert(const char *chCond, const char *chLine, int wErrCode) {
       (void)chCond;    (void)chLine;    (void)wErrCode;        while(1) {
           __NOP();    }}#endif

Since the above set  __IS_COMPILER_xxxx__  So easy to use , Where can we get it ?

Currently known access channels Including but not limited to

  • Copy it from this article

  • Include getting perf_counter  And includes  perf_counter.h 

  • In existence  arm-2d  Under the circumstances , Direct contains  arm_2d.h  perhaps  arm_2d_utils.h

……

【 What's going on in the back 】


I admit that  Arm Compiler 5  Migrate to  Arm Compiler 6  It's not an easy process , But it is by no means as painful as people think , A lot of times , Maybe it's just  MDK  It is as simple as changing an option in :

How do you know if you don't try ?

For major chip manufacturers , such as ST and NXP Come on , Their libraries have long been completed Arm Compiler 6 Support for , It can be said that if you encounter compiler compatibility problems , First of all Consider downloading the latest version of the driver library .

The method introduced in this paper , Basically, it can deal with common problems from Arm Compiler 5 To  Arm Compiler 6 Possible problems . This is certainly not a panacea , For some special cases , We will have a special discussion in the following articles .


Finally, the download links of various compilers are attached :

Arm Compiler 5:

https://developer.arm.com/downloads/-/legacy-compilers

Arm Compiler 6:

https://developer.arm.com/downloads/-/arm-compiler-for-embedded

Arm GCC:

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads

LLVM Embedded ToolChain for Arm 14.0.0

https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases

You can also follow the official account 【 Naked thinking 】 after , Send a message LLVM get


原网站

版权声明
本文为[Traceless rain]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206120755212752.html