arduino_ci 0.3.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +125 -69
  3. data/REFERENCE.md +711 -0
  4. data/cpp/arduino/Arduino.h +1 -7
  5. data/cpp/arduino/ArduinoDefines.h +3 -0
  6. data/cpp/arduino/AvrMath.h +117 -17
  7. data/cpp/arduino/Client.h +27 -0
  8. data/cpp/arduino/EEPROM.h +64 -0
  9. data/cpp/arduino/Godmode.cpp +7 -0
  10. data/cpp/arduino/Godmode.h +121 -15
  11. data/cpp/arduino/HardwareSerial.h +4 -4
  12. data/cpp/arduino/IPAddress.h +59 -0
  13. data/cpp/arduino/Print.h +9 -12
  14. data/cpp/arduino/Printable.h +8 -0
  15. data/cpp/arduino/SPI.h +11 -3
  16. data/cpp/arduino/Server.h +5 -0
  17. data/cpp/arduino/Udp.h +27 -0
  18. data/cpp/arduino/Wire.h +197 -77
  19. data/cpp/arduino/avr/io.h +10 -1
  20. data/cpp/arduino/avr/pgmspace.h +76 -46
  21. data/cpp/unittest/ArduinoUnitTests.h +32 -0
  22. data/cpp/unittest/Assertion.h +54 -26
  23. data/cpp/unittest/Compare.h +58 -51
  24. data/cpp/unittest/OstreamHelpers.h +4 -0
  25. data/exe/arduino_ci.rb +538 -0
  26. data/exe/arduino_ci_remote.rb +2 -393
  27. data/exe/arduino_library_location.rb +2 -2
  28. data/exe/ensure_arduino_installation.rb +7 -1
  29. data/lib/arduino_ci.rb +1 -0
  30. data/lib/arduino_ci/arduino_backend.rb +238 -0
  31. data/lib/arduino_ci/arduino_downloader.rb +43 -73
  32. data/lib/arduino_ci/arduino_downloader_linux.rb +17 -55
  33. data/lib/arduino_ci/arduino_downloader_osx.rb +21 -33
  34. data/lib/arduino_ci/arduino_downloader_windows.rb +11 -53
  35. data/lib/arduino_ci/arduino_installation.rb +18 -80
  36. data/lib/arduino_ci/ci_config.rb +8 -11
  37. data/lib/arduino_ci/cpp_library.rb +250 -59
  38. data/lib/arduino_ci/host.rb +59 -4
  39. data/lib/arduino_ci/library_properties.rb +101 -0
  40. data/lib/arduino_ci/version.rb +1 -1
  41. data/misc/default.yml +57 -6
  42. metadata +19 -87
  43. data/cpp/arduino/Arduino.h.orig +0 -143
  44. data/exe/libasan.rb +0 -29
  45. data/lib/arduino_ci/arduino_cmd.rb +0 -332
  46. data/lib/arduino_ci/arduino_cmd_linux.rb +0 -17
  47. data/lib/arduino_ci/arduino_cmd_linux_builder.rb +0 -19
  48. data/lib/arduino_ci/arduino_cmd_osx.rb +0 -17
  49. data/lib/arduino_ci/arduino_cmd_windows.rb +0 -17
@@ -9,13 +9,12 @@ Where possible, variable names from the Arduino library are used to avoid confli
9
9
 
10
10
  #include "ArduinoDefines.h"
11
11
 
12
+ #include "IPAddress.h"
12
13
  #include "WCharacter.h"
13
14
  #include "WString.h"
14
15
  #include "Print.h"
15
16
  #include "Stream.h"
16
17
  #include "HardwareSerial.h"
17
- #include "SPI.h"
18
- #include "Wire.h"
19
18
 
20
19
  typedef bool boolean;
21
20
  typedef uint8_t byte;
@@ -37,9 +36,6 @@ typedef uint8_t byte;
37
36
  #define highByte(w) ((uint8_t) ((w) >> 8))
38
37
  #define lowByte(w) ((uint8_t) ((w) & 0xff))
39
38
 
40
- // Arduino defines this
41
- #define _NOP() do { 0; } while (0)
42
-
43
39
  // might as well use that NO-op macro for these, while unit testing
44
40
  // you need interrupts? interrupt yourself
45
41
  #define yield() _NOP()
@@ -71,5 +67,3 @@ inline unsigned int makeWord(unsigned int w) { return w; }
71
67
  inline unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
72
68
 
73
69
  #define word(...) makeWord(__VA_ARGS__)
74
-
75
-
@@ -92,3 +92,6 @@
92
92
  #if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
