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
@@ -1,7 +1,7 @@
1
1
  #pragma once
2
2
 
3
3
  //#include <inttypes.h>
4
- #include "Stream.h"
4
+ #include "ci/StreamTape.h"
5
5
 
6
6
  // definitions neeeded for Serial.begin's config arg
7
7
  #define SERIAL_5N1 0x00
@@ -29,53 +29,34 @@
29
29
  #define SERIAL_7O2 0x3C
30
30
  #define SERIAL_8O2 0x3E
31
31
 
32
- class HardwareSerial : public Stream, public ObservableDataStream
32
+ class HardwareSerial : public StreamTape
33
33
  {
34
- protected:
35
- String* mGodmodeDataOut;
36
-
37
34
  public:
38
- HardwareSerial(String* dataIn, String* dataOut, unsigned long* delay): Stream(), ObservableDataStream() {
39
- mGodmodeDataIn = dataIn;
40
- mGodmodeDataOut = dataOut;
41
- mGodmodeMicrosDelay = delay;
42
- }
35
+ HardwareSerial(String* dataIn, String* dataOut, unsigned long* delay): StreamTape(dataIn, dataOut, delay) {}
36
+
43
37
  void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
44
38
  void begin(unsigned long baud, uint8_t config) {
45
39
  *mGodmodeMicrosDelay = 1000000 / baud;
46
40
  }
47
41
  void end() {}
48
42
 
49
- // virtual int available(void);
50
- // virtual int peek(void);
51
- // virtual int read(void);
52
- // virtual int availableForWrite(void);
53
- // virtual void flush(void);
54
- virtual size_t write(uint8_t aChar) {
55
- mGodmodeDataOut->append(String((char)aChar));
56
- advertiseByte((unsigned char)aChar);
57
- return 1;
58
- }
59
-
60
- // https://stackoverflow.com/a/4271276
61
- using Print::write; // pull in write(str) and write(buf, size) from Print
43
+ // support "if (Serial1) {}" sorts of things
62
44
  operator bool() { return true; }
63
-
64
45
  };
65
46
 
66
- #if defined(UBRRH) || defined(UBRR0H)
47
+ #if NUM_SERIAL_PORTS >= 1
67
48
  extern HardwareSerial Serial;
68
49
  #define HAVE_HWSERIAL0
69
50
  #endif
70
- #if defined(UBRR1H)
51
+ #if NUM_SERIAL_PORTS >= 2
71
52
  extern HardwareSerial Serial1;
72
53
  #define HAVE_HWSERIAL1
73
54
  #endif
74
- #if defined(UBRR2H)
55
+ #if NUM_SERIAL_PORTS >= 3
75
56
  extern HardwareSerial Serial2;
76
57
  #define HAVE_HWSERIAL2
77
58
  #endif
78
- #if defined(UBRR3H)
59
+ #if NUM_SERIAL_PORTS >= 4
79
60
  extern HardwareSerial Serial3;
80
61
  #define HAVE_HWSERIAL3
81
62
  #endif
