arduino_ci 0.1.20 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -19
  3. data/REFERENCE.md +625 -0
  4. data/cpp/arduino/Arduino.h +1 -2
  5. data/cpp/arduino/AvrMath.h +117 -17
  6. data/cpp/arduino/Client.h +26 -0
  7. data/cpp/arduino/EEPROM.h +64 -0
  8. data/cpp/arduino/Godmode.cpp +38 -19
  9. data/cpp/arduino/Godmode.h +88 -22
  10. data/cpp/arduino/HardwareSerial.h +9 -28
  11. data/cpp/arduino/IPAddress.h +59 -0
  12. data/cpp/arduino/MockEventQueue.h +86 -0
  13. data/cpp/arduino/PinHistory.h +64 -24
  14. data/cpp/arduino/Print.h +9 -12
  15. data/cpp/arduino/Printable.h +8 -0
  16. data/cpp/arduino/SPI.h +11 -3
  17. data/cpp/arduino/Server.h +5 -0
  18. data/cpp/arduino/Udp.h +27 -0
  19. data/cpp/arduino/Wire.h +234 -0
  20. data/cpp/arduino/avr/io.h +10 -1
  21. data/cpp/arduino/avr/pgmspace.h +76 -46
  22. data/cpp/arduino/ci/StreamTape.h +36 -0
  23. data/cpp/unittest/ArduinoUnitTests.h +1 -0
  24. data/cpp/unittest/Compare.h +91 -897
  25. data/cpp/unittest/OstreamHelpers.h +9 -0
  26. data/exe/arduino_ci.rb +401 -0
  27. data/exe/arduino_ci_remote.rb +2 -385
  28. data/lib/arduino_ci.rb +1 -0
  29. data/lib/arduino_ci/arduino_cmd.rb +13 -9
  30. data/lib/arduino_ci/arduino_downloader.rb +5 -4
  31. data/lib/arduino_ci/arduino_installation.rb +5 -5
  32. data/lib/arduino_ci/ci_config.rb +12 -0
  33. data/lib/arduino_ci/cpp_library.rb +152 -25
  34. data/lib/arduino_ci/installed_cpp_library.rb +0 -0
  35. data/lib/arduino_ci/library_properties.rb +86 -0
  36. data/lib/arduino_ci/version.rb +1 -1
  37. data/misc/default.yml +50 -3
  38. metadata +23 -13
  39. data/cpp/arduino/Arduino.h.orig +0 -143
  40. data/cpp/arduino/Nullptr.h +0 -7
  41. data/cpp/arduino/ci/Queue.h +0 -73
  42. data/exe/libasan.rb +0 -29
@@ -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 "Nullptr.h"
19
18
 
20
19
  typedef bool boolean;
21
20
  typedef uint8_t byte;
@@ -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,26 @@
1
+ #pragma once
2
+
3
+ #include <Stream.h>
4
+
5
+ class Client : public Stream {
6
+ public:
7
+ Client() {
8
+ // The Stream mock defines a String buffer but never puts anyting in it!
9
+ if (!mGodmodeDataIn) {
10
+ mGodmodeDataIn = new String;
11
+ }
12
+ }
13
+ ~Client() {
14
+ if (mGodmodeDataIn) {
15
+ delete mGodmodeDataIn;
16
+ mGodmodeDataIn = nullptr;
17
+ }
18
+ }
19
+ virtual size_t write(uint8_t value) {
20
+ mGodmodeDataIn->concat(value);
21
+ return 1;
22
+ }
23
+
24
+ protected:
25
+ uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); }
26
+ };
@@ -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;
@@ -1,38 +1,47 @@
1
1
  #include "Godmode.h"
2
2
  #include "HardwareSerial.h"
3
3
  #include "SPI.h"
4
-
5
- GodmodeState godmode = GodmodeState();
4
+ #include "Wire.h"
6
5
 
7
6
  GodmodeState* GODMODE() {
8
- return &godmode;
7
+ return GodmodeState::getInstance();
8
+ }
9
+
10
+ GodmodeState* GodmodeState::instance = nullptr;
11
+
12
+ GodmodeState* GodmodeState::getInstance()
13
+ {
14
+ if (instance == nullptr)
15
+ {
16
+ instance = new GodmodeState();
17
+ for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
18
+ instance->digitalPin[i].setMicrosRetriever(&GodmodeState::getMicros);
19
+ instance->analogPin[i].setMicrosRetriever(&GodmodeState::getMicros);
20
+ }
21
+ }
22
+
23
+ return instance;
9
24
  }
