arduino_ci 0.1.21 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +49 -20
- data/REFERENCE.md +625 -0
- data/cpp/arduino/Arduino.h +1 -1
- data/cpp/arduino/AvrMath.h +117 -17
- data/cpp/arduino/Client.h +27 -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/OstreamHelpers.h +4 -0
- data/exe/arduino_ci.rb +400 -0
- data/exe/arduino_ci_remote.rb +2 -385
- data/exe/arduino_library_location.rb +2 -2
- data/lib/arduino_ci.rb +1 -0
- data/lib/arduino_ci/arduino_backend.rb +218 -0
- data/lib/arduino_ci/arduino_downloader.rb +42 -72
- data/lib/arduino_ci/arduino_downloader_linux.rb +17 -55
- data/lib/arduino_ci/arduino_downloader_osx.rb +21 -33
- data/lib/arduino_ci/arduino_downloader_windows.rb +11 -53
- data/lib/arduino_ci/arduino_installation.rb +18 -80
- data/lib/arduino_ci/ci_config.rb +12 -7
- data/lib/arduino_ci/cpp_library.rb +262 -48
- data/lib/arduino_ci/host.rb +59 -4
- data/lib/arduino_ci/library_properties.rb +96 -0
- data/lib/arduino_ci/version.rb +1 -1
- data/misc/default.yml +55 -4
- metadata +18 -83
- data/cpp/arduino/Arduino.h.orig +0 -143
- data/cpp/arduino/ci/Queue.h +0 -73
- data/exe/libasan.rb +0 -29
- data/lib/arduino_ci/arduino_cmd.rb +0 -328
- data/lib/arduino_ci/arduino_cmd_linux.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_linux_builder.rb +0 -19
- data/lib/arduino_ci/arduino_cmd_osx.rb +0 -17
- data/lib/arduino_ci/arduino_cmd_windows.rb +0 -17
@@ -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;
|