arduino_ci 0.1.20 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
-