Skip to content

Commit 927054b

Browse files
authored
Merge pull request #63 from bxparks/develop
merge v1.3.0 into master
2 parents eb19dab + 0661c08 commit 927054b

File tree

12 files changed

+431
-56
lines changed

12 files changed

+431
-56
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
# Changelog
22

33
* Unreleased
4+
* 1.3.0 (2022-03-28)
5+
* Add support for `EXTRA_CPPFLAGS`, similar to `EXTRA_CXXFLAGS`.
6+
* Add `digitalReadValue(pin, val)` to control the return value of
7+
`digitalRead(pin)`.
8+
* May be useful for testing purposes.
9+
* The `pin` parameter must satisfy `0 <= pin < 32`, otherwise
10+
`digitalReadValue()` is a no-op.
11+
* See [PR#61](https://github.com/bxparks/EpoxyDuino/pull/61).
12+
* Add an empty `EpoxyDuino.h` at the top level to stop warning messages from
13+
the Arduino IDE.
14+
* Fixes [Issue#62](https://github.com/bxparks/EpoxyDuino/issues/62).
15+
* Add [libraries/EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC)
16+
* A mock of the [STM32RTC](https://github.com/stm32duino/STM32RTC)
17+
library.
418
* 1.2.3 (2022-02-24)
519
* Rename `unixhostduino_main()` to `epoxyduino_main()`, and make it
620
static. No need to expose it publicly.

EpoxyDuino.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This header file is empty. Its sole purpose is to disable warnings in the
2+
// Arduino IDE which identifies EpoxyDuino as an invalid Arduino library when it
3+
// is installed inside the Arduino sketchbook libraries directory. The warning
4+
// message looks like this:
5+
//
6+
// "Invalid library found in /home/brian/src/arduino/libraries/EpoxyDuino: no
7+
// headers files (.h) found in /home/brian/src/arduino/libraries/EpoxyDuino"
8+
//
9+
// EpoxyDuino is *not* an Arduino library. But it is very convenient to install
10+
// it along side the other Arduino libraries so that it can search for those
11+
// libraries as siblings to its own location when they are referenced in the
12+
// `ARDUINO_LIBS` Makefile variable. It can be installed somewhere else, but you
13+
// then have to define the `ARDUINO_LIB_DIRS` variable in all your Makefiles to
14+
// tell EpoxyDuino where to look for those libraries.

EpoxyDuino.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ endif
133133
CXXFLAGS += $(EXTRA_CXXFLAGS)
134134

135135
# Pre-processor flags (-I, -D, etc), mostly for header files.
136-
CPPFLAGS ?=
136+
CPPFLAGS += $(EXTRA_CPPFLAGS)
137137
# Define a macro to indicate that EpoxyDuino is being used. Defined here
138138
# instead of Arduino.h so that files like 'compat.h' can determine the
139139
# compile-time environment without having to include <Arduino.h>.

README.md

Lines changed: 117 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,19 @@ also provided:
3434
TimerOne (https://github.com/PaulStoffregen/TimerOne) library
3535
* [EpoxyMockFastLED](libraries/EpoxyMockFastLED/): mock version of the
3636
FastLED (https://github.com/FastLED/FastLED) library
37+
* [EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC/): mock version of the
38+
STM32RTC (https://github.com/stm32duino/STM32RTC) library
3739

3840
These mock libraries may be sufficient for a CI pipeline.
3941

4042
For actual application development, I have started to build a set of
4143
libraries within EpoxyDuino which emulate the versions that run the actual
4244
hardware:
4345

44-
* EpoxyFS: emulation of the ESP8266 LittleFS or ESP32 LittleFS
45-
* EpoxyEepromAvr: emulation of AVR-flavored `EEPROM`
46-
* EpoxyEepromEsp: emulation of ESP-flavored `EEPROM`
46+
* [EpoxyFS](libraries/EpoxyFS): emulation of the ESP8266 LittleFS or
47+
ESP32 LittleFS filesystem
48+
* [EpoxyEepromAvr](libraries/EpoxyEepromAvr): emulation of AVR-flavored `EEPROM`
49+
* [EpoxyEepromEsp](libraries/EpoxyEepromEsp): emulation of ESP-flavored `EEPROM`
4750

4851
If your program has limited hardware dependencies so that it is conceptually
4952
portable to a vanilla Unix environment, EpoxyDuino may work well for you.
@@ -68,7 +71,7 @@ The disadvantages are:
6871
environments (e.g. 16-bit `int` versus 32-bit `int`, or 32-bit `long` versus
6972
64-bit `long`).
7073

71-
**Version**: 1.2.3 (2022-02-24)
74+
**Version**: 1.3.0 (2022-03.28)
7275

7376
**Changelog**: See [CHANGELOG.md](CHANGELOG.md)
7477

@@ -85,14 +88,17 @@ The disadvantages are:
8588
* [Continuous Integration](#ContinuousIntegration)
8689
* [Advanced Usage](#AdvancedUsage)
8790
* [Alternate C++ Compiler](#AlternateCompiler)
88-
* [Generated Source Code](#GeneratedSourceCode)
91+
* [Additional Cpp Flags](#AdditionalCppFlags)
92+
* [Additional Compiler Flags](#AdditionalCompilerFlags)
8993
* [Additional Clean Up](#AdditionalCleanUp)
9094
* [Additional Dependencies](#AdditionalDependencies)
95+
* [Generated Source Code](#GeneratedSourceCode)
9196
* [Alternate Arduino Core](#AlternateArduinoCore)
9297
* [PlatformIO](#PlatformIO)
9398
* [Command Line Flags and Arguments](#CommandLineFlagsAndArguments)
9499
* [Debugging](#Debugging)
95100
* [Valgrind](#Valgrind)
101+
* [Controlling digitalRead()](#DigitalReadValue)
96102
* [Supported Arduino Features](#SupportedArduinoFeatures)
97103
* [Arduino Functions](#ArduinoFunctions)
98104
* [Serial Port Emulation](#SerialPortEmulation)
@@ -449,52 +455,35 @@ Take a look at some of my GitHub Actions YAML config files:
449455
### Alternate C++ Compiler
450456

451457
Normally the C++ compiler on Linux is `g++`. If you have `clang++` installed
452-
you can use that instead by specifying the `CXX` environment variable:
458+
you can use that instead by specifying the `CXX` makefile variable:
453459
```
454-
$ CXX=clang++ make
460+
$ make CXX=clang++
455461
```
456-
(This sets the `CXX` shell environment variable temporarily, for the duration of
457-
the `make` command, which causes `make` to set its internal `CXX` variable,
458-
which causes `EpoxyDuino.mk` to use `clang++` over the default `g++`.)
462+
(This tells `make` to set the `CXX` variable to `clang++` within the context of
463+
`EpoxyDuino.mk` which causes `clang++` to be used over the default `g++`.)
459464

460-
The `clang++` compiler will sometimes catch a different set of programming
461-
errors.
465+
One reason to use `clang++` instead of `g++` is that the `clang++` compiler will
466+
sometimes catch a different set of programming errors.
462467

463-
<a name="GeneratedSourceCode"></a>
464-
### Generated Source Code
468+
<a name="AdditionalCppFlags"></a>
469+
### Additional Cpp Flags
465470

466-
If a source file is generated dynamically through a code generation script,
467-
and the source file is *not* checked into the repository because it is too
468-
dynamic, then you can include the generated files using the `GENERATED`
469-
and the `OBJS` variables.
470-
471-
First add the list of generated files `*.cpp` or `*.c` to the `GENERATED`
472-
variable. Then add the corresponding `*.o` files to the `OBJS` variable, like
473-
this:
471+
You can pass additional flags to the C preprocessor through the `EXTRA_CPPFLAGS`
472+
variable, like this:
474473

475474
```
476-
GENERATED := foo.cpp bar.cpp
477-
OBJS := foo.o bar.o
478-
APP_NAME := {name of project}
479-
ARDUINO_LIBS := {list of dependent Arduino libraries}
480-
include {path/to/EpoxyDuino.mk}
475+
$ make EXTRA_CPPFLAGS='-D DEBUG=2'
476+
```
481477

482-
foo.cpp: foo.h generate_foo.sh
483-
./generate_foo.sh # creates 'foo.cpp'
478+
<a name="AdditionalCompilerFlags"></a>
479+
### Additional Compiler Flags
484480

485-
bar.cpp: bar.h generate_bar.sh
486-
./generate_bar.sh # creates 'bar.cpp'
481+
You can pass additional flags to the C++ compiler through the `EXTRA_CXXFLAGS`
482+
variable, like this:
487483

488-
...
489484
```
490-
491-
The `*.o` files in `OJBS` are passed to the linker when the `app.out` binary
492-
file is created.
493-
494-
The `GENERATED` is not strictly required, since the default rules already know
495-
how to compile the `*.o` files from the `*.cpp` or `*.c` files. The primary
496-
effect of `GENERATED` currently is to cause the generated files to be removed
497-
when `make clean` is called.
485+
$ make EXTRA_CXXFLAGS='-g'
486+
```
498487

499488
<a name="AdditionalCleanUp"></a>
500489
### Additional Clean Up
@@ -535,6 +524,42 @@ DEPS := header1.h header2.h
535524
include {path/to/EpoxyDuino.mk}
536525
```
537526

527+
<a name="GeneratedSourceCode"></a>
528+
### Generated Source Code
529+
530+
If a source file is generated dynamically through a code generation script,
531+
and the source file is *not* checked into the repository because it is too
532+
dynamic, then you can include the generated files using the `GENERATED`
533+
and the `OBJS` variables.
534+
535+
First add the list of generated files `*.cpp` or `*.c` to the `GENERATED`
536+
variable. Then add the corresponding `*.o` files to the `OBJS` variable, like
537+
this:
538+
539+
```
540+
GENERATED := foo.cpp bar.cpp
541+
OBJS := foo.o bar.o
542+
APP_NAME := {name of project}
543+
ARDUINO_LIBS := {list of dependent Arduino libraries}
544+
include {path/to/EpoxyDuino.mk}
545+
546+
foo.cpp: foo.h generate_foo.sh
547+
./generate_foo.sh # creates 'foo.cpp'
548+
549+
bar.cpp: bar.h generate_bar.sh
550+
./generate_bar.sh # creates 'bar.cpp'
551+
552+
...
553+
```
554+
555+
The `*.o` files in `OJBS` are passed to the linker when the `app.out` binary
556+
file is created.
557+
558+
The `GENERATED` is not strictly required, since the default rules already know
559+
how to compile the `*.o` files from the `*.cpp` or `*.c` files. The primary
560+
effect of `GENERATED` currently is to cause the generated files to be removed
561+
when `make clean` is called.
562+
538563
<a name="AlternateArduinoCore"></a>
539564
### Alternate Arduino Core
540565

@@ -694,6 +719,45 @@ start:
694719
When the program crashes because of a `nullptr` dereference, Valgrind will show
695720
exactly where that happened in the source code.
696721

722+
<a name="DigitalReadValue"></a>
723+
### Controlling digitalRead()
724+
725+
By default, the `digitalRead(pin)` function simply returns a 0, because
726+
EpoxyDuino does not actually have any hardware pins. For testing purposes, it
727+
can be useful to control the value that will be returned by a `digitalRead()`.
728+
729+
The `digitalReadValue(pin, val)` function sets the value that will be returned
730+
by the corresponding `digitalRead(pin)`. Here is an example of how this can be
731+
used:
732+
733+
```C++
734+
#include <Arduino.h>
735+
736+
...
737+
const uint8_t PIN = 8;
738+
739+
void something() {
740+
uint8_t val = digitalRead(PIN); // val == 0
741+
742+
#if defined(EPOXY_DUINO)
743+
digitalReadValue(PIN, 1);
744+
#endif
745+
val = digitalRead(PIN); // val == 1
746+
747+
#if defined(EPOXY_DUINO)
748+
digitalReadValue(PIN, 0);
749+
#endif
750+
val = digitalRead(PIN); // val == 0
751+
}
752+
```
753+
754+
The `#if defined(EPOXY_DUINO)` is recommended because `digitalReadValue()` is
755+
not a standard Arduino function. It is defined only in EpoxyDuino.
756+
757+
The `pin` parameter should satisfy `0 <= pin < 32`. If `pin >= 32`, then
758+
`digitalReadValue()` is a no-op and the corresponding `digitalRead(pin)` will
759+
always return 0.
760+
697761
<a name="SupportedArduinoFeatures"></a>
698762
## Supported Arduino Features
699763

@@ -799,8 +863,6 @@ worth the trade-off.
799863
<a name="UnixLineMode"></a>
800864
#### Unix Line Mode
801865

802-
(Added in v1.2.0)
803-
804866
The `Print` class in the Arduino API implements the `Print::println()` function
805867
by printing the DOS line terminator characters `\r\n`. This decision make sense
806868
when the serial port of the microcontroller is connected to a serial terminal,
@@ -873,8 +935,6 @@ test(myTest) {
873935
<a name="EnableTerminalEcho"></a>
874936
#### Enable Terminal Echno
875937
876-
(Added in v1.2.3)
877-
878938
By default, the `stdin` of the terminal is set to `NOECHO` mode for consistency
879939
with the actual serial port of an Arduino microcontroller. However when running
880940
a command line utility on a Unix terminal emulator using EpoxyDuino, it is often
@@ -1004,6 +1064,9 @@ intended. This limitation may be sufficient for Continuous Integration purposes.
10041064
library.
10051065
* [EpoxyMockFastLED](libraries/EpoxyMockFastLED/)
10061066
* Mock version of the FastLED (https://github.com/FastLED/FastLED) library.
1067+
* [EpoxyMockSTM32RTC](libraries/EpoxyMockSTM32RTC/)
1068+
* Mock version of the STM32RTC (https://github.com/stm32duino/STM32RTC)
1069+
library.
10071070
* EspMock (https://github.com/hsaturn/EspMock)
10081071
* This is a separate project that provides various mocks for functions and
10091072
libraries included with the ESP8266 and the ESP32 processors.
@@ -1015,18 +1078,18 @@ intended. This limitation may be sufficient for Continuous Integration purposes.
10151078

10161079
This library has Tier 1 support on:
10171080

1018-
* Ubuntu 18.04
1019-
* g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
1020-
* clang++ 8.0.0-3~ubuntu18.04.2
1021-
* clang++ 6.0.0-1ubuntu2
1022-
* GNU Make 4.1
1023-
* Ubuntu 20.04
1024-
* g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
1081+
* Ubuntu 20.04.4 LTS
1082+
* g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
10251083
* clang++ version 10.0.0-4ubuntu1
10261084
* GNU Make 4.2.1
10271085

10281086
The following environments are Tier 2 because I do not test them often enough:
10291087

1088+
* Ubuntu 18.04 LTS
1089+
* g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
1090+
* clang++ 8.0.0-3~ubuntu18.04.2
1091+
* clang++ 6.0.0-1ubuntu2
1092+
* GNU Make 4.1
10301093
* Raspbian GNU/Linux 10 (buster)
10311094
* On Raspberry Pi Model 3B
10321095
* g++ (Raspbian 8.3.0-6+rpi1) 8.3.0
@@ -1136,3 +1199,6 @@ people ask similar questions later.
11361199
see [PR#32](https://github.com/bxparks/EpoxyDuino/pull/32).
11371200
* Simplify `StdioSerial` by Bernhard (@felias-fogg),
11381201
[Issue#43](https://github.com/bxparks/EpoxyDuino/issues/43).
1202+
* Add `digitalReadValue(pin, val)` to control the return value of
1203+
`digitalRead(pin)` by @CaioPellicani. See
1204+
[PR#61](https://github.com/bxparks/EpoxyDuino/pull/61).

cores/epoxy/Arduino.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
// Arduino methods emulated in Unix
2222
// -----------------------------------------------------------------------
2323

24+
static uint32_t digitalPinValues = 0;
25+
2426
void yield() {
2527
usleep(1000); // prevents program from consuming 100% CPU
2628
}
@@ -29,7 +31,21 @@ void pinMode(uint8_t /*pin*/, uint8_t /*mode*/) {}
2931

3032
void digitalWrite(uint8_t /*pin*/, uint8_t /*val*/) {}
3133

32-
int digitalRead(uint8_t /*pin*/) { return 0; }
34+
int digitalRead(uint8_t pin) {
35+
if (pin >= 32) return 0;
36+
37+
return (digitalPinValues & (((uint32_t)0x1) << pin)) != 0;
38+
}
39+
40+
void digitalReadValue(uint8_t pin, uint8_t val) {
41+
if (pin >= 32) return;
42+
43+
if (val == 0) {
44+
digitalPinValues &= ~(((uint32_t)0x1) << pin);
45+
} else {
46+
digitalPinValues |= ((uint32_t)0x1) << pin;
47+
}
48+
}
3349

3450
int analogRead(uint8_t /*pin*/) { return 0; }
3551

cores/epoxy/Arduino.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#define EPOXY_DUINO_EPOXY_ARDUINO_H
1515

1616
// xx.yy.zz => xxyyzz (without leading 0)
17-
#define EPOXY_DUINO_VERSION 10203
18-
#define EPOXY_DUINO_VERSION_STRING "1.2.3"
17+
#define EPOXY_DUINO_VERSION 10300
18+
#define EPOXY_DUINO_VERSION_STRING "1.3.0"
1919

2020
#include <algorithm> // min(), max()
2121
#include <cmath> // abs()
@@ -223,6 +223,18 @@ void analogWrite(uint8_t pin, int val);
223223
void analogWriteRange(uint32_t range);
224224
#endif
225225

226+
/**
227+
* Control the value that will be returned by `digitalRead(pin)` by setting it
228+
* to `val`, where `val` is either 0 or 1. This may be useful for testing
229+
* purposes. This works only if `pin < 32` because the underlying implementation
230+
* uses a `uint32_t` for storage. If the `pin` is greater than or equal to 32,
231+
* this function does nothing and `digitalRead(pin)` will return 0.
232+
*
233+
* This function is available only on EpoxyDuino. It is not a standard Arduino
234+
* function, so it is not available when compiling on actual hardware.
235+
*/
236+
void digitalReadValue(uint8_t pin, uint8_t val);
237+
226238
unsigned long millis();
227239
unsigned long micros();
228240
void delay(unsigned long ms);

0 commit comments

Comments
 (0)