- Important information
- New features
- Known problems
- Program corrections
- User guide corrections
- Miscellaneous
- Release history
Important information
- IAR Embedded Workbench for Arm 9.30 uses an updated version of
arm_mve.h
.- The new version can be included from both C and C++ (the version used in 9.20 could only be included from C).
- The new version does not affect the status of IAR extensions (the version used in 9.20 always enabled IAR extensions).
-
The names of the built-in MVE intrinsics have been updated to match the new
arm_mve.h
. As long as your application only uses the publicly visible names (the ones defined inarm_mve.h
) nothing changes, but if you refer directly to the built-in intrinsic functions, you must adapt to the new names.
- Limitations of compiler support for Armv8.1-M
There are some limitations to the support for Armv8.1-M:
- MVE: The Cortex-M vector extension can be utilized by means of intrinsic functions.
There is currently no support for auto-vectorization. The header filecannot be included from C++ code. Some optimizations of MVE code are missing, in particular when a VCMP instruction is followed by VPST they should be combined into a VPT instruction. - LOB: Limited matching of low-overhead loops.
A candidate loop must have a loop counter that is counted down by 1 until it reaches zero. The presence of an outer loop can lead to an inner loop not being matched. Other optimizations (most notably loop unrolling) can lead to a loop not being matched. - CMSE: The Armv8.1-M register FPCXT_NS is not restored by a non-secure entry function.
- _Float16: Some operations on _Float16 (such as plus and minus) are implemented by converting the input operands to float, using the corresponding instruction for float, and converting the result to _Float16.
- The conditional instructions from Armv8-A are not utilized (CSEL, CSET, CNEG).
- MVE: The Cortex-M vector extension can be utilized by means of intrinsic functions.
- Characteristics for the toolset in AARCH64 mode:
- The toolset, by default, supports generating code and data that is situated in one space that has a maximum size of 4 Gbytes. This is because static data will be accessed with an addressing mode that reaches +/- 4 Gbytes. Mechanisms exist to jump/call between such spaces.
- The produced code, by default, runs in execution state EL1.
Limitations:
- Big-endian code is not supported.
- Position-independent code is not supported.
- Compiler MISRA C C:1998/C:2004 support is removed in version 9.10
The Compiler MISRA C is still available through the compiler command line but will be removed in a future release.
Refer to IAR C-STAT for full MISRA C support. - Changes in implementation of CMSIS intrinsics in version 8.20
The implementation of the CMSIS intrinsic interface is no longer based on IAR's intrinsics.h. As a consequence of that some intrinsics that was previously declared when the CMSIS header was included are no longer declared.
Examples of these intrinsics include __LDREX(), __STREX() and __enable_interrupt().
- Changed size of wchar_t in version 8.10 and later
Object files following the ARM ABI has a runtime attribute indicating the size of
wchar_t
.In EWARM version 7.80 and earlier, the size of
wchar_t
was 2 bytes wide and the runtime attribute was set accordingly.In EWARM version 8.10 and later,
wchar_t
is 4 bytes wide. -
If you have implemented the
time()
function, you must rename it into__time32()
. For more information see the Development guide. -
A special note on CMSIS integration:
If your application source code includes CMSIS header files explicitly, then you should not select Project>Options...>General Options>Library Configuration>Use CMSIS. Some of the Cortex-M application examples include CMSIS source files explicitly. Do not select the option Use CMSIS in these projects.
Deprecated features in version 7.60
-
--interwork
Future versions of the IAR C/C++ Compiler for ARM will assume
--interwork
when generating code for the ARMv4T architecture. There will be no option to generate non-interworking code for ARMv4T.
-
New features
The Zephyr kernel 4.1 or later can now be built with the IAR build tools for Arm
All files needed for a customer to build Zephyr with IAR tools are up-streamed and available in the Zephyr repository, this also includes build scripts. There is an IAR specific toolchain page on how to setup the tools.
Limitations:
- C++ is not supported
- Userspace is not supported
- 64-bit is not supported
- On optimization levels Medium and High, the compiler will mark module and function local variables with static storage duration that are neither written nor have their address taken as read-only, to allow them to be placed in ROM.
- The product will no longer generate DWARF .debug_types sections. This should increase compatibility with certain versions of GDB.
Language extension option
The compiler has a new option--language ext,ext,...
that specifies which language extensions that are enabled during the compilation. The available extension areextended
(IAR extensions) andgnu
(GNU C/C++ extensions). Using--language extended
is identical to the-e
option. The#pragma language
directive also supports the newgnu
extension mode.- Additional support for GCC extensions
- Additional support for GCC attributes:
__attribute__((nonnull))
__attribute__((noinit))
__attribute__((hot))
__attribute__((cold))
__attribute__((cleanup))
- Conditionals with Omitted Operands, e.g.,
x ? : y
- ILINK support for
--wrap
option - A local variable can be placed in a specific register using
#pragma location=reg
,@ reg
, orregister ... asm("reg")
. - New compiler option
--function_sections
that has the same behavior as the GCC option-ffunction-sections
. - Additional support for GCC-like
__builtin
function calls. Added functions are:__builtin_constant_p
__builtin_inf
,__builtin_inff
, and__builtin_infl
__builtin_huge_val
,__builtin_huge_valf
, and__builtin_huge_vall
__builtin_sadd_overflow
__builtin_saddl_overflow
__builtin_saddll_overflow
__builtin_uadd_overflow
__builtin_uaddl_overflow
__builtin_uaddll_overflow
__builtin_ssub_overflow
__builtin_ssubl_overflow
__builtin_ssubll_overflow
__builtin_usub_overflow
__builtin_usubl_overflow
__builtin_usubll_overflow
__builtin_smul_overflow
__builtin_smull_overflow
__builtin_smulll_overflow
__builtin_umul_overflow
__builtin_umull_overflow
__builtin_umulll_overflow
__builtin_add_overflow
(partial support)__builtin_sub_overflow
(partial support)__builtin_mul_overflow
(partial support)__atomic_thread_fence
__atomic_signal_fence
__sync_synchronize
__builtin_return_address
(partial support)
- The compiler accepts the keyword
__asm__
in all modes. It behaves exactly like the already supported keyword__asm
. - The compiler accepts multiple optimization options. The last specified option on the command line is the one that is used.
- Support for selected C++20 features
The following C++20 features are supported:
- Concepts (including abbreviated function template declarations)
- Three-way comparison (a.k.a. spaceship) operator
<=>
constinit
andconsteval
constexpr
relaxations- virtual function
- try-catch block
dynamic_cast
and polymorphictypeid
- changing the active member of a union
- transient allocation
- trivial default initialization
constexpr
intrinsics: unevaluatedasm
-declarations andstd::is_constant_evaluated
- Lambdas
- Default constructible and assignable stateless lambdas
- Lambdas in unevaluated contexts
- Template syntax for generic lambdas
explicit (bool)
typename
optional in more contextsstd::bit_cast, std::type_identity
andstd::remove_cvref
- The predefined preprocessor symbol
__cplusplus
still says201703L
(C++17) but individual feature testing macros are updated according to supported level. - Even though
constexpr
transient allocation is supported,std::string
andstd::vector
are not yet supported in constant expressions. - Libc++ does not support
std::strong_ordering
with long double until version 19. - Partial ordering of rewritten operator candidates resulting from constrained templates are not supported.
- New C23 features
- Standard attribute syntax:
[[attr]]
__has_c_attribute
in preprocessor conditionals- Support for the standard attributes
[[deprecated]]
,[[nodiscard]]
,[[maybe_unused]]
,[[fallthrough]]
and[[noreturn]]
- Support for alloca and vla on the stack
- The compiler implements
alloca()
and__builtin_alloca()
for allocating a chunk of the stack for the rest of the function. - By default C99 variable lenght arrays are now allocated op the stack instead of the heap.
- NOTE THAT calls to
alloca()
and variable length arrays CAN NOT both be used in the same function and the combination will generate a compilation error. - Improved semihosting support
- To support reading command line parameters using semihosting,
use linker option
--keep __iar_argc_argv
: this is useful for example with qemu. - To support qemu-specific handling of exit status for 32-bit Arm.
use linker option
--redirect __exit=__qemu32_exit
. - For 64-bit Arm the semihosting implementation already supports passing an exit code in a way that works with both C-SPY and qemu.
The trigonometric functions
sin(), cos()
, andtan()
(IEEE 754, single-precision only) have been greatly improved in terms of speed, size, and accuracy.
Known problems
-
[EWARM-13931] A transformation in the compiler that marks non const-declared data that are initialized but after that only read as read only, can cause speed regressions on targets with low flash bandwidth, such as early versions of Cortex-M7.
Workaround: Turn off the transformation using the command line option --no_auto_ro_placement
-
[EWARM-13885] The ADR.N instruction cannot be used to take the address of a local label in inline assembler. The instruction requires the label to be 4-bytes aligned:
- in THUMB mode, a local label is odd, so it is never 4-bytes aligned
- if we subtract 1 from the label to compensate for the THUMB bit, we still cannot be sure that the label is 4-bytes aligned, because we do not know if the start of the inline assembler statement is 4-bytes aligned
For most Arm cores it is possible to use ADR.W instead, but for Cortex-M0 (and other baseline Cortex-M, such as Cortex-M1 and Cortex-M23) this is not possible.
Workaround: For mainline Cortex-M, use "ADR.W". For baseline Cortex-M, no reliable workaround is available.
-
[EWARM-13687, TPB-3934] The compiler does not generate step points correctly for C++17 if and switch statements with initializers, which prevents setting a breakpoint on the initializer in such statements.
Workaround: Do not use if and switch statements with initializers.
-
[EWARM-13138] In some cases when generating optimized Thumb2 code, a compare with zero is generated to examine the result of an ADD instruction even though only the Z and N flags are used. This should be better optimized. The corresponding optimized code should use an ADDS instruction, to replace both the ADD instruction and the compare.
-
The functions strcoll and wcscoll which compare two strings based on the collation strategy of the current locale can have incorrect results.
#include <stdio.h> #include <string.h> #include <wchar.h> #include <locale.h> int main(void) { setlocale(LC_COLLATE, "sv_SE.utf8"); if(wcscoll(L"å", L"ä") < 0) { printf("correct\n"); } else { printf("wrong\n"); } if(strcoll("å", "ä") < 0) { printf("correct\n"); } else { printf("wrong\n"); } }
This example produces the following output:
wrong wrong
-
[EWARM-12792, TPB-3881] The compiler does not emit a warning for uninitialized variables in relation to structs. This is a known limitation of the uninitialized variable analysis.
-
The compiler can generate incorrect debug information for a variable that is changed locally in an isolated part of the user application, if that part ends with an early return and if the variable is put in a different register in this part than in the rest of the application. The code snippet below can trigger the problem, so that the debug information will contain the wrong location for broken from line 14 and onward.
float g(void); void barrier(void); int f(int v2) { float broken = 0.0f; switch (v2) { case 0: broken = g(); barrier(); return 5; case 1: broken = g(); } if (broken > 0.0f) return 1; return 0; }
-
static_cast conversions can erroneously try to use a user-defined conversion function instead of downcasting. This can lead to incorrect code being generated.
For example:
struct V { template <typename T> operator T() { return {42}; } }; struct J : V {}; void f() { auto v = V{}; static_cast<J const&>(v); // Error, tries to use T() for conversion which leads to type mismatch }
-
[EWARM-11621, TPB-3808] When using malloc or calloc to request heap memory of a size close to the full representational range of the size_t type, for example, 0xFFFF'FFFF bytes on a 32-bit architecture or 0xFFFF bytes on a 16-bit architecture, the request fails if no such continuous space is available (which is usually the case). However, input values are processed, for example, word-aligned, before the requested heap space is allocated. As a result, an enormously large input value can wrap around and become tiny, so that the request is accepted instead. This behavior is considered a bug.
The bug shows only in projects that use the no-free heap implementation, that is, using the option --no_free_heap, and particularly when heap storage is requested (using malloc or calloc) with a size close to the full representational size of a size_t type. (To be precise, any heap storage request larger than the full representational range of a size_t type minus the architecture's maximum alignment size is affected by the bug.)
The program correction is that malloc and calloc now check for integer overflows. If a memory request results in an integer overflow, these functions return a null pointer.
Workaround: Use an alternate heap handler such as --basic_heap or --advanced_heap
-
[EWARM-11455, TPB-3789] The compiler is sometimes too conservative and keeps temporary variables that could be removed. This can cause temporary variables to be used for copying, even when none is needed. The generated code is still correct, however not optimal.
Workaround: There is no known workaround for this problem.
-
[EWARM-11283] The GCC C extension __auto_type is not supported for variable-length arrays (VLA).
-
[EWARM-10949, TPB-3746] On optimization level High, the compiler can generate incorrect code for functions that contain local variables with static storage duration, if they call a small function in the same module that in turn can call a function declared as noreturn. In the triggering example below, an indeterminate value will be written to the variable idx at the end of the function.
int *f(int x); void __attribute__((noreturn)) fail(void); static inline void check(_Bool condition) { if (!condition) fail(); } void g(int a, int b) { static int idx = 0U; int* pA = f(idx); check(pA != 0); *pA = a; if (b != 0) ++idx; }
Workaround: Prevent inlining of small functions that contain calls to functions declared as noreturn. Either use the #pragma optimize=no_inline directive, turn off inlining for the entire module, or reduce the optimization level to Medium or lower.
-
[EWARM-10849, TPB-3738] #pragma data_alignment cannot be used to specify alignment on an anonymous structure or union.
Workaround: Use the _Alignas keyword on one of the members.
-
[EWARM-10377] When running, the compiler uses both a compiler and a linker license slot.
-
[EWARM-9298] In some cases, when using NEON intrinsics with vector parameters, the compiler might generate an internal error.
Workaround: If an internal error is caused by the usage of a Neon intrinsic, it can in some cases help to switch to an optimization level higher than None.
-
[EWARM-7572, EWARM-8763, TPB-3377] The compiler can be extremely slow when compiling code that contains structs with hundreds of fields.
Workaround: Avoid structs with many fields.
-
[EWARM-6667, TPB-3086] The compiler can cluster variables that are initialized by copy and zero-initialized variables with static storage duration. When the total size of the variables initialized by copy is small compared to the total size of the zero-initialized variables, and if compressed initializers are not used, this can create a significant size overhead.
Workaround: Specify use of compressed initializers in the linker configuration file or turn off static clustering on the module.
-
[EWARM-5239, EW25660] Passing a parameter of type va_list to a C++ function, where the caller is defined in one object file and the callee in another, will result in a linker error if one of the two objects is built with EWARM 7.20 (or newer) and the other is built with EWARM 7.10 (or older).
-
[EWARM-4824, EW24720] MISRA-C:2004 rule 9.1 will not find all used uninitialized local variables.
-
[TPB-3891] When compiling a source file as UTF-8 (either via the --source_encoding utf8 option or if the source file is saved as in UTF-8 encoding with a Byte-Order Mark) the compiler does not produce a warning for Unicode characters related to CVE-2021-42694.
See also TPB-3890 -
[TPB-3890] When compiling a source file as UTF-8 (either via the --source_encoding utf8 option or if the source file is saved as in UTF-8 encoding with a Byte-Order Mark) the compiler does not produce a warning for Unicode characters related to CVE-2021-42574.
See also TPB-3891 -
[TPB-3817] When writing to bitfields in a volatile context, the compiler emits a read and a write of the underlying storage unit. This happens even if the bitfield has the same size as the type, for example, int a_member:32.
Workaround: When using a bitfield that has the same size as the type, the bitfield size specifier could be removed. For example `int a_member:32` could be rewritten `int a_member`.
Program corrections
-
[EWARM-13750, TPB-3926] The IAR assembler does not allow more than ten levels of nested includes.
-
[EWARM-13461] The optimizer can in some cases enter an infinite loop when trying to normalize large commutative expressions. This triggers an internal error.
-
On optimization level High, the compiler can generate incorrect code when compiling code like the one below. The triggering conditions are:
- a small function that returns an arithmetic expression of its parameter and a constant
- another function with multiple calls to this function with the same parameter each time
- at least two of these values are compared to different constants in the same if statement.
The result is that the test and the code for the second test are removed by the compiler.
int foo(int arg) { return arg - 10; } int test_func(int arg) { int var1 = foo(arg); int var2 = foo(arg); /* Comparison with any valid integer values */ if(var1 == 1) { return 111; } else if(var2 == 2) { return 112; } else { return 113; } }
-
[EWARM-13334, TPB-3900] On optimization level High, the compiler can generate incorrect code for loops where the loop variable is used to index an array. The error can occur on targets that have a combined load and increment-pointer instruction if this instruction is generated by the compiler. The observed effect is that accesses to this loop variable are erroneously removed in the generated code.
-
[EWARM-13278] For an inline assembler statement that contains a literal pool load without a size specifier (LDR Rt,=expr), an error message "Expression out of range" is reported if:
- code is generated in Thumb mode for a Thumb2-capable core
- the load is to a low register (R0 to R7) and
- the inline assembler statement is too large to place the literal pool value within in range for a narrow (16-bit) LDR instruction.
The expected behavior is that a wide (32-bit) LDR instruction should be used: this behavior can be enforced by specifying the instruction width using LDR.W.
-
[EWARM-13111, TPB-3905] Because the IAR compiler generates DWARF .debug_types sections, there can be compatibility issues with some versions of the GNU Debugger (GDB).
-
[EWARM-13081, TPB-3892] On optimization level High, the compiler can generate code where the condition of a loop is tested twice at the first iteration, if the loop variable is of pointer type. The generated code is correct but sub-optimal.
-
When generating position-independent code and read-only data (--ropi) for 32-bit Arm, using some library functions will in some configurations result in a linker error, Lt041: Absolute relocation to movable block.
- Using any of these library functions with --ropi will always result in Lt041:
- lgammaf, lgamma, lgammal, tgammaf, tgamma, tgammal
- Using any of these library functions with --ropi will result in Lt041 in configurations
with an FPU:
- logf, log10f, log1pf, log2f, acoshf, asinhf, atanhf, expf, exp2f, expm1f, coshf, sinhf, tanhf, erfcf
- Using any of these library functions with --ropi will result in Lt041 in configurations
with an FPU with support for double precision:
- log, logl, log10, log10l, log1p, log1pl, log2, log2l, acosh, acoshl, asinh, asinhl, atanh, atanhl, exp, expl, exp2, exp2l, expm1, expm1l, cosh, coshl, sinh, sinhl, tanh, tanhl, erfc, erfcl
Note that indirect use is also affected, in particular these routines for complex numbers:
- cacoshf, cacosh, cacoshl, casinhf, casinh, casinhl, cpowf, cpow, cpowl, ctanf, ctan, ctanl, ctanhf, ctanh, ctanhl, catanhf, catanh, catanhl, clogf, clog, clogl, clog10f, clog10, clog10l
- Using any of these library functions with --ropi will always result in Lt041:
-
[EWARM-12748, TPB-3876] Compiling extremely large and deep expressions can take much longer than expected, in particular on optimization levels Low and None.
-
In some situations, the compiler might register a local temporary in the wrong scope, causing an internal error. This can occur in situations where aggregate initialization is performed on a class with an array field of aggregate type that is implicitly initialized, and the aggregate type contains dynamic initialization via—for example—a default member initializer.
Example:
struct S { S(int const & e); }; struct SubAggr { S flags{0}; }; struct AggrWithArray { SubAggr elems[1]; }; AggrWithArray arr{}; // Internal Error
-
In C++ source code, if the first member of a class/struct is initialized by default and the member is of class/struct type with a defined destructor, the compiler might generate the internal error [symbol_lookup_M31: ... <mangled name of destructor> ... . For example, the following code would generate such an internal error:
struct A { A(); ~A() = default; // This is the destructor that the error message refers to }; struct B { A member1{}; // This is the initialization that triggers it A member2; }; void UseObject() { B(); }
-
[EWARM-11959] The implementation of __iar_argc_argv included in the semihosting library uses IAR extensions to the semihosting interface.
See also EWARM-11958 -
[EWARM-11958] Enabling semihosting on the linker command line or in the Embedded Workbench IDE Project>Options dialog box does not add support for command line parameters.
See also EWARM-11959 -
[EWARM-11953, TPB-3795] A static_assert on an "==" comparison between two floating-point constants (a GCC and MSVC extension) incorrectly produces Error[Pe031]: expression must have integral type.
-
[TPB-3910]
The compiler can exit with an internal error when compiling for a big-endian target, and the code contains a struct or union that contains a character array of size 4 or 8, and the array is indexed by an expression that contains the array size subtracted by a variable. This example code triggers the problem:
union U { unsigned char a[8]; }; int f(void) { union U u = {0,1,2,3,4,5,6,7}; int i = 1; return u.a[8U - i]; }
-
[TPB-3896]
The compiler triggers an internal error when accessing and modifying different union fields in a code sequence like the one in the example below.
typedef union { int value; volatile int *p; } type_punning; int temp[1]; int main ( void ) { type_punning un; un.p = temp; int i = 0; while ( i++ < 4 ) { // The order of the following operations is not important *un.p; // Indirect access through some union field --un.value; // Read modify write operation in another field } return (0); }
The combination of these conditions triggers the problem:
- The main operation involved is a read-modify-write in a variable
- Type punning is performed with the use of a union
- The optimization level is High
- A small, static loop bound, for example, 2 - 8 iterations, is used.
-
[TPB-3836] In C++, a comparison of two pointers (or the address of a variable and a pointer) of different sizes may be performed with a truncated value of the larger-sized pointer, which can lead to the wrong result of the comparison.
User guide corrections
- None.
Miscellaneous
-
Available workarounds for device erratas:
-
CVE-2024-0151
Security weakness in PCS (Procedure Call Standard) for CMSE (Cortex-M security extensions).
The weakness in the PCS is that the 32-bit AEABI specifies that it is the callers responsibility to extend small arguments to register width, and that it is the callees responsibility to extend small return values to register width for CMSE this is handled as follows:
- small arguments are extended in prolog of non-secure entry functions
- small return values are extended at call-site after return from non-secure call
"small" in this context are values of `char` or `short` type, or enum or wide-characters if they are represented in either 8 bits or 16 bits.
More information is available on developer.arm.com.
In EWARM 9.50.4 and later, the compiler avoids this vulnerability. -
CVE-2021-35465
A VLLDM instruction Security Vulnerability affects Arm Cortex-M33 r0p0 to r1p0, Arm Cortex-M35P r0, Arm Cortex-M55 r0p0 to r1p0, and Arm China STAR-MC1 (STAR SE configuration).
On these processors, any Armv8-M Secure software that uses FPU or Helium instructions and that calls Non-secure functions might be affected.
In EWARM 9.20.1 and later, the compiler avoids this vulnerability. The workaround is enabled by default, but can be disabled using the command line option --enable_hardware_workaround no-fix-cmse-cve-2021-35465. -
ARM Cortex-M3 errata 463764
Core might freeze forSLEEPONEXIT
single instructionISR
. More information is available on infocenter.arm.com.
Workaround generated for functions with attribute__irq
withiccarm --enable_hardware_workaround=arm463764
. Supported from EWARM 5.41. -
ARM Cortex-M3 errata 602117
LDRD
with base in list might result in incorrect base register when interrupted or faulted. From EWARM 5.20.3 the compiler/library avoids theLDRD
instruction with the base register in list. -
ARM Cortex-M3 errata 752419
ARM Cortex-M4 errata 752770
Interrupted loads toSP
can cause erroneous behaviour. From EWARM 6.21 the compiler/library does not generateLDR SP
instructions with writeback toRn
. Otherwise we allow the extra reads because the stack resides in RAM where multiple reads are acceptable. -
ARM Cortex-M4 errata 776924
VDIV or VSQRT instructions might not complete correctly when very short ISRs are used. IAR recommends the second workaround proposed by Arm: "Ensure that every interrupt service routine contains more than 2 instructions in addition to the exception return instruction." The background is that the compiler is unaware of interrupts since the Cortex-M architecture does not distinguish between ordinary functions and interrupt functions. -
ARM Cortex-M7 errata 833872
Flag setting instructions inside an IT block might cause incorrect execution of subsequent instructions. From EWARM 7.40, the compiler will the skip the IT transformation on this particular code pattern. -
ARM Cortex-M3 errata 838469
ARM Cortex-M4 errata 838869
Store immediate overlapping exception return operation might vector to incorrect interrupt. Follow the guidelines in the errata and implement the workaround proposed by ARM by using__DSB(void)
in applicable cases. -
Functional problem Core.1 in NXP device LPC2478: Incorrect update of the Abort Link register in Thumb state.
Workaround generated withiccarm --enable_hardware_workaround=NXP_Core.1
-
Functional problem in Stellaris devices: Non-word-aligned write to SRAM can cause an incorrect value to be loaded. More information is available on the Stellaris web site at www.ti.com/stellaris.
Workaround generated withiccarm --enable_hardware_workaround=LM3S_NWA_SRAM_Write
-
Functional problem in Freescale Semiconductors MC9328MX1 (i.MX1), masks 0L44N, 1L44N, and 2L44N:
TheLDM
instruction will in some cases not load the second register correctly. Workaround generated withiccarm --enable_hardware_workaround=920t-ldm2
NOTE: The libraries in the current EWARM version are not built with this workaround. Use EWARM 6.50.6 and linker option--enable_hardware_workaround=920t-ldm2
to use libraries built with this hardware workaround.
-
-
RTOS Threads and TLS
The inc\c\DLib_Threads.h header file contains support for locks and thread-local storage (TLS) variables. This is useful for implementing thread support. For more information, see the header file.
-
va_args
The implementation of
va_args
functions has changed in IAR Embedded Workbench for ARM 7.20.1. It is no longer possible to compile the output of the preprocessor from an earlier version of the compiler. The original source code must be preprocessed again, using IAR Embedded Workbench for ARM 7.20.1.
Release history
-
See release history.