Take advantage of your intrinsics

For hardware-related parts of an application for embedded systems, accessing low-level features is essential. The C programming language is usually a good choice for embedded systems since it is fairly close to hardware and you can relatively easy control the peripherals on the device.

However, sometimes C is not enough and you have to mix C and assembler modules by for example inline an assembler instruction in to your C functions.

int foo() 
{ ...
InitADC();
InitTimer();

/* Enable interrupts */
asm("CPSIE i");

while(1){
CollectData();

asm("NOP");
CalcData();
...
}
}

Inline assembler can be used for inserting assembler instructions directly into a C or C++ function. Typically, this can be useful if you need to access hardware resources that are not accessible in C or you manually have to write a time-critical sequence of code that if written in C will not have the right timing.

An inline assembler statement is similar to a C function in that it can take input arguments (input operands), have return values (output operands), and read or write to C symbols (via the operands). An inline assembler statement can also declare clobbered resources (that is, values in registers and memory that have been overwritten).

Without operands and clobbered resources, inline assembler statements have no interface with the surrounding C source code. This makes the inline assembler code fragile, and might also become a maintenance problem if you update the compiler in the future. A limitation using inline assembler is that the compiler’s various optimizations will disregard any effects of the inline statements, which will not be optimized at all. So as a consequence, inline assembler is often best avoided wherever possible or separated in its own function or module.

A better approach to control the lower levels of the hardware is to use intrinsic functions instead. The compiler in IAR Embedded Workbench provides a few predefined functions that allow direct access to low-level processor operations without having to use the assembler language. These functions are known as intrinsic functions. They can be very useful in, for example, time-critical routines.

An intrinsic function looks like a normal function call, but it is really a built-in function that the compiler recognizes. The intrinsic functions compile into inline code, either as a single instruction, or as a short sequence of instructions, and are marked with a double underscore (__).

To use intrinsic functions in an application, include the header file intrinsics.h.

#include "intrinsics.h"

int foo()
{ ...
  InitADC();
  InitTimer();

  /* Intrinsic function to enable interrupts */
  __enable_interrupt();

  while(1){
  CollectData();

  /* Intrinsic function for NOP */
  __no_operation();
  CalcData();
  ...
} }

In the compiler manual you find a summary of which intrinsic functions that is available for your compiler and a description on how they work.

© IAR Systems 1995-2016 - All rights reserved.