UnityConfigurationGuide.md 17.8 KB
Newer Older
D
Deryew 已提交
1
# Unity Configuration Guide
T
toby 已提交
2 3

## C Standards, Compilers and Microcontrollers
4

T
toby 已提交
5
The embedded software world contains its challenges. Compilers support different
6 7 8
revisions of the C Standard. They ignore requirements in places, sometimes to
make the language more usable in some special regard. Sometimes it's to simplify
their support. Sometimes it's due to specific quirks of the microcontroller they
T
toby 已提交
9 10
are targeting. Simulators add another dimension to this menagerie.

11 12 13 14
Unity is designed to run on almost anything that is targeted by a C compiler. It
would be awesome if this could be done with zero configuration. While there are
some targets that come close to this dream, it is sadly not universal. It is
likely that you are going to need at least a couple of the configuration options
T
toby 已提交
15 16
described in this document.

17 18 19 20 21
All of Unity's configuration options are `#defines`. Most of these are simple
definitions. A couple are macros with arguments. They live inside the
unity_internals.h header file. We don't necessarily recommend opening that file
unless you really need to. That file is proof that a cross-platform library is
challenging to build. From a more positive perspective, it is also proof that a
D
Deryew 已提交
22
great deal of complexity can be centralized primarily to one place to
T
toby 已提交
23 24
provide a more consistent and simple experience elsewhere.

25 26 27 28 29

### Using These Options

It doesn't matter if you're using a target-specific compiler and a simulator or
a native compiler. In either case, you've got a couple choices for configuring
T
toby 已提交
30 31
these options:

