Why I Started Using This Tool

With build, deploy, and F5 debugging all working, it was finally time to write application code. The first task I wanted was a simple heartbeat, and its header needed a thread handle, an on/off flag, an interval, and a return code. That's where I hit the first question: what type is each of those? Plain int is "whatever size this compiler likes", and I didn't want to guess. So before any task, I wrote one small shared header, types.h, that every other file in the project includes.

What It Does

Here's the whole file:

#ifndef TYPES_H
#define TYPES_H

#include <stdint.h>

typedef int32_t   INT32;
typedef uint32_t  UINT32;
typedef uint8_t   BOOLEAN;

#define TRUE   1
#define FALSE  0

#endif /* TYPES_H */

The include guard

#include literally copy-pastes a header into your file. Since almost every file will include types.h, sometimes indirectly through another header, it's easy for it to get pasted in twice, and then the compiler complains that INT32 is defined twice. The guard reads like this: "if TYPES_H isn't defined yet, define it and keep going. If it already is, skip everything down to #endif." The first include gets the content, and every one after that gets nothing. The name is just a convention: the file name in capitals with . turned into _.

Exact sizes from <stdint.h>

<stdint.h> is the standard header that gives you exact-size integers: int32_t is always 32 bits and signed, uint32_t is always 32 bits and unsigned, and uint8_t is always 8 bits, on every compiler. That matters in embedded work, where you often care exactly how many bits a value takes, for example when it maps onto a hardware register.

Why my own names on top

INT32, UINT32, and BOOLEAN aren't part of C. They're just shorter aliases for the stdint.h types, in a style you see a lot in embedded code: the size is right there in the name, in capitals, so it stands out when you read a struct. If you prefer the plain uint32_t names, that's completely fine. The important part is using exact-size types consistently, not what you call them.

BOOLEAN, TRUE, and FALSE

BOOLEAN is a one-byte unsigned value, with TRUE and FALSE as 1 and 0. Modern C also has bool from <stdbool.h>, which would work too. I went with the explicit one-byte type so I know exactly how big it is. One habit worth keeping: test a flag with if (flag), not if (flag == TRUE), because any non-zero value counts as true in C.

Where it gets used next

The very next header, swalive.h for the "SW is alive" task, includes "types.h" for its running flag, its interval, and its return code. Quotes in the include mean "look in my project folder first", unlike the angle brackets on <stdint.h>, which mean "a system header".

Final Verdict

It's the smallest file in the project, but it's the one everything else stands on. Every struct and function signature from here on says exactly how big its values are, and the include guard means any file can include it without worrying about who included it first. If you're starting an embedded C project, I'd write this header before anything else. It takes two minutes and saves you from ever wondering how big an int is on your board.