@@ -0,0 +1,59 @@
1
+ #pragma once
2
+
3
+ #include <stdint.h>
4
+
5
+ class IPAddress {
6
+ private:
7
+ union {
8
+ uint8_t bytes[4];
9
+ uint32_t dword;
10
+ operator uint8_t *() const { return (uint8_t *)bytes; }
11
+ } _address;
12
+
13
+ public:
14
+ // Constructors
15
+ IPAddress() : IPAddress(0, 0, 0, 0) {}
16
+ IPAddress(uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4) {
17
+ _address.bytes[0] = octet1;
18
+ _address.bytes[1] = octet2;
19
+ _address.bytes[2] = octet3;
20
+ _address.bytes[3] = octet4;
21
+ }
22
+ IPAddress(uint32_t dword) { _address.dword = dword; }
23
+ IPAddress(const uint8_t bytes[]) {
24
+ _address.bytes[0] = bytes[0];
25
+ _address.bytes[1] = bytes[1];
26
+ _address.bytes[2] = bytes[2];
27
+ _address.bytes[3] = bytes[3];
28
+ }
29
+ IPAddress(unsigned long dword) { _address.dword = (uint32_t)dword; }
30
+
31
+ // Accessors
32
+ uint32_t asWord() const { return _address.dword; }
33
+ uint8_t *raw_address() { return _address.bytes; }
34
+
35
+ // Comparisons
36
+ bool operator==(const IPAddress &rhs) const {
37
+ return _address.dword == rhs.asWord();
38
+ }
39
+
40
+ bool operator!=(const IPAddress &rhs) const {
41
+ return _address.dword != rhs.asWord();
42
+ }
43
+
44
+ // Indexing
45
+ uint8_t operator[](int index) const { return _address.bytes[index]; }
46
+ uint8_t &operator[](int index) { return _address.bytes[index]; }
47
+
48
+ // Conversions
49
+ operator uint32_t() const { return _address.dword; };
50
+
51
+ friend class EthernetClass;
52
+ friend class UDP;
53
+ friend class Client;
54
+ friend class Server;
55
+ friend class DhcpClass;
56
+ friend class DNSClient;
57
+ };
58
+
59
+ const IPAddress INADDR_NONE(0, 0, 0, 0);
@@ -0,0 +1,86 @@
1
+ #pragma once
2
+
3
+ template <typename T>
4
+ class MockEventQueue {
5
+ public:
6
+ struct Event {
7
+ T data;
8
+ unsigned long micros;
9
+
10
+ Event() : data(T()), micros(0) {}
11
+ Event(const T &d, unsigned long const t) : data(d), micros(t) { }
12
+ };
13
+
14
+ private:
15
+ struct Node {
16
+ Event event;
17
+ Node* next;
18
+
19
+ Node(const Event &e, Node* n) : event(e), next(n) { }
20
+ };
21
+
22
+ Node* mFront;
23
+ Node* mBack;
24
+ unsigned long mSize;
25
+ T mNil;
26
+ unsigned long (*mGetMicros)(void);
27
+
28
+ void init(unsigned long (*getMicros)(void)) {
29
+ mFront = mBack = nullptr;
30
+ mSize = 0;
31
+ mGetMicros = getMicros;
32
+ }
33
+
34
+ public:
35
+ MockEventQueue(unsigned long (*getMicros)(void)): mNil() { init(getMicros); }
36
+ MockEventQueue(): mNil() { init(nullptr); }
37
+
38
+ MockEventQueue(const MockEventQueue<T>& q) {
39
+ init(q.mGetMicros);
40
+ for (Node* n = q.mFront; n; n = n->next) push(n->event);
41
+ }
42
+
43
+ void setMicrosRetriever(unsigned long (*getMicros)(void)) { mGetMicros = getMicros; }
44
+
45
+ inline unsigned long size() const { return mSize; }
46
+ inline bool empty() const { return 0 == mSize; }
47
+ inline Event front() const { return empty() ? Event(mNil, 0) : mFront->event; }
48
+ inline Event back() const { return empty() ? Event(mNil, 0) : mBack->event; }
49
+ inline T frontData() const { return front().data; }
50
+ inline T backData() const { return back().data; }
51
+ inline unsigned long frontTime() const { return front().micros; }
52
+ inline unsigned long backTime() const { return back().micros; }
53
+
54
+
55
+ // fully formed event
56
+ bool push(const Event& e) {
57
+ Node *n = new Node(e, nullptr);
58
+ if (n == nullptr) return false;
59
+ mBack = (mFront == nullptr ? mFront : mBack->next) = n;
60
+ return ++mSize;
61
+ }
62
+
63
+ // fully specfied event
64
+ bool push(const T& v, unsigned long const time) {
65
+ Event e = {v, time};
66
+ return push(e);
67
+ }
68
+
69
+ // event needing timestamp
70
+ bool push(const T& v) {
71
+ unsigned long micros = mGetMicros == nullptr ? 0 : mGetMicros();
72
+ return push(v, micros);
73
+ }
74
+
75
+ void pop() {
76
+ if (empty()) return;
77
+ Node* n = mFront;
78
+ mFront = mFront->next;
79
+ delete n;
80
+ if (--mSize == 0) mBack = nullptr;
81
+ }
82
+
83
+ void clear() { while (!empty()) pop(); }
84
+
85
+ ~MockEventQueue() { clear(); }
86
+ };
@@ -1,5 +1,5 @@
1
1
  #pragma once
2
- #include "ci/Queue.h"
2
+ #include "MockEventQueue.h"
3
3
  #include "ci/ObservableDataStream.h"
4
4
  #include "WString.h"
5
5
 
@@ -7,8 +7,8 @@
7
7
  template <typename T>
