Illustrating machine storage classes

This recipe illustrates a version of addTwoNums that uses the machine storage classes, int32_t and uint8_t. We explain why it is advantageous for embedded applications to define and use these as opposed to the primitive types that are provided by the C language.

How to do it…

To define and use machine storage classes, please follow the outlined steps:

  1. Create a new folder named addTwoNums_v2 by cloning the previous project.
  2. Copy the addTwoNums.c file from the previous recipe to the folder and modify it as follows:
    int main (void) {
      
      int32_t input;
      uint8_t num1, num2, res;
    
      HAL_Init ();   /* Init Hardware Abstraction Layer */
      SystemClock_Config ();           /* Config Clocks */
    
      SER_Init();
      
        for (;;) {                      /* Loop forever */
        printf("Enter First Number: ");
        scanf("%d", &input);
        num1 = (uint8_t) input;
        printf("Enter Second Number: ");
        scanf("%d", &input);
        num2 = (uint8_t) input;
        res = num1 + num2;
        printf("Result = %d 
    ", res);
      }
    }
  3. Add the Serial.c, Serial.h, Retarget.c and addTwoNums.c files to the project.
  4. Connect the evaluation board's UART 1/2/3 9-pin D-type connector to the PC's COM port.

Invoke PuTTY and configure the port as we did in Chapter 2, C Language Programming.

  1. Remember to check the Use MicroLIB project option.
  2. Build the project; download and run the program (please note that you may need to reset the evaluation board).
  3. Check that the program behaves as before.

How it works…

The size of signed and unsigned integers that a microprocessor can manipulate is determined by its low-level architecture. The Cortex-M3 and -M4 microcontrollers are based on the ARMv7-M architecture (refer to ARMv7-M Architecture Application Level Reference Manual). Part A of the manual details the application-level architecture and programmers' model, and it begins by summarizing the core data types and arithmetic operations. ARMv7-M processors support the following data types in memory:

Byte

8-bit

Halfword

16-bit

Word

32-bit

The manual explains that processor registers are 32 bits in size, and the instruction set supports the following data types:

  • 32-bit pointers
  • Unsigned or signed 32-bit integers
  • Unsigned 16-bit or 8-bit integers (held in zero-extended form)
  • Signed 16-bit or 8-bit integers (held in sign-extended form)
  • Unsigned or signed 64-bit integers held in two registers

It also describes the binary format that is used to store these quantities and provides a pseudo-code description of how addition and subtraction are performed. This description is consistent with the results that we got with the recipe, addTwoNums_c3_v0. The pseudo-code uses the terms zero-extended and sign-extended to describe how 8- and 16-bit numbers are stored in the 32-bit registers of the Cortex-M architecture. This is important as the processor status-register bits reflect the result of 32-bit arithmetic, and so, 8- and 16-bit values must be appropriately extended to fill the whole 32-bit register so that the sign and overflow bits correctly reflect the result of operations on shorter word lengths.

Implementations of C standard data types, such as char, short int, int, long int, and so on, depend on the (machine-specific) compiler implementation. You may recall that the C standard only specifies they must be at least a certain size. Apply italics to (at least). This can be a problem for embedded system programs that need to be ported between architectures with particular sizes of storage. Luckily, C provides a mechanism called typedef to create new types that are aliases of existing types. The C Standard Library includes stdint.h, containing C type definitions that can be customized for the different target architectures. The stdint.h header is included in stm32F4xx_hal.h, so there is no need to include it again in our program. A typedef keyword in the stdint.h header defines the following machine storage classes:

    /* exact-width signed integer types */
typedef   signed           char int8_t;
typedef   signed short     int int16_t;
typedef   signed           int int32_t;
typedef   signed       __int64 int64_t;

    /* exact-width unsigned integer types */
typedef unsigned           char uint8_t;
typedef unsigned short     int uint16_t;
typedef unsigned           int uint32_t;
typedef unsigned           int64 uint64_t;

If we require that an integer be represented in exactly N bits, then we use one of the following types:

signed:

int8_t

int16_t

int32_t

int64_t

unsigned:

uint8_t

uint16_t

uint32_t

uint64_t
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.105.159