FreeEMS  0.2.0-SNAPSHOT-282-g9efc524
typeChecks.h
Go to the documentation of this file.
1 /* FreeEMS - the open source engine management system
2  *
3  * Copyright 2008-2012 Fred Cooke
4  *
5  * This file is part of the FreeEMS project.
6  *
7  * FreeEMS software is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * FreeEMS software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with any FreeEMS software. If not, see http://www.gnu.org/licenses/
19  *
20  * We ask that if you make any changes to this file you email them upstream to
21  * us at admin(at)diyefi(dot)org or, even better, fork the code on github.com!
22  *
23  * Thank you for choosing FreeEMS to run your engine!
24  */
25 
26 
27 /** @file
28  *
29  * @ingroup allHeaders
30  * @ingroup globalHeaders
31  * @ingroup dataStructures
32  *
33  * @brief Compile time checks on types
34  *
35  * This file contains checks on sizes of various structs.
36  */
37 
38 
39 /* Header file multiple inclusion protection courtesy eclipse Header Template */
40 /* and http://gcc.gnu.org/onlinedocs/gcc-3.1.1/cpp/ C pre processor manual */
41 #ifndef FILE_TYPE_CHECKS_H_SEEN
42 #define FILE_TYPE_CHECKS_H_SEEN
43 
44 
45 /** A compile time assertion check.
46  *
47  * Validate at compile time that the predicate is true without
48  * generating code. This can be used at any point in a source file
49  * where typedef is legal.
50  *
51  * On success, compilation proceeds normally.
52  *
53  * On failure, attempts to typedef an array type of negative size. The
54  * offending line will look like
55  * typedef assertion_failed_file_h_42[-1]
56  * where file is the content of the second parameter which should
57  * typically be related in some obvious way to the containing file
58  * name, 42 is the line number in the file on which the assertion
59  * appears, and -1 is the result of a calculation based on the
60  * predicate failing.
61  *
62  * @param predicate The predicate to test. It must evaluate to
63  * something that can be coerced to a normal C boolean.
64  *
65  * @param file A sequence of legal identifier characters that should
66  * uniquely identify the source file in which this condition appears.
67  */
68 #define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate,__LINE__,file)
69 #define _impl_PASTE(a,b) a##b
70 #define _impl_CASSERT_LINE(predicate, line, file) typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
71 
72 
73 // Things with specific sizes:
74 CASSERT(sizeof(Flaggable) == 16, Flaggable)
75 CASSERT(sizeof(ADCBuffer) == 32, ADCBuffer)
76 CASSERT(sizeof(twoDTableUS) == 64, twoDTableUS)
78 CASSERT(sizeof(cutEnabled) == 2, cutEnabled)
79 CASSERT(sizeof(ignitionCutFlags) == 1, ignitionCutFlags)
80 CASSERT(sizeof(injectionCutFlags) == 1, injectionCutFlags)
81 
82 // Short alignment checks:
83 CASSERT((sizeof(Clock) % 2) == 0, Clock)
84 CASSERT((sizeof(Counter) % 2) == 0, Counter)
85 CASSERT((sizeof(CoreVar) % 2) == 0, CoreVar)
86 CASSERT((sizeof(DerivedVar) % 2) == 0, DerivedVar)
87 CASSERT((sizeof(KeyUserDebug) % 2) == 0, KeyUserDebug)
88 
89 // Flash block alignment checks:
90 CASSERT((sizeof(SmallTables1) == flashSectorSize), SmallTables1)
91 CASSERT((sizeof(SmallTables2) == flashSectorSize), SmallTables2)
92 CASSERT((sizeof(SmallTables3) == flashSectorSize), SmallTables3)
93 CASSERT((sizeof(SmallTables4) == flashSectorSize), SmallTables4)
94 
95 CASSERT((sizeof(fixedConfig1) == flashSectorSize), fixedConfig1)
96 CASSERT((sizeof(fixedConfig2) == flashSectorSize), fixedConfig2)
97 
98 // Check the fixed point readability macros for correct behaviour
99 CASSERT(KPA(655.36) > SHORTMAX, PRESSURE) // Overflow gets caught
100 CASSERT(KPA(655.35) == SHORTMAX, PRESSURE) // Centre == max
101 CASSERT(KPA(655.3450000000) == SHORTMAX, PRESSURE) // Lowest to round up
102 CASSERT(KPA(655.3549999999) == SHORTMAX, PRESSURE) // Highest to round down
103 
104 CASSERT(DEGREES_K(655.36) > SHORTMAX, TEMPERATURE_K) // Overflow gets caught
105 CASSERT(DEGREES_K(655.35) == SHORTMAX, TEMPERATURE_K) // Centre == max
106 CASSERT(DEGREES_K(655.3450000000) == SHORTMAX, TEMPERATURE_K) // Lowest to round up
107 CASSERT(DEGREES_K(655.3549999999) == SHORTMAX, TEMPERATURE_K) // Highest to round down
108 
109 CASSERT(CC_PER_MINUTE(3840) > SHORTMAX, INJECTOR_FLOW) // Overflow gets caught
110 CASSERT(CC_PER_MINUTE(3839.94140625) == SHORTMAX, INJECTOR_FLOW) // Centre == max
111 CASSERT(CC_PER_MINUTE(3839.9701171875) == SHORTMAX, INJECTOR_FLOW) // Lowest to round up
112 CASSERT(CC_PER_MINUTE(3839.9121093750) == SHORTMAX, INJECTOR_FLOW) // Highest to round down
113 
114 CASSERT(CYLINDER_VOLUME(2000) > SHORTMAX, CYL_VOLUME) // Overflow gets caught
115 CASSERT(CYLINDER_VOLUME(1999.969482422) == SHORTMAX, CYL_VOLUME) // Centre == max
116 CASSERT(CYLINDER_VOLUME(1999.954223633) == SHORTMAX, CYL_VOLUME) // Lowest to round up
117 CASSERT(CYLINDER_VOLUME(1999.984740906) == SHORTMAX, CYL_VOLUME) // Highest to round down
118 
119 CASSERT(VOLTS(65.536) > SHORTMAX, VOLTAGE) // Overflow gets caught
120 CASSERT(VOLTS(65.535) == SHORTMAX, VOLTAGE) // Centre == max
121 CASSERT(VOLTS(65.5345000001) == SHORTMAX, VOLTAGE) // Lowest to round up
122 CASSERT(VOLTS(65.5354999999) == SHORTMAX, VOLTAGE) // Highest to round down
123 
124 CASSERT(LAMBDA(2.0) > SHORTMAX, LAMBDA) // Overflow gets caught
125 CASSERT(LAMBDA(1.999969482) == SHORTMAX, LAMBDA) // Centre == max
126 CASSERT(LAMBDA(1.999954224) == SHORTMAX, LAMBDA) // Lowest to round up
127 CASSERT(LAMBDA(1.999984741) == SHORTMAX, LAMBDA) // Highest to round down
128 
129 CASSERT(RPM(32767.75) > SHORTMAX, RPM) // Overflow gets caught
130 CASSERT(RPM(32767.5) == SHORTMAX, RPM) // Centre == max
131 CASSERT(RPM(32767.25) == SHORTMAX, RPM) // Lowest to round up
132 CASSERT(RPM(32767.74999999999) == SHORTMAX, RPM) // Highest to round down
133 
134 // Only used with values less than 720, overflows over 720 handled in the code
135 CASSERT(ANGLE(1310.71) > SHORTMAX, ANGLE) // Overflow gets caught
136 CASSERT(ANGLE(1310.7) == SHORTMAX, ANGLE) // Centre == max
137 CASSERT(ANGLE(1310.69) == SHORTMAX, ANGLE) // Lowest to round up
138 CASSERT(ANGLE(1310.7099999999) == SHORTMAX, ANGLE) // Highest to round down
139 
140 CASSERT(PW_MS(52.4284) > SHORTMAX, PW_MS) // Overflow gets caught
141 CASSERT(PW_MS(52.428) == SHORTMAX, PW_MS) // Centre == max
142 CASSERT(PW_MS(52.4276) == SHORTMAX, PW_MS) // Lowest to round up
143 CASSERT(PW_MS(52.428399999999) == SHORTMAX, PW_MS) // Highest to round down
144 
145 CASSERT(PERCENT(102.39921875) > SHORTMAX, PERCENT) // Overflow gets caught
146 CASSERT(PERCENT(102.3984375) == SHORTMAX, PERCENT) // Centre == max
147 CASSERT(PERCENT(102.39765625) == SHORTMAX, PERCENT) // Lowest to round up
148 CASSERT(PERCENT(102.39921874) == SHORTMAX, PERCENT) // Highest to round down
149 
150 CASSERT(VE(127.9990234375) > SHORTMAX, VE) // Overflow gets caught
151 CASSERT(VE(127.998046875) == SHORTMAX, VE) // Centre == max
152 CASSERT(VE(127.9970703125) == SHORTMAX, VE) // Lowest to round up
153 CASSERT(VE(127.9990234374999) == SHORTMAX, VE) // Highest to round down
154 
155 CASSERT(W(399.996948242188) > SHORTMAX, WARMUP) // Overflow gets caught
156 CASSERT(W(399.993896484375) == SHORTMAX, WARMUP) // Centre == max
157 CASSERT(W(399.990844726563) == SHORTMAX, WARMUP) // Lowest to round up
158 CASSERT(W(399.996948242187) == SHORTMAX, WARMUP) // Highest to round down
159 
160 CASSERT(AP(29.4) > SHORTMAX, AFR) // Overflow gets caught
161 CASSERT(AP(14.7) == LR(1.0), AFR) // Matches lambda macro
162 CASSERT(AP(7.35) == LR(0.5), AFR) // Matches lambda macro
163 CASSERT(AP(0) == 0, AFR) // Minimum is OK
164 
165 
166 // TODO Add checks for the IT() macro once new format is setup
167 
168 
169 #else
170  /* let us know if we are being untidy with headers */
171  #warning "Header file TYPE_CHECKS_H seen before, sort it out!"
172 /* end of the wrapper ifdef from the very top */
173 #endif