8
8
  class PinHistory : public ObservableDataStream {
9
9
  private:
10
- ArduinoCIQueue<T> qIn;
11
- ArduinoCIQueue<T> qOut;
10
+ MockEventQueue<T> qIn;
11
+ MockEventQueue<T> qOut;
12
12
 
13
13
  void clear() {
14
14
  qOut.clear();
@@ -16,14 +16,14 @@ class PinHistory : public ObservableDataStream {
16
16
  }
17
17
 
18
18
  // enqueue ascii bits
19
- void a2q(ArduinoCIQueue<T> &q, String input, bool bigEndian, bool advertise) {
19
+ void a2q(MockEventQueue<T> &q, String input, bool bigEndian, bool advertise) {
20
20
  // 8 chars at a time, form up
21
21
  for (int j = 0; j < input.length(); ++j) {
22
22
  for (int i = 0; i < 8; ++i) {
23
23
  int shift = bigEndian ? 7 - i : i;
24
24
  unsigned char mask = (0x01 << shift);
25
25
  q.push(mask & input[j]);
26
- if (advertise) advertiseBit(q.back()); // not valid for all possible types but whatever
26
+ if (advertise) advertiseBit(q.backData()); // not valid for all possible types but whatever
27
27
  }
28
28
  }
29
29
  }
@@ -31,10 +31,10 @@ class PinHistory : public ObservableDataStream {
31
31
 
32
32
  // convert a queue to a string as if it was serial bits
33
33
  // start from offset, consider endianness
34
- String q2a(const ArduinoCIQueue<T> &q, unsigned int offset, bool bigEndian) const {
34
+ String q2a(const MockEventQueue<T> &q, unsigned int offset, bool bigEndian) const {
35
35
  String ret = "";
36
36
 
37
- ArduinoCIQueue<T> q2(q);
37
+ MockEventQueue<T> q2(q);
38
38
 
39
39
  while (offset) {
40
40
  q2.pop();
@@ -48,7 +48,7 @@ class PinHistory : public ObservableDataStream {
48
48
  unsigned char acc = 0x00;
49
49
  for (int i = 0; i < 8; ++i) {
50
50
  int shift = bigEndian ? 7 - i : i;
51
- T val = q2.front();
51
+ T val = q2.frontData();
52
52
  unsigned char bit = val ? 0x1 : 0x0;
53
53
  acc |= (bit << shift);
54
54
  q2.pop();
@@ -59,15 +59,25 @@ class PinHistory : public ObservableDataStream {
59
59
  return ret;
60
60
  }
61
61
 
62
+ void init() {
63
+ asciiEncodingOffsetIn = 0; // default is sensible
64
+ asciiEncodingOffsetOut = 1; // default is sensible
65
+ }
66
+
62
67
  public:
63
68
  unsigned int asciiEncodingOffsetIn;
64
69
  unsigned int asciiEncodingOffsetOut;
65
70
 
71
+ PinHistory(unsigned long (*getMicros)(void)) : ObservableDataStream(), qOut(getMicros) {
72
+ init();
73
+ }
74
+
66
75
  PinHistory() : ObservableDataStream() {
67
- asciiEncodingOffsetIn = 0; // default is sensible
68
- asciiEncodingOffsetOut = 1; // default is sensible
76
+ init();
69
77
  }
70
78
 
79
+ void setMicrosRetriever(unsigned long (*getMicros)(void)) { qOut.setMicrosRetriever(getMicros); }
80
+
71
81
  void reset(T val) {
72
82
  clear();
73
83
  qOut.push(val);
@@ -79,8 +89,8 @@ class PinHistory : public ObservableDataStream {
79
89
 
80
90
  // This returns the "value" of the pin in a raw sense
81
91
  operator T() const {
82
- if (!qIn.empty()) return qIn.front();
83
- return qOut.back();
92
+ if (!qIn.empty()) return qIn.frontData();
93
+ return qOut.backData();
84
94
  }
85
95
 
86
96
  // this sets the value of the pin authoritatively
@@ -89,8 +99,8 @@ class PinHistory : public ObservableDataStream {
89
99
  T operator=(const T& i) {
90
100
  qIn.clear();
91
101
  qOut.push(i);
92
- advertiseBit(qOut.back()); // not valid for all possible types but whatever
93
- return qOut.back();
102
+ advertiseBit(qOut.backData()); // not valid for all possible types but whatever
103
+ return qOut.backData();
94
104
  }
95
105
 
96
106
  // This returns the "value" of the pin according to the queued values
@@ -98,14 +108,14 @@ class PinHistory : public ObservableDataStream {
98
108
  // then take the latest output.
99
109
  T retrieve() {
100
110
  if (!qIn.empty()) {
101
- T hack_required_by_travis_ci = qIn.front();
111
+ T hack_required_by_travis_ci = qIn.frontData();
102
112
  qIn.pop();
103
113
  qOut.push(hack_required_by_travis_ci);
104
114
  }
105
- return qOut.back();
115
+ return qOut.backData();
106
116
  }
107
117
 
108
- // enqueue a set of elements
118
+ // enqueue a set of data elements
109
119
  void fromArray(T const * const arr, unsigned int length) {
110
120
  for (int i = 0; i < length; ++i) qIn.push(arr[i]);
111
121
  }
@@ -124,18 +134,48 @@ class PinHistory : public ObservableDataStream {
124
134
  // start from offset, consider endianness
125
135
  String incomingToAscii(bool bigEndian) const { return incomingToAscii(asciiEncodingOffsetIn, bigEndian); }
126
136
 
127
- // convert the pin history to a string as if it was Serial comms
137
+ // convert the pin history data to a string as if it was Serial comms
128
138
  // start from offset, consider endianness
129
139
  String toAscii(unsigned int offset, bool bigEndian) const { return q2a(qOut, offset, bigEndian); }
130
140
 
131
- // convert the pin history to a string as if it was Serial comms
141
+ // convert the pin history data to a string as if it was Serial comms
132
142
  // start from offset, consider endianness
133
143
  String toAscii(bool bigEndian) const { return toAscii(asciiEncodingOffsetOut, bigEndian); }
134
144
 
135
- // copy elements to an array, up to a given length
145
+ // copy data elements to an array, up to a given length
136
146
  // return the number of elements moved
137
147
  int toArray (T* arr, unsigned int length) const {
138
- ArduinoCIQueue<T> q2(qOut);
148
+ MockEventQueue<T> q2(qOut); // preserve const by copying
149
+
150
+ int ret = 0;
151
+ for (int i = 0; i < length && q2.size(); ++i) {
152
+ arr[i] = q2.frontData();
153
+ q2.pop();
154
+ ++ret;
155
+ }
156
+ return ret;
157
+ }
158
+
159
+ // copy pin history timing to an array, up to a given length.
160
+ // note that this records times between calls to the pin, not between transitions
161
+ // return the number of elements moved
162
+ int toTimestampArray(unsigned long* arr, unsigned int length) const {
163
+ MockEventQueue<T> q2(qOut); // preserve const by copying
164
+
165
+ int ret = 0;
166
+ for (int i = 0; i < length && q2.size(); ++i) {
167
+ arr[i] = q2.frontTime();
168
+ q2.pop();
169
+ ++ret;
170
+ }
171
+ return ret;
172
+ }
173
+
174
+ // copy pin history timing to an array, up to a given length.
175
+ // note that this records times between calls to the pin, not between transitions
176
+ // return the number of elements moved
177
+ int toEventArray(typename MockEventQueue<T>::Event* arr, unsigned int length) const {
178
+ MockEventQueue<T> q2(qOut); // preserve const by copying
139
179
 
140
180
  int ret = 0;
141
181
  for (int i = 0; i < length && q2.size(); ++i) {
@@ -146,12 +186,12 @@ class PinHistory : public ObservableDataStream {
146
186
  return ret;
147
187
  }
148
188
 
149
- // see if the array matches the elements in the queue
189
+ // see if the array matches the data of the elements in the queue
150
190
  bool hasElements (T const * const arr, unsigned int length) const {
151
191
  int i;
152
- ArduinoCIQueue<T> q2(qOut);
192
+ MockEventQueue<T> q2(qOut); // preserve const by copying
153
193
  for (i = 0; i < length && q2.size(); ++i) {
154
- if (q2.front() != arr[i]) return false;
194
+ if (q2.frontData() != arr[i]) return false;
155
195
  q2.pop();
156
196
  }
157
197
  return i == length;
@@ -2,6 +2,8 @@
2
2
 
3
3
  #include <stdio.h>
4
4
  #include <avr/pgmspace.h>
5
+
6
+ #include "Printable.h"
5
7
  #include "WString.h"
6
8
 
7
9
  #define DEC 10
@@ -12,22 +14,17 @@
12
14
  #endif
13
15
  #define BIN 2
14
16
 
15
- class Print;
16
-
17
- class Printable
18
- {
19
- public:
20
- virtual size_t printTo(Print& p) const = 0;
21
- };
22
-
23
17
  class Print
24
18
  {
19
+ private:
20
+ int write_error;
21
+ protected:
22
+ void setWriteError(int err = 1) { write_error = err; }
25
23
  public:
26
- Print() {}
24
+ Print() : write_error(0) {}
27
25
 
28
- // Arduino's version of this is richer but until I see an actual error case I'm not sure how to mock
29
- int getWriteError() { return 0; }
30
- void clearWriteError() { }
26
+ int getWriteError() { return write_error; }
27
+ void clearWriteError() { setWriteError(0); }
31
28
  virtual int availableForWrite() { return 0; }
32
29
 
33
30
  virtual size_t write(uint8_t) = 0;
@@ -0,0 +1,8 @@
1
+ #pragma once
2
+
3
+ class Print;
4
+
5
+ class Printable {
6
+ public:
7
+ virtual size_t printTo(Print &p) const = 0;
8
+ };