I spent the last two afternoons procrastinating from other work doing a deferred maintenance project, porting the labs for UK’s CPE287 Introduction to Embedded Systems from the “V5” armcc to the “V6” armclang compiler, since the most recent releases of Keil (the IDE we use in the class) have dropped support for the older compiler, and all our materials were written against V5. It has been a somewhat interesting porting exercise for a “same vendor, same platform” situation.
We have some slightly unusual circumstances: First, because the class starts in writing pure assembly, proceeds through manual bit manipulation in C, and eventually starts to write high-level software driver model code, we hit all the styles and interfaces. Secondly, we have an inexpensive textbook and supporting materials we rather like, but all the examples use the old style assembly syntax, which differs significantly from the more modern GCC/LLVM style, and for pedagogical consistency reasons we’d like to write our code in that style.
ARM/Keil have produced a document AN298 – Migrate ARM Compiler 5 to ARM Compiler 6 which covers most of the important details, but it was still a bit of a skilled process.
Some notes:
- For the time being, Keil with the V6 toolchain includes the older
armasm
binary, so separate pure-assembly .s sources written in the old syntax can still be ingested, you only have to port inline assembly. - Keil’s debugger doesn’t appear to be able to keep source lines of inline assembly and the disassembly view synchronized for GCC-style inlined assembly the way it could with
armcc
. Unfortunate, and a bit klutzy for setting breakpoints, but not a deal-breaker. armclang
defines__ARMCC_VERSION
as 6something so various pieces of existing code have pre-processor directives that will decide to use thearmcc
style inline assembly instead of the gcc style ones. Particularly irritating, TI’s first party TivaWare library has this problem in bothcpu.c
andsysctl.c
, so I had to make a hacked version with the#ifdef
s swirled around appropriately. The code in TivaWare intended for IARewarm
is suitable forarmclang
… as long as you remove some spare ewarm-specific pragmas embedded here and there for suppressing return value warnings; I ended up putting-Wno-return-type
in the extended compiler options for projects depending on those files.armclang
is much more aggressive about optimization by default thanarmcc
was. In particular, you could get away without marking variables used in busy wait loops or ISRs volatile in armcc, and armclang will happily optimize them out if you forget.armclang
is more vocal about implicit type conversion thanarmcc
, especially where it might affect signedness. This is triggered a lot by theREGISTER_NAME &= ~0xMASK
bit-specific addressing idiom. I sprinkled in lots ofUL
suffixes on literals to avoid the issue.
Long term we might try to get off of Keil, though my experiences with CodeComposerStudio have been sufficiently frustrating that I’m in no hurry to move to it for the TI TivaC boards we’ve been using, and while I like ST’s Cube environment, it would both be a major change of materials and a potential supply-chain nightmare (when is the last time you saw a legitimate major electronics vendor with STM32 parts in a stock status other than “Expected Date: Eventually”?)