SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: How to make use of the GCC fixed-point types extension on ARM Cortex-M?
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

How to make use of the GCC fixed-point types extension on ARM Cortex-M?

Graham Kruk
Last updated: September 15, 2023 6:42 am
Graham Kruk 7 Min Read
Share
SHARE

The GCC compiler for ARM Cortex-M microcontrollers provides built-in support for fixed-point data types through its fixed-point types extension. This allows developers to use fixed-point math in their C/C++ code instead of floating point, which can provide performance and memory benefits on resource-constrained microcontroller systems.

Contents
What are fixed-point types?GCC fixed-point types for ARM Cortex-MUsing fixed-point math operationsBenefits of fixed-point math on Cortex-MLimitations to considerConfiguration optionsPutting it all together

What are fixed-point types?

Fixed-point types represent real numbers using integers and fractional values. For example, the number 1.5 could be stored as 15, with the decimal point implied between the first and second digit. This differs from floating point representations like float and double which store exponents and mantissas.

The advantage of fixed-point math is that it does not require dedicated floating point hardware, which helps minimize silicon area and power consumption on microcontrollers. Operations on fixed-point values can be performed using standard integer instructions. Additionally, fixed-point representations take up less memory than floats.

GCC fixed-point types for ARM Cortex-M

The GCC compiler includes built-in types for 8, 16, 32 and 64 bit fixed-point math. To use them in your C/C++ code, include the stdint.h header which defines the types:

#include <stdint.h>

The primary fixed-point types are:

  • intFX_t – signed fixed-point types
  • uintFX_t – unsigned fixed-point types

Where FX is the number of integer + fractional bits. For example:

int16_t - 16 bit signed integer 
int32_8_t - 32 bit signed fixed-point with 8 fractional bits
uint48_16_t - 48 bit unsigned fixed-point with 16 fractional bits

Using fixed-point math operations

The fixed-point types can be used directly in code and behave like regular integer types. However, values are interpreted as real numbers based on the placement of the implied decimal point. For example:

int16_8_t a = 20; // Represents 20 / 2^8 = 0.3125
int16_8_t b = 30; // Represents 30 / 2^8 = 0.46875 
int16_8_t c = a + b; // c = 0.78125

Arithmetic operations like add, subtract, multiply, divide will work as expected. Just be mindful of the decimal place when assigning values and interpreting results.

There are also helper functions defined for tasks like conversion between types, rounding, and determining max/min values:

int32_t a = 12345;
int16_8_t b = int32_to_int16_8(a); // b = 123.40625

int64_32_t c = -9876543; 
int32_t d = int64_32_round_to_int32(c); // d = -9876500

This allows seamless integration of fixed and integer types in code. See the gcc documentation for the full list of available functions.

Benefits of fixed-point math on Cortex-M

Here are some of the major benefits of using GCC’s fixed-point types for ARM Cortex-M development:

  • No floating point unit (FPU) required – Fixed-point math works on any Cortex-M core without needing dedicated floating point hardware. This saves silicon area and power.
  • Faster than software floating point – Integer operations are faster than soft-float emulation of floats. Fixed-point math provides a performance boost for many use cases.
  • Smaller code size – Fixed-point code compiles to smaller machine code than floating point equivalents.
  • Less RAM usage – Storing fixed-point values takes half the RAM compared to single-precision floats.
  • Easier debugging – Viewing fixed-point values in the debugger shows the actual number without having to print the bits.
  • Range and precision control – The developer can configure the integer and fractional bits to match their application needs.

For microcontroller projects that need math operations without heavy number crunching, fixed-point provides a nice middle-ground between integers and floats.

Limitations to consider

Fixed-point math has some downsides to keep in mind:

  • Limited precision – There are only so many fractional bits available, restricting precision for very small or very large values.
  • Chance of overflow – Operations can overflow just like regular integer math, so care must be taken.
  • No hardware division – Integer divide instructions are slower than hardware float division units.
  • No native support in C – Requires use of GCC fixed-point extension types vs normal floats.

For applications that need high precision or dynamic range, hardware floating point may be a better option. Complex math-heavy code may also benefit from the precision and speed of floating point units.

Configuration options

GCC provides some configuration options to control the behavior of fixed-point math operations:

-ffixed-point - Enable fixed-point types in C/C++ code.
-fno-fixed-point - Disable fixed-point types.

-muint32-fixed32 - Use 32-bit unsigned fixed-point for "int" type.
-muint64-fixed64 - Use 64-bit unsigned fixed-point for "long long" type.

-msaturated-fixed-point - Saturate results instead of overflowing.
-mno-saturated-fixed-point - Disable saturating behavior.

This allows customizing fixed-point math to meet project needs. The defaults work well for most situations.

Putting it all together

Here is an example demonstrating fixed-point math operations on an ARM Cortex-M7 microcontroller:

#include <stdint.h>

// Function to do fixed-point matrix multiplication 
void matmul_fxp(const int16_8_t *A, const int16_8_t *B, int16_8_t *C, int n) {

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      int32_t sum = 0;
      for (int k = 0; k < n; k++) {
        // 32-bit accumulation to prevent overflow  
        sum += A[i*n + k] * B[k*n + j]; 
      }
      C[i*n + j] = int32_to_int16_8_round(sum);
    }
  }

}

int main() {

  int16_8_t A[9] = {1, 2, 3, 
                     4, 5, 6,
                     7, 8, 9};

  int16_8_t B[9] = {9, 8, 7,  
                     6, 5, 4,
                     3, 2, 1};

  int16_8_t C[9];

  // Call fixed-point matrix multiplication                  
  matmul_fxp(A, B, C, 3); 

  return 0;

}

This performs the matrix math using only fixed-point types. The int32_t accumulator prevents overflow, and the results are rounded to the target 16.8 fixed-point format.

With GCC’s fixed-point extension, developers can build high-performance math-centric applications for ARM Cortex-M without the need for a floating point unit.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Does cortex M0 have floating point?
Next Article Fixed-point calculation using CMSIS library
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

Practical guidelines for ARM on FPGAs

Implementing ARM processors on FPGAs can enable powerful and flexible…

7 Min Read

What is the performance of the ARM Cortex-M0?

The ARM Cortex-M0 is an ultra low power 32-bit microcontroller…

5 Min Read

What is the difference between link register and stack?

The link register and stack are two important concepts in…

8 Min Read

Why Cortex-M Requires Its First Word as Initial Stack Pointer?

The Cortex-M processor is an extremely popular 32-bit ARM processor…

6 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account