32 33 34 35 36 37 38 39
1. Because these options are specified via C defines, you can pass most of these
options to your compiler through command line compiler flags. Even if you're
using an embedded target that forces you to use their overbearing IDE for all
configuration, there will be a place somewhere in your project to configure
defines for your compiler.
2. You can create a custom `unity_config.h` configuration file (present in your
toolchain's search paths). In this file, you will list definitions and macros
specific to your target. All you must do is define `UNITY_INCLUDE_CONFIG_H` and
T
toby 已提交
40 41
Unity will rely on `unity_config.h` for any further definitions it may need.

42

T
toby 已提交
43 44 45
## The Options

### Integer Types
46 47 48 49 50 51 52 53 54

If you've been a C developer for long, you probably already know that C's
concept of an integer varies from target to target. The C Standard has rules
about the `int` matching the register size of the target microprocessor. It has
rules about the `int` and how its size relates to other integer types. An `int`
on one target might be 16 bits while on another target it might be 64. There are
more specific types in compilers compliant with C99 or later, but that's
certainly not every compiler you are likely to encounter. Therefore, Unity has a
number of features for helping to adjust itself to match your required integer
T
toby 已提交
55 56
sizes. It starts off by trying to do it automatically.

57

T
toby 已提交
58
##### `UNITY_EXCLUDE_STDINT_H`
59 60

The first thing that Unity does to guess your types is check `stdint.h`.
D
Deryew 已提交
61
This file includes defines like `UINT_MAX` that Unity can use to
62 63 64 65
learn a lot about your system. It's possible you don't want it to do this
(um. why not?) or (more likely) it's possible that your system doesn't
support `stdint.h`. If that's the case, you're going to want to define this.
That way, Unity will know to skip the inclusion of this file and you won't
T
toby 已提交
66 67 68 69 70
be left with a compiler error.

_Example:_
        #define UNITY_EXCLUDE_STDINT_H

71

T
toby 已提交
72
##### `UNITY_EXCLUDE_LIMITS_H`
73 74 75

The second attempt to guess your types is to check `limits.h`. Some compilers
that don't support `stdint.h` could include `limits.h` instead. If you don't
T
toby 已提交
76 77 78 79 80
want Unity to check this file either, define this to make it skip the inclusion.

_Example:_
        #define UNITY_EXCLUDE_LIMITS_H

81

M
Mark VanderVoord 已提交
82
If you've disabled both of the automatic options above, you're going to have to
83 84
do the configuration yourself. Don't worry. Even this isn't too bad... there are
just a handful of defines that you are going to specify if you don't like the
T
toby 已提交
85 86
defaults.

87

T
toby 已提交
88
##### `UNITY_INT_WIDTH`
89 90

Define this to be the number of bits an `int` takes up on your system. The
T
toby 已提交
91 92 93 94 95
default, if not autodetected, is 32 bits.

_Example:_
        #define UNITY_INT_WIDTH 16

96

T
toby 已提交
97
##### `UNITY_LONG_WIDTH`
98 99 100 101 102

Define this to be the number of bits a `long` takes up on your system. The
default, if not autodetected, is 32 bits. This is used to figure out what kind
of 64-bit support your system can handle. Does it need to specify a `long` or a
`long long` to get a 64-bit value. On 16-bit systems, this option is going to be
T
toby 已提交
103 104 105 106 107
ignored.

_Example:_
        #define UNITY_LONG_WIDTH 16

108

T
toby 已提交
109
##### `UNITY_POINTER_WIDTH`
110 111 112

Define this to be the number of bits a pointer takes up on your system. The
default, if not autodetected, is 32-bits. If you're getting ugly compiler
T
toby 已提交
113 114 115 116 117
warnings about casting from pointers, this is the one to look at.

_Example:_
        #define UNITY_POINTER_WIDTH 64

118

M
Mark VanderVoord 已提交
119
##### `UNITY_SUPPORT_64`
120 121 122 123 124

Unity will automatically include 64-bit support if it auto-detects it, or if
your `int`, `long`, or pointer widths are greater than 32-bits. Define this to
enable 64-bit support if none of the other options already did it for you. There
can be a significant size and speed impact to enabling 64-bit support on small
T
toby 已提交
125 126 127
targets, so don't define it if you don't need it.

_Example:_
M
Mark VanderVoord 已提交
128
        #define UNITY_SUPPORT_64
T
toby 已提交
129

130 131 132 133 134 135 136 137

### Floating Point Types

In the embedded world, it's not uncommon for targets to have no support for
floating point operations at all or to have support that is limited to only
single precision. We are able to guess integer sizes on the fly because integers
are always available in at least one size. Floating point, on the other hand, is
sometimes not available at all. Trying to include `float.h` on these platforms
T
toby 已提交
138 139
would result in an error. This leaves manual configuration as the only option.

140

T
toby 已提交
141
##### `UNITY_INCLUDE_FLOAT`
142

T
toby 已提交
143
##### `UNITY_EXCLUDE_FLOAT`
144

T
toby 已提交
145
##### `UNITY_INCLUDE_DOUBLE`
146

T
toby 已提交
147
##### `UNITY_EXCLUDE_DOUBLE`
148 149 150 151 152

By default, Unity guesses that you will want single precision floating point
support, but not double precision. It's easy to change either of these using the
include and exclude options here. You may include neither, either, or both, as
suits your needs. For features that are enabled, the following floating point
T
toby 已提交
153 154 155 156 157 158 159 160
options also become available.

_Example:_

        //what manner of strange processor is this?
        #define UNITY_EXCLUDE_FLOAT
        #define UNITY_INCLUDE_DOUBLE

161

M
Mark VanderVoord 已提交
162
##### `UNITY_EXCLUDE_FLOAT_PRINT`
163 164

Unity aims for as small of a footprint as possible and avoids most standard
M
Mark VanderVoord 已提交
165
library calls (some embedded platforms don’t have a standard library!). Because
166
of this, its routines for printing integer values are minimalist and hand-coded.
M
Mark VanderVoord 已提交
167 168 169 170 171 172
Therefore, the display of floating point values during a failure are optional.
By default, Unity will print the actual results of floating point assertion
failure (e.g. ”Expected 4.56 Was 4.68”). To not include this extra support, you
can use this define to instead respond to a failed assertion with a message like
”Values Not Within Delta”. If you would like verbose failure messages for floating
point assertions, use these options to give more explicit failure messages.
T
toby 已提交
173 174

_Example:_
M
Mark VanderVoord 已提交
175
        #define UNITY_EXCLUDE_FLOAT_PRINT
T
toby 已提交
176

177

T
toby 已提交
178
##### `UNITY_FLOAT_TYPE`
179 180 181

If enabled, Unity assumes you want your `FLOAT` asserts to compare standard C
floats. If your compiler supports a specialty floating point type, you can
T
toby 已提交
182 183 184 185 186
always override this behavior by using this definition.

_Example:_
        #define UNITY_FLOAT_TYPE float16_t

187

T
toby 已提交
188
##### `UNITY_DOUBLE_TYPE`
189 190 191 192 193

If enabled, Unity assumes you want your `DOUBLE` asserts to compare standard C
doubles. If you would like to change this, you can specify something else by
using this option. For example, defining `UNITY_DOUBLE_TYPE` to `long double`
could enable gargantuan floating point types on your 64-bit processor instead of
T
toby 已提交
194 195 196 197 198
the standard `double`.

_Example:_
        #define UNITY_DOUBLE_TYPE long double

199

T
toby 已提交
200
##### `UNITY_FLOAT_PRECISION`
201

T
toby 已提交
202
##### `UNITY_DOUBLE_PRECISION`
203 204 205 206 207 208 209 210 211 212

If you look up `UNITY_ASSERT_EQUAL_FLOAT` and `UNITY_ASSERT_EQUAL_DOUBLE` as
documented in the big daddy Unity Assertion Guide, you will learn that they are
not really asserting that two values are equal but rather that two values are
"close enough" to equal. "Close enough" is controlled by these precision
configuration options. If you are working with 32-bit floats and/or 64-bit
doubles (the normal on most processors), you should have no need to change these
options. They are both set to give you approximately 1 significant bit in either
direction. The float precision is 0.00001 while the double is 10-12.
For further details on how this works, see the appendix of the Unity Assertion
T
toby 已提交
213 214 215 216 217
Guide.

_Example:_
        #define UNITY_FLOAT_PRECISION 0.001f

218 219 220 221 222 223 224 225 226 227 228 229
### Miscellaneous

##### `UNITY_EXCLUDE_STDDEF_H`

Unity uses the `NULL` macro, which defines the value of a null pointer constant,
defined in `stddef.h` by default. If you want to provide
your own macro for this, you should exclude the `stddef.h` header file by adding this
define to your configuration.

_Example:_
        #define UNITY_EXCLUDE_STDDEF_H

230

T
toby 已提交
231
### Toolset Customization
232 233 234 235 236

In addition to the options listed above, there are a number of other options
which will come in handy to customize Unity's behavior for your specific
toolchain. It is possible that you may not need to touch any of these... but
certain platforms, particularly those running in simulators, may need to jump
D
Deryew 已提交
237
through extra hoops to run properly. These macros will help in those
T
toby 已提交
238 239
situations.

240

T
toby 已提交
241
##### `UNITY_OUTPUT_CHAR(a)`
242

T
toby 已提交
243
##### `UNITY_OUTPUT_FLUSH()`
244

T
toby 已提交
245
##### `UNITY_OUTPUT_START()`
246

T
toby 已提交
247
##### `UNITY_OUTPUT_COMPLETE()`
248 249 250 251 252 253 254 255 256

By default, Unity prints its results to `stdout` as it runs. This works
perfectly fine in most situations where you are using a native compiler for
testing. It works on some simulators as well so long as they have `stdout`
routed back to the command line. There are times, however, where the simulator
will lack support for dumping results or you will want to route results
elsewhere for other reasons. In these cases, you should define the
`UNITY_OUTPUT_CHAR` macro. This macro accepts a single character at a time (as
an `int`, since this is the parameter type of the standard C `putchar` function
T
toby 已提交
257 258 259
most commonly used). You may replace this with whatever function call you like.

_Example:_
260 261
Say you are forced to run your test suite on an embedded processor with no
`stdout` option. You decide to route your test result output to a custom serial
T
toby 已提交
262
`RS232_putc()` function you wrote like thus:
263 264
        #include "RS232_header.h"
        ...
T
toby 已提交
265 266 267 268 269 270
        #define UNITY_OUTPUT_CHAR(a) RS232_putc(a)
        #define UNITY_OUTPUT_START() RS232_config(115200,1,8,0)
        #define UNITY_OUTPUT_FLUSH() RS232_flush()
        #define UNITY_OUTPUT_COMPLETE() RS232_close()

_Note:_
271
`UNITY_OUTPUT_FLUSH()` can be set to the standard out flush function simply by
272
specifying `UNITY_USE_FLUSH_STDOUT`. No other defines are required.
T
toby 已提交
273

274

M
Mark VanderVoord 已提交
275 276 277 278 279
##### `UNITY_WEAK_ATTRIBUTE`

##### `UNITY_WEAK_PRAGMA`

##### `UNITY_NO_WEAK`
280

M
Mark VanderVoord 已提交
281 282 283 284 285 286 287 288 289 290 291 292 293 294
For some targets, Unity can make the otherwise required setUp() and tearDown()
functions optional. This is a nice convenience for test writers since setUp and
tearDown don’t often actually do anything. If you’re using gcc or clang, this
option is automatically defined for you. Other compilers can also support this
behavior, if they support a C feature called weak functions. A weak function is
a function that is compiled into your executable unless a non-weak version of
the same function is defined elsewhere. If a non-weak version is found, the weak
version is ignored as if it never existed. If your compiler supports this feature,
you can let Unity know by defining UNITY_WEAK_ATTRIBUTE or UNITY_WEAK_PRAGMA as
the function attributes that would need to be applied to identify a function as
weak. If your compiler lacks support for weak functions, you will always need to
define setUp and tearDown functions (though they can be and often will be just
empty). You can also force Unity to NOT use weak functions by defining
UNITY_NO_WEAK. The most common options for this feature are:
T
toby 已提交
295 296

_Example:_
M
Mark VanderVoord 已提交
297 298 299 300
        #define UNITY_WEAK_ATTRIBUTE weak
        #define UNITY_WEAK_ATTRIBUTE __attribute__((weak))
        #define UNITY_WEAK_PRAGMA
        #define UNITY_NO_WEAK
T
toby 已提交
301

302

T
toby 已提交
303
##### `UNITY_PTR_ATTRIBUTE`
304 305 306

Some compilers require a custom attribute to be assigned to pointers, like
`near` or `far`. In these cases, you can give Unity a safe default for these by
T
toby 已提交
307 308 309 310 311 312
defining this option with the attribute you would like.

_Example:_
        #define UNITY_PTR_ATTRIBUTE __attribute__((far))
        #define UNITY_PTR_ATTRIBUTE near

313

M
Mark VanderVoord 已提交
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
##### `UNITY_PRINT_EOL`

By default, Unity outputs \n at the end of each line of output. This is easy
to parse by the scripts, by Ceedling, etc, but it might not be ideal for YOUR
system. Feel free to override this and to make it whatever you wish.

_Example:_
        #define UNITY_PRINT_EOL { UNITY_OUTPUT_CHAR('\r'); UNITY_OUTPUT_CHAR('\n') }



##### `UNITY_EXCLUDE_DETAILS`

This is an option for if you absolutely must squeeze every byte of memory out of
your system. Unity stores a set of internal scratchpads which are used to pass
extra detail information around. It's used by systems like CMock in order to
report which function or argument flagged an error. If you're not using CMock and
you're not using these details for other things, then you can exclude them.

_Example:_
        #define UNITY_EXCLUDE_DETAILS



##### `UNITY_EXCLUDE_SETJMP`

If your embedded system doesn't support the standard library setjmp, you can
exclude Unity's reliance on this by using this define. This dropped dependence
comes at a price, though. You will be unable to use custom helper functions for
your tests, and you will be unable to use tools like CMock. Very likely, if your
compiler doesn't support setjmp, you wouldn't have had the memory space for those
things anyway, though... so this option exists for those situations.

_Example:_
        #define UNITY_EXCLUDE_SETJMP

350 351 352 353 354 355 356
##### `UNITY_OUTPUT_COLOR`

If you want to add color using ANSI escape codes you can use this define.
t
_Example:_
        #define UNITY_OUTPUT_COLOR

M
Mark VanderVoord 已提交
357 358


T
toby 已提交
359
## Getting Into The Guts
360 361 362 363 364 365 366 367 368

There will be cases where the options above aren't quite going to get everything
perfect. They are likely sufficient for any situation where you are compiling
and executing your tests with a native toolchain (e.g. clang on Mac). These
options may even get you through the majority of cases encountered in working
with a target simulator run from your local command line. But especially if you
must run your test suite on your target hardware, your Unity configuration will
require special help. This special help will usually reside in one of two
places: the `main()` function or the `RUN_TEST` macro. Let's look at how these
T
toby 已提交
369 370
work.

371

T
toby 已提交
372
##### `main()`
373 374 375 376 377 378

Each test module is compiled and run on its own, separate from the other test
files in your project. Each test file, therefore, has a `main` function. This
`main` function will need to contain whatever code is necessary to initialize
your system to a workable state. This is particularly true for situations where
you must set up a memory map or initialize a communication channel for the
T
toby 已提交
379 380 381 382
output of your test results.

A simple main function looks something like this:

383 384 385 386 387 388
        int main(void) {
            UNITY_BEGIN();
            RUN_TEST(test_TheFirst);
            RUN_TEST(test_TheSecond);
            RUN_TEST(test_TheThird);
            return UNITY_END();
T
toby 已提交
389 390
        }

391 392 393 394
You can see that our main function doesn't bother taking any arguments. For our
most barebones case, we'll never have arguments because we just run all the
tests each time. Instead, we start by calling `UNITY_BEGIN`. We run each test
(in whatever order we wish). Finally, we call `UNITY_END`, returning its return
T
toby 已提交
395 396
value (which is the total number of failures).

397 398 399
It should be easy to see that you can add code before any test cases are run or
after all the test cases have completed. This allows you to do any needed
system-wide setup or teardown that might be required for your special
T
toby 已提交
400 401
circumstances.

402

T
toby 已提交
403
##### `RUN_TEST`
404 405 406 407 408 409

The `RUN_TEST` macro is called with each test case function. Its job is to
perform whatever setup and teardown is necessary for executing a single test
case function. This includes catching failures, calling the test module's
`setUp()` and `tearDown()` functions, and calling `UnityConcludeTest()`. If
using CMock or test coverage, there will be additional stubs in use here. A
T
toby 已提交
410 411 412 413 414 415 416 417 418 419 420 421
simple minimalist RUN_TEST macro looks something like this:

        #define RUN_TEST(testfunc) \
            UNITY_NEW_TEST(#testfunc) \
            if (TEST_PROTECT()) { \
                setUp(); \
                testfunc(); \
            } \
            if (TEST_PROTECT() && (!TEST_IS_IGNORED)) \
                tearDown(); \
            UnityConcludeTest();

422 423 424 425 426 427
So that's quite a macro, huh? It gives you a glimpse of what kind of stuff Unity
has to deal with for every single test case. For each test case, we declare that
it is a new test. Then we run `setUp` and our test function. These are run
within a `TEST_PROTECT` block, the function of which is to handle failures that
occur during the test. Then, assuming our test is still running and hasn't been
ignored, we run `tearDown`. No matter what, our last step is to conclude this
T
toby 已提交
428 429
test before moving on to the next.

430 431 432 433 434
Let's say you need to add a call to `fsync` to force all of your output data to
flush to a file after each test. You could easily insert this after your
`UnityConcludeTest` call. Maybe you want to write an xml tag before and after
each result set. Again, you could do this by adding lines to this macro. Updates
to this macro are for the occasions when you need an action before or after
T
toby 已提交
435 436
every single test case throughout your entire suite of tests.

437

T
toby 已提交
438
## Happy Porting
439 440 441

The defines and macros in this guide should help you port Unity to just about
any C target we can imagine. If you run into a snag or two, don't be afraid of
M
Mark VanderVoord 已提交
442 443 444 445
asking for help on the forums. We love a good challenge!


*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*