93
93
  #define LED_BUILTIN 13
94
94
  #endif
95
+
96
+ // Arduino defines this
97
+ #define _NOP() do { 0; } while (0)
@@ -1,26 +1,126 @@
1
1
  #pragma once
2
+ #include "ArduinoDefines.h"
2
3
  #include <math.h>
3
4
 
4
- #define constrain(x,l,h) ((x)<(l)?(l):((x)>(h)?(h):(x)))
5
- #define map(x,inMin,inMax,outMin,outMax) (((x)-(inMin))*((outMax)-(outMin))/((inMax)-(inMin))+outMin)
5
+ #ifdef __cplusplus
6
6
 
7
- #define sq(x) ((x)*(x))
7
+ template <class Amt, class Low, class High>
8
+ auto constrain(const Amt &amt, const Low &low, const High &high)
9
+ -> decltype(amt < low ? low : (amt > high ? high : amt)) {
10
+ return (amt < low ? low : (amt > high ? high : amt));
11
+ }
8
12
 
9
- #define radians(deg) ((deg)*DEG_TO_RAD)
10
- #define degrees(rad) ((rad)*RAD_TO_DEG)
13
+ template <class X, class InMin, class InMax, class OutMin, class OutMax>
14
+ auto map(const X &x, const InMin &inMin, const InMax &inMax,
15
+ const OutMin &outMin, const OutMax &outMax)
16
+ -> decltype((x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin) {
17
+ return (x - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
18
+ }
11
19
 
12
- #ifdef abs
13
- #undef abs
14
- #endif
15
- #define abs(x) ((x)>0?(x):-(x))
20
+ template <class T> auto radians(const T &deg) -> decltype(deg * DEG_TO_RAD) {
21
+ return deg * DEG_TO_RAD;
22
+ }
16
23
 
17
- #ifdef max
18
- #undef max
19
- #endif
20
- #define max(a,b) ((a)>(b)?(a):(b))
24
+ template <class T> auto degrees(const T &rad) -> decltype(rad * RAD_TO_DEG) {
25
+ return rad * RAD_TO_DEG;
26
+ }
21
27
 
22
- #ifdef min
23
- #undef min
24
- #endif
25
- #define min(a,b) ((a)<(b)?(a):(b))
28
+ template <class T> auto sq(const T &x) -> decltype(x * x) { return x * x; }
29
+
30
+ template <class T> auto abs(const T &x) -> decltype(x > 0 ? x : -x) {
31
+ return x > 0 ? x : -x;
32
+ }
33
+
34
+ template <class T, class L>
35
+ auto min(const T &a, const L &b) -> decltype((b < a) ? b : a) {
36
+ return (b < a) ? b : a;
37
+ }
38
+
39
+ template <class T, class L>
40
+ auto max(const T &a, const L &b) -> decltype((b < a) ? b : a) {
41
+ return (a < b) ? b : a;
42
+ }
43
+
44
+ #else // __cplusplus
45
+
46
+ #ifdef constrain
47
+ #undef constrain
48
+ #endif
49
+ #define constrain(amt, low, high) \
50
+ ({ \
51
+ __typeof__(amt) _amt = (amt); \
52
+ __typeof__(low) _low = (low); \
53
+ __typeof__(high) _high = (high); \
54
+ (amt < low ? low : (amt > high ? high : amt)); \
55
+ })
26
56
 
57
+ #ifdef map
58
+ #undef map
59
+ #endif
60
+ #define map(x, inMin, inMax, outMin, outMax) \
61
+ ({ \
62
+ __typeof__(x) _x = (x); \
63
+ __typeof__(inMin) _inMin = (inMin); \
64
+ __typeof__(inMax) _inMax = (inMax); \
65
+ __typeof__(outMin) _outMin = (outMin); \
66
+ __typeof__(outMax) _outMax = (outMax); \
67
+ (_x - _inMin) * (_outMax - _outMin) / (_inMax - _inMin) + _outMin; \
68
+ })
69
+
70
+ #ifdef radians
71
+ #undef radians
72
+ #endif
73
+ #define radians(deg) \
74
+ ({ \
75
+ __typeof__(deg) _deg = (deg); \
76
+ _deg *DEG_TO_RAD; \
77
+ })
78
+
79
+ #ifdef degrees
80
+ #undef degrees
81
+ #endif
82
+ #define degrees(rad) \
83
+ ({ \
84
+ __typeof__(rad) _rad = (rad); \
85
+ _rad *RAD_TO_DEG; \
86
+ })
87
+
88
+ #ifdef sq
89
+ #undef sq
90
+ #endif
91
+ #define sq(x) \
92
+ ({ \
93
+ __typeof__(x) _x = (x); \
94
+ _x *_x; \
95
+ })
96
+
97
+ #ifdef abs
98
+ #undef abs
99
+ #endif
100
+ #define abs(x) \
101
+ ({ \
102
+ __typeof__(x) _x = (x); \
103
+ _x > 0 ? _x : -_x; \
104
+ })
105
+
106
+ #ifdef min
107
+ #undef min
108
+ #endif
109
+ #define min(a, b) \
110
+ ({ \
111
+ __typeof__(a) _a = (a); \
112
+ __typeof__(b) _b = (b); \
113
+ _a < _b ? _a : _b; \
114
+ })
115
+
116
+ #ifdef max
117
+ #undef max
118
+ #endif
119
+ #define max(a, b) \
120
+ ({ \
121
+ __typeof__(a) _a = (a); \
122
+ __typeof__(b) _b = (b); \
123
+ _a > _b ? _a : _b; \
124
+ })
125
+
126
+ #endif
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+
3
+ #include <Stream.h>
4
+ #include <IPAddress.h>
5
+
6
+ class Client : public Stream {
7
+ public:
8
+ Client() {
9
+ // The Stream mock defines a String buffer but never puts anyting in it!
10
+ if (!mGodmodeDataIn) {
11
+ mGodmodeDataIn = new String;
12
+ }
13
+ }
14
+ ~Client() {
15
+ if (mGodmodeDataIn) {
16
+ delete mGodmodeDataIn;
17
+ mGodmodeDataIn = nullptr;
18
+ }
19
+ }
20
+ virtual size_t write(uint8_t value) {
21
+ mGodmodeDataIn->concat(value);
22
+ return 1;
23
+ }
24
+
25
+ protected:
26
+ uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); }
27
+ };
@@ -0,0 +1,64 @@
1
+ #pragma once
2
+
3
+ #include <cassert>
4
+ #include <inttypes.h>
5
+ #include <Godmode.h>
6
+
7
+ // Does the current board have EEPROM?
8
+ #ifndef EEPROM_SIZE
9
+ // In lieu of an "EEPROM.h not found" error for unsupported boards
10
+ #error "EEPROM library not available for your board"
11
+ #endif
12
+
13
+ class EEPROMClass {
14
+ private:
15
+ GodmodeState* state;
16
+ public:
17
+ // constructor
18
+ EEPROMClass() {
19
+ state = GODMODE();
20
+ }
21
+ // array subscript operator
22
+ uint8_t &operator[](const int index) {
23
+ assert(index < EEPROM_SIZE);
24
+ return state->eeprom[index];
25
+ }
26
+
27
+ uint8_t read(const int index) {
28
+ assert(index < EEPROM_SIZE);
29
+ return state->eeprom[index];
30
+ }
31
+
32
+ void write(const int index, const uint8_t value) {
33
+ assert(index < EEPROM_SIZE);
34
+ state->eeprom[index] = value;
35
+ }
36
+
37
+ void update(const int index, const uint8_t value) {
38
+ assert(index < EEPROM_SIZE);
39
+ state->eeprom[index] = value;
40
+ }
41
+
42
+ uint16_t length() { return EEPROM_SIZE; }
43
+
44
+ // read any object
45
+ template <typename T> T &get(const int index, T &object) {
46
+ uint8_t *ptr = (uint8_t *)&object;
47
+ for (int i = 0; i < sizeof(T); ++i) {
48
+ *ptr++ = read(index + i);
49
+ }
50
+ return object;
51
+ }
52
+
53
+ // write any object
54
+ template <typename T> const T &put(const int index, T &object) {
55
+ const uint8_t *ptr = (const uint8_t *)&object;
56
+ for (int i = 0; i < sizeof(T); ++i) {
57
+ write(index + i, *ptr++);
58
+ }
59
+ return object;
60
+ }
61
+ };
62
+
63
+ // global available in Godmode.cpp
64
+ extern EEPROMClass EEPROM;
@@ -113,3 +113,10 @@ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);
113
113
 
114
114
  // defined in Wire.h
115
115
  TwoWire Wire = TwoWire();
116
+
117
+ #if defined(EEPROM_SIZE)
118
+ #include <EEPROM.h>
119
+ EEPROMClass EEPROM;
120
+ #endif
121
+
122
+ volatile uint8_t __ARDUINO_CI_SFR_MOCK[1024];
@@ -1,6 +1,8 @@
1
1
  #pragma once
2
2
  #include "ArduinoDefines.h"
3
+ #if defined(__AVR__)
3
4
  #include <avr/io.h>
5
+ #endif
4
6
  #include "WString.h"
5
7
  #include "PinHistory.h"
6
8
 
@@ -18,16 +20,29 @@ unsigned long micros();
18
20
 
19
21
  #define MOCK_PINS_COUNT 256
20
22
 
21
- #if defined(UBRR3H)
22
- #define NUM_SERIAL_PORTS 4
23
- #elif defined(UBRR2H)
24
- #define NUM_SERIAL_PORTS 3
25
- #elif defined(UBRR1H)
26
- #define NUM_SERIAL_PORTS 2
27
- #elif defined(UBRRH) || defined(UBRR0H)
28
- #define NUM_SERIAL_PORTS 1
23
+ #if (!defined NUM_SERIAL_PORTS)
24
+ #if defined(UBRR3H)
25
+ #define NUM_SERIAL_PORTS 4
26
+ #elif defined(UBRR2H)
27
+ #define NUM_SERIAL_PORTS 3
28
+ #elif defined(UBRR1H)
29
+ #define NUM_SERIAL_PORTS 2
30
+ #elif defined(UBRRH) || defined(UBRR0H)
31
+ #define NUM_SERIAL_PORTS 1
32
+ #else
33
+ #define NUM_SERIAL_PORTS 0
34
+ #endif
35
+ #endif
36
+
37
+ // different EEPROM implementations have different macros that leak out
38
+ #if !defined(EEPROM_SIZE) && defined(E2END) && (E2END)
39
+ // public value indicates that feature is available
40
+ #define EEPROM_SIZE (E2END + 1)
41
+ // local array size
42
+ #define _EEPROM_SIZE EEPROM_SIZE
29
43
  #else
30
- #define NUM_SERIAL_PORTS 0
44
+ // feature is not available but we want to have the array so other code compiles
45
+ #define _EEPROM_SIZE (0)
31
46
  #endif
32
47
 
33
48
  class GodmodeState {
@@ -43,6 +58,8 @@ class GodmodeState {
43
58
  uint8_t mode;
44
59
  };
45
60
 
61
+ uint8_t mmapPorts[MOCK_PINS_COUNT];
62
+
46
63
  static GodmodeState* instance;
47
64
 
48
65
  public:
@@ -54,6 +71,7 @@ class GodmodeState {
54
71
  struct PortDef serialPort[NUM_SERIAL_PORTS];
55
72
  struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number
56
73
  struct PortDef spi;
74
+ uint8_t eeprom[_EEPROM_SIZE];
57
75
 
58
76
  void resetPins() {
59
77
  for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
@@ -87,12 +105,28 @@ class GodmodeState {
87
105
  spi.readDelayMicros = 0;
88
106
  }
89
107
 
108
+ void resetMmapPorts() {
109
+ for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
110
+ mmapPorts[i] = 1;
111
+ }
112
+ }
113
+
114
+ void resetEEPROM() {
115
+ #if defined(EEPROM_SIZE)
116
+ for(int i = 0; i < EEPROM_SIZE; ++i) {
117
+ eeprom[i] = 255;
118
+ }
119
+ #endif
120
+ }
121
+
90
122
  void reset() {
91
123
  resetClock();
92
124
  resetPins();
93
125
  resetInterrupts();
94
126
  resetPorts();
95
127
  resetSPI();
128
+ resetMmapPorts();
129
+ resetEEPROM();
96
130
  seed = 1;
97
131
  }
98
132
 
@@ -112,6 +146,9 @@ class GodmodeState {
112
146
  return instance->micros;
113
147
  }
114
148
 
149
+ uint8_t* pMmapPort(uint8_t port) { return &mmapPorts[port]; }
150
+ uint8_t mmapPortValue(uint8_t port) { return mmapPorts[port]; }
151
+
115
152
  // C++ 11, declare as public for better compiler error messages
116
153
  GodmodeState(GodmodeState const&) = delete;
117
154
  void operator=(GodmodeState const&) = delete;
@@ -123,21 +160,90 @@ class GodmodeState {
123
160
  };
124
161
 
125
162
  // io pins
126
- #define pinMode(...) _NOP()
127
- #define analogReference(...) _NOP()
163
+ inline void pinMode(uint8_t pin, uint8_t mode) { _NOP(); }
164
+ inline void analogReference(uint8_t mode) { _NOP(); }
128
165
 
129
166
  void digitalWrite(uint8_t, uint8_t);
130
167
  int digitalRead(uint8_t);
131
168
  int analogRead(uint8_t);
132
169
  void analogWrite(uint8_t, int);
133
- #define analogReadResolution(...) _NOP()
134
- #define analogWriteResolution(...) _NOP()
170
+ inline void analogReadResolution(uint8_t bits) { _NOP(); }
171
+ inline void analogWriteResolution(uint8_t bits) { _NOP(); }
135
172
  void attachInterrupt(uint8_t interrupt, void ISR(void), uint8_t mode);
136
173
  void detachInterrupt(uint8_t interrupt);
137
174
 
138
175
  // TODO: issue #26 to track the commanded state here
139
- inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
140
- inline void noTone(uint8_t _pin) {}
176
+ inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) { throw "Not Yet Implemented"; }
177
+ inline void noTone(uint8_t _pin) { throw "Not Yet Implemented"; }
178
+ inline uint8_t pulseIn(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
179
+ inline uint8_t pulseIn(uint8_t pin, uint8_t value) { return pulseIn(pin, value, (uint32_t) 1000000); }
180
+ inline uint32_t pulseInLong(uint8_t _pin, uint8_t _value, uint32_t _timeout) { throw "Not Yet Implemented"; }
181
+ inline uint32_t pulseInLong(uint8_t pin, uint8_t value) { return pulseInLong(pin, value, (uint32_t) 1000000); }
182
+
183
+ /**
184
+ * Shifts in a byte of data one bit at a time.
185
+ *
186
+ * Starts from either the most (i.e. the leftmost) or least (rightmost)
187
+ * significant bit. For each bit, the clock pin is pulled high, the next bit is
188
+ * read from the data line, and then the clock pin is taken low.
189
+ *
190
+ * @param dataPin the pin on which to input each bit
191
+ * @param clockPin the pin to toggle to signal a read from dataPin
192
+ * @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
193
+ *
194
+ * @return The value read
195
+ */
196
+ inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, bool bitOrder) {
197
+ bool mFirst = bitOrder == MSBFIRST;
198
+ uint8_t ret = 0x00;
199
+ for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
200
+ digitalWrite(clockPin, HIGH);
201
+ uint8_t setBit = mFirst ? 0x80 : 0x01;
202
+ uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
203
+ ret = ret | (digitalRead(dataPin) ? val : 0x00);
204
+ digitalWrite(clockPin, LOW);
205
+ }
206
+ return ret;
207
+ }
208
+
209
+ /**
210
+ * Shifts out a byte of data one bit at a time.
211
+ *
212
+ * Starts from either the most (i.e. the leftmost) or least (rightmost)
213
+ * significant bit. Each bit is written in turn to a data pin, after which a
214
+ * clock pin is pulsed (taken high, then low) to indicate that the bit is
215
+ * available.
216
+ *
217
+ * @param dataPin the pin on which to input each bit
218
+ * @param clockPin the pin to toggle to signal a write from dataPin
219
+ * @param bitOrder which order to shift in the bits; either MSBFIRST or LSBFIRST. B=Bit, not byte
220
+ * @param value the data to shift out
221
+ *
222
+ * @return The value read
223
+ */
224
+ inline void shiftOut(uint8_t dataPin, uint8_t clockPin, bool bitOrder, uint8_t value) {
225
+ bool mFirst = bitOrder == MSBFIRST;
226
+ uint8_t ret = 0x00;
227
+ for (uint8_t i = 0, mask = (bitOrder == MSBFIRST ? 0x80 : 0x01); i < 8; ++i) {
228
+ uint8_t setBit = mFirst ? 0x80 : 0x01;
229
+ uint8_t val = (mFirst ? (setBit >> i) : (setBit << i));
230
+ digitalWrite(dataPin, (value & val) ? HIGH : LOW);
231
+ digitalWrite(clockPin, HIGH);
232
+ digitalWrite(clockPin, LOW);
233
+ }
234
+ }
235
+
236
+ // These definitions allow the following to compile (see issue #193):
237
+ // https://github.com/arduino-libraries/Ethernet/blob/master/src/utility/w5100.h:341
238
+ // we allow one byte per port which "wastes" 224 bytes, but makes the code easier
239
+ #if defined(__AVR__)
240
+ #define digitalPinToBitMask(pin) (1)
241
+ #define digitalPinToPort(pin) (pin)
242
+ #define portInputRegister(port) (GODMODE()->pMmapPort(port))
243
+ #define portOutputRegister(port) (GODMODE()->pMmapPort(port))
244
+ #else
245
+ // we don't (yet) support other boards
246
+ #endif
141
247
 
142
248
 
143
249
  GodmodeState* GODMODE();