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.
- checksums.yaml +4 -4
- data/README.md +21 -19
- data/REFERENCE.md +625 -0
- data/cpp/arduino/Arduino.h +1 -2
- data/cpp/arduino/AvrMath.h +117 -17
- data/cpp/arduino/Client.h +26 -0
- data/cpp/arduino/EEPROM.h +64 -0
- data/cpp/arduino/Godmode.cpp +38 -19
- data/cpp/arduino/Godmode.h +88 -22
- data/cpp/arduino/HardwareSerial.h +9 -28
- data/cpp/arduino/IPAddress.h +59 -0
- data/cpp/arduino/MockEventQueue.h +86 -0
- data/cpp/arduino/PinHistory.h +64 -24
- data/cpp/arduino/Print.h +9 -12
- data/cpp/arduino/Printable.h +8 -0
- data/cpp/arduino/SPI.h +11 -3
- data/cpp/arduino/Server.h +5 -0
- data/cpp/arduino/Udp.h +27 -0
- data/cpp/arduino/Wire.h +234 -0
- data/cpp/arduino/avr/io.h +10 -1
- data/cpp/arduino/avr/pgmspace.h +76 -46
- data/cpp/arduino/ci/StreamTape.h +36 -0
- data/cpp/unittest/ArduinoUnitTests.h +1 -0
- data/cpp/unittest/Compare.h +91 -897
- data/cpp/unittest/OstreamHelpers.h +9 -0
- data/exe/arduino_ci.rb +401 -0
- data/exe/arduino_ci_remote.rb +2 -385
- data/lib/arduino_ci.rb +1 -0
- data/lib/arduino_ci/arduino_cmd.rb +13 -9
- data/lib/arduino_ci/arduino_downloader.rb +5 -4
- data/lib/arduino_ci/arduino_installation.rb +5 -5
- data/lib/arduino_ci/ci_config.rb +12 -0
- data/lib/arduino_ci/cpp_library.rb +152 -25
- data/lib/arduino_ci/installed_cpp_library.rb +0 -0
- data/lib/arduino_ci/library_properties.rb +86 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +50 -3
- metadata +23 -13
- data/cpp/arduino/Arduino.h.orig +0 -143
- data/cpp/arduino/Nullptr.h +0 -7
- data/cpp/arduino/ci/Queue.h +0 -73
- data/exe/libasan.rb +0 -29
@@ -1,7 +1,7 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
//#include <inttypes.h>
|
4
|
-
#include "
|
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
|
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):
|
39
|
-
|
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
|
-
//
|
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
|
47
|
+
#if NUM_SERIAL_PORTS >= 1
|
67
48
|
extern HardwareSerial Serial;
|
68
49
|
#define HAVE_HWSERIAL0
|
69
50
|
#endif
|
70
|
-
#if
|
51
|
+
#if NUM_SERIAL_PORTS >= 2
|
71
52
|
extern HardwareSerial Serial1;
|
72
53
|
#define HAVE_HWSERIAL1
|
73
54
|
#endif
|
74
|
-
#if
|
55
|
+
#if NUM_SERIAL_PORTS >= 3
|
75
56
|
extern HardwareSerial Serial2;
|
76
57
|
#define HAVE_HWSERIAL2
|
77
58
|
#endif
|
78
|
-
#if
|
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
|
+
};
|
data/cpp/arduino/PinHistory.h
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#pragma once
|
2
|
-
#include "
|
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
|
-
|
11
|
-
|
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(
|
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.
|
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
|
34
|
+
String q2a(const MockEventQueue<T> &q, unsigned int offset, bool bigEndian) const {
|
35
35
|
String ret = "";
|
36
36
|
|
37
|
-
|
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.
|
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
|
-
|
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.
|
83
|
-
return qOut.
|
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.
|
93
|
-
return qOut.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
192
|
+
MockEventQueue<T> q2(qOut); // preserve const by copying
|
153
193
|
for (i = 0; i < length && q2.size(); ++i) {
|
154
|
-
if (q2.
|
194
|
+
if (q2.frontData() != arr[i]) return false;
|
155
195
|
q2.pop();
|
156
196
|
}
|
157
197
|
return i == length;
|
data/cpp/arduino/Print.h
CHANGED
@@ -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
|
-
|
29
|
-
|
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;
|