10
25
 
11
26
  unsigned long millis() {
12
- GodmodeState* godmode = GODMODE();
13
- return godmode->micros / 1000;
27
+ return GODMODE()->micros / 1000;
14
28
  }
15
29
 
16
30
  unsigned long micros() {
17
- GodmodeState* godmode = GODMODE();
18
- return godmode->micros;
31
+ return GODMODE()->micros;
19
32
  }
20
33
 
21
34
  void delay(unsigned long millis) {
22
- GodmodeState* godmode = GODMODE();
23
- godmode->micros += millis * 1000;
35
+ GODMODE()->micros += millis * 1000;
24
36
  }
25
37
 
26
38
  void delayMicroseconds(unsigned long micros) {
27
- GodmodeState* godmode = GODMODE();
28
- godmode->micros += micros;
39
+ GODMODE()->micros += micros;
29
40
  }
30
41
 
31
-
32
42
  void randomSeed(unsigned long seed)
33
43
  {
34
- GodmodeState* godmode = GODMODE();
35
- godmode->seed = seed;
44
+ GODMODE()->seed = seed;
36
45
  }
37
46
 
38
47
  long random(long vmax)
@@ -81,16 +90,16 @@ void detachInterrupt(uint8_t interrupt) {
81
90
 
82
91
  // Serial ports
83
92
  #if defined(HAVE_HWSERIAL0)
84
- HardwareSerial Serial(&godmode.serialPort[0].dataIn, &godmode.serialPort[0].dataOut, &godmode.serialPort[0].readDelayMicros);
93
+ HardwareSerial Serial(&GODMODE()->serialPort[0].dataIn, &GODMODE()->serialPort[0].dataOut, &GODMODE()->serialPort[0].readDelayMicros);
85
94
  #endif
86
95
  #if defined(HAVE_HWSERIAL1)
87
- HardwareSerial Serial1(&godmode.serialPort[1].dataIn, &godmode.serialPort[1].dataOut, &godmode.serialPort[1].readDelayMicros);
96
+ HardwareSerial Serial1(&GODMODE()->serialPort[1].dataIn, &GODMODE()->serialPort[1].dataOut, &GODMODE()->serialPort[1].readDelayMicros);
88
97
  #endif
89
98
  #if defined(HAVE_HWSERIAL2)
90
- HardwareSerial Serial2(&godmode.serialPort[2].dataIn, &godmode.serialPort[2].dataOut, &godmode.serialPort[2].readDelayMicros);
99
+ HardwareSerial Serial2(&GODMODE()->serialPort[2].dataIn, &GODMODE()->serialPort[2].dataOut, &GODMODE()->serialPort[2].readDelayMicros);
91
100
  #endif
92
101
  #if defined(HAVE_HWSERIAL3)
93
- HardwareSerial Serial3(&godmode.serialPort[3].dataIn, &godmode.serialPort[3].dataOut, &godmode.serialPort[3].readDelayMicros);
102
+ HardwareSerial Serial3(&GODMODE()->serialPort[3].dataIn, &GODMODE()->serialPort[3].dataOut, &GODMODE()->serialPort[3].readDelayMicros);
94
103
  #endif
95
104
 
96
105
  template <typename T>
@@ -100,4 +109,14 @@ inline std::ostream& operator << ( std::ostream& out, const PinHistory<T>& ph )
100
109
  }
101
110
 
102
111
  // defined in SPI.h
103
- SPIClass SPI = SPIClass(&godmode.spi.dataIn, &godmode.spi.dataOut);
112
+ SPIClass SPI = SPIClass(&GODMODE()->spi.dataIn, &GODMODE()->spi.dataOut);
113
+
114
+ // defined in Wire.h
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
 
@@ -16,32 +18,49 @@ void delayMicroseconds(unsigned long micros);
16
18
  unsigned long millis();
17
19
  unsigned long micros();
18
20
 
19
-
20
21
  #define MOCK_PINS_COUNT 256
21
22
 
22
- #if defined(UBRR3H)
23
- #define NUM_SERIAL_PORTS 4
24
- #elif defined(UBRR2H)
25
- #define NUM_SERIAL_PORTS 3
26
- #elif defined(UBRR1H)
27
- #define NUM_SERIAL_PORTS 2
28
- #elif defined(UBRRH) || defined(UBRR0H)
29
- #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
30
43
  #else
31
- #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)
32
46
  #endif
33
47
 
34
48
  class GodmodeState {
35
- struct PortDef {
36
- String dataIn;
37
- String dataOut;
38
- unsigned long readDelayMicros;
39
- };
49
+ private:
50
+ struct PortDef {
51
+ String dataIn;
52
+ String dataOut;
53
+ unsigned long readDelayMicros;
54
+ };
40
55
 
41
- struct InterruptDef {
42
- bool attached;
43
- uint8_t mode;
44
- };
56
+ struct InterruptDef {
57
+ bool attached;
58
+ uint8_t mode;
59
+ };
60
+
61
+ uint8_t mmapPorts[MOCK_PINS_COUNT];
62
+
63
+ static GodmodeState* instance;
45
64
 
46
65
  public:
47
66
  unsigned long micros;
@@ -52,6 +71,7 @@ class GodmodeState {
52
71
  struct PortDef serialPort[NUM_SERIAL_PORTS];
53
72
  struct InterruptDef interrupt[MOCK_PINS_COUNT]; // not sure how to get actual number
54
73
  struct PortDef spi;
74
+ uint8_t eeprom[_EEPROM_SIZE];
55
75
 
56
76
  void resetPins() {
57
77
  for (int i = 0; i < MOCK_PINS_COUNT; ++i) {
@@ -85,12 +105,28 @@ class GodmodeState {
85
105
  spi.readDelayMicros = 0;
86
106
  }
87
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
+
88
122
  void reset() {
89
123
  resetClock();
90
124
  resetPins();
91
125
  resetInterrupts();
92
126
  resetPorts();
93
127
  resetSPI();
128
+ resetMmapPorts();
129
+ resetEEPROM();
94
130
  seed = 1;
95
131
  }
96
132
 
@@ -98,8 +134,27 @@ class GodmodeState {
98
134
  return NUM_SERIAL_PORTS;
99
135
  }
100
136
 
101
- GodmodeState()
102
- {
137
+ // Using this for anything other than unit testing arduino_ci itself
138
+ // is unsupported at the moment
139
+ void overrideClockTruth(unsigned long (*getMicros)(void)) {
140
+ }
141
+
142
+ // singleton pattern
143
+ static GodmodeState* getInstance();
144
+
145
+ static unsigned long getMicros() {
146
+ return instance->micros;
147
+ }
148
+
149
+ uint8_t* pMmapPort(uint8_t port) { return &mmapPorts[port]; }
150
+ uint8_t mmapPortValue(uint8_t port) { return mmapPorts[port]; }
151
+
152
+ // C++ 11, declare as public for better compiler error messages
153
+ GodmodeState(GodmodeState const&) = delete;
154
+ void operator=(GodmodeState const&) = delete;
155
+
156
+ private:
157
+ GodmodeState() {
103
158
  reset();
104
159
  }
105
160
  };
@@ -121,6 +176,17 @@ void detachInterrupt(uint8_t interrupt);
121
176
  inline void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0) {}
122
177
  inline void noTone(uint8_t _pin) {}
123
178
 
179
+ // These definitions allow the following to compile (see issue #193):
180
+ // https://github.com/arduino-libraries/Ethernet/blob/master/src/utility/w5100.h:341
181
+ // we allow one byte per port which "wastes" 224 bytes, but makes the code easier
182
+ #if defined(__AVR__)
183
+ #define digitalPinToBitMask(pin) (1)
184
+ #define digitalPinToPort(pin) (pin)
185
+ #define portInputRegister(port) (GODMODE()->pMmapPort(port))
186
+ #define portOutputRegister(port) (GODMODE()->pMmapPort(port))
187
+ #else
188
+ // we don't (yet) support other boards
189
+ #endif
190
+
124
191
 
125
192
  GodmodeState* GODMODE();
126
-