Integer and boolean types to use in an embedded system with two architectures

烂漫一生 提交于 2019-12-11 05:53:12

问题


I'm writing some software for an embedded system, mostly in C. It happens to be a dual core TI platform and I am using a few vendor and other libraries. The processor has one ARM core which is 32-bit and can do byte access (sizeof(char) == 1 and sizeof(int) == 4: 8 and 32 bits respectively) and one C28 core which is a 32-bit CPU with sizeof(char) == sizeof(int) == 1: both are 16-bits (yes, really).

I plan to avoid types such as int and char in favour of always being explicit about what I am doing. I would plan on this anyway, but doubly so when "char" is a bit traitorous and not always 8 bits.

However, I have quite a few sets of integer and booleans definitions (and floats, but let's not worry about them) available to me, depending on exactly how many and which headers I include:

On the ARM side:

<stdint.h> // from the ARM compiler's include dir
typedef   signed char   int8_t;
typedef unsigned char  uint8_t;
typedef          short  int16_t;
typedef unsigned short uint16_t;
typedef          int    int32_t;
typedef unsigned int   uint32_t;
typedef          long long  int64_t;
typedef unsigned long long uint64_t;

On the C28 Side:

<stdint.h> // from the C28 compiler's include dir
typedef          int    int16_t;
typedef unsigned int   uint16_t;
typedef          long   int32_t;
typedef unsigned long  uint32_t;
// note: no uint8_t

On both sides:

// "DSP28_DATA_TYPES" - comes with the following comment:
    // For Portability, User Is Recommended To Use Following Data Type Size
    // Definitions For 16-bit and 32-Bit Signed/Unsigned Integers:
typedef int int16;
typedef long int32;
typedef long long int64;
typedef unsigned long long Uint64;

<xcd/std.h> // "TI_STD_TYPE", also with and xdc_ prefix, presumably for internal use to the XDC framework
typedef int Int;
typedef unsigned Uns;
typedef char Char;
typedef unsigned long Uint32;
typedef unsigned int Uint16;
typedef unsigned char Uint8;
typedef long Int32;
typedef int Int16;
typedef char Int8;

There are also a handful of library-specific versions, such as

typedef char          INT8; // from the NDK network headers
typedef unsigned char u8_t;  // from the uIP network headers

As for booleans, I have

<stdbool.h> // on ARM
<stdbool.h> // on C28
typedef unsigned char bool;

<xdc/std.h> // on both
typedef unsigned short  Bool;       /* boolean flag */

// TI Driver library
typedef unsigned char tBoolean;

// TI Flash access library
typedef unsigned char       boolean;

My gut instinct is to go with <stdint.h> and <stdbool.h> on both sides. This will have the side effect that any headers that I do share between the ARM and C28 core can't use uint8_t. However, this IPC code is very limited and easily dealt with.

On code that runs on only one core, it means I don't need to pull in TI or library headers in cases like this:

// someheader_arm.h
#include <stdint.h> // only need a standard header, not a TI one
#include <stdbool.h>

extern uint8_t getDeviceFooIndex(void);
extern bool    isDeviceFoobared(void);

Which then means I can include like this and prevent forcing the user of the header to have some library header included first, or force visibility of it by adding the library include to my header:

// someimpl_arm.c
#include "someheader_arm.h" // include first of all to ensure that all types are visible to the headers
#include <some_ti_lib.h> // brings in UintN, for example

// main.c
#include "someheader_arm.h" 
#include <some_ti_lib.h> // e.g. needed by main.c functions
// include order doesn't matter - UintN isn't needed by someheader_arm.h

There are places when function signatures for library functions take unsigned long style or UintN style, but it's always fairly clear what's going to what. The main concern is keeping headers like the example above and variables throughout my code tidy and consistent, even if the functions I call from libraries use an exciting range of definitions.

The fact that things like char and int differ radically on the two cores is an interesting quirk, but my question would stand even on a single core processor, I just have even more types floating around than usual!

So the question is: Does it make sense to make the C99 standard headers a general standard in the code and generally disregard the various types provided in libraries?

来源:https://stackoverflow.com/questions/40843225/integer-and-boolean-types-to-use-in-an-embedded-system-with-two-architectures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!