Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 3102f22

Browse files
authored
v1.5.0 to fix multiple-definitions linker error
### Release v1.5.0 1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories 2. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project. 3. Optimize library code by using `reference-passing` instead of `value-passing` 4. Update all examples
1 parent ef71002 commit 3102f22

28 files changed

+1046
-766
lines changed

CONTRIBUTING.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
1414

1515
Please ensure to specify the following:
1616

17-
* Arduino IDE version (e.g. 1.8.16) or Platform.io version
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
1818
* `Arduino megaAVR` Core Version (e.g. Arduino megaAVR core v1.8.7)
1919
* Contextual information (e.g. what you were trying to achieve)
2020
* Simplest possible steps to reproduce
@@ -26,10 +26,10 @@ Please ensure to specify the following:
2626
### Example
2727

2828
```
29-
Arduino IDE version: 1.8.16
29+
Arduino IDE version: 1.8.19
3030
Arduino megaAVR Core Version 1.8.7
3131
OS: Ubuntu 20.04 LTS
32-
Linux xy-Inspiron-3593 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
32+
Linux xy-Inspiron-3593 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3333
3434
Context:
3535
I encountered a crash while trying to use the Timer Interrupt.

README.md

+54-32
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
## Table of Contents
1010

11+
* [Important Change from v1.5.0](#Important-Change-from-v150)
1112
* [Why do we need this megaAVR_TimerInterrupt library](#why-do-we-need-this-megaavr_timerinterrupt-library)
1213
* [Features](#features)
1314
* [Why using ISR-based Hardware Timer Interrupt is better](#why-using-isr-based-hardware-timer-interrupt-is-better)
@@ -46,6 +47,7 @@
4647
* [ 11. SwitchDebounce](examples/SwitchDebounce)
4748
* [ 12. TimerDuration](examples/TimerDuration)
4849
* [ 13. TimerInterruptTest](examples/TimerInterruptTest)
50+
* [ 14. **multiFileProject**](examples/multiFileProject) **New**
4951
* [Example ISR_16_Timers_Array_Complex](#example-isr_16_timers_array_complex)
5052
* [Debug Terminal Output Samples](#debug-terminal-output-samples)
5153
* [1. ISR_16_Timers_Array_Complex on Arduino megaAVR Nano Every](#1-isr_16_timers_array_complex-on-arduino-megaavr-nano-every)
@@ -68,6 +70,10 @@
6870
---
6971
---
7072

73+
### Important Change from v1.5.0
74+
75+
Please have a look at [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error)
76+
7177
### Why do we need this [megaAVR_TimerInterrupt library](https://github.com/khoih-prog/megaAVR_TimerInterrupt)
7278

7379
### Features
@@ -124,9 +130,11 @@ The catch is your function is now part of an ISR (Interrupt Service Routine), an
124130

125131
## Prerequisites
126132

127-
1. [`Arduino IDE 1.8.13+` for Arduino](https://www.arduino.cc/en/Main/Software)
133+
1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest)
128134
2. [`Arduino megaAVR core 1.8.7+`](https://github.com/arduino/ArduinoCore-megaavr/releases) for Arduino megaAVR boards. Use Arduino Board Manager to install.
129-
135+
3. To use with certain example
136+
- [`SimpleTimer library`](https://github.com/jfturcot/SimpleTimer) for [ISR_Timers_Array_Simple](examples/ISR_Timers_Array_Simple) and [ISR_16_Timers_Array_Complex](examples/ISR_16_Timers_Array_Complex) examples.
137+
130138
---
131139
---
132140

@@ -158,24 +166,29 @@ Another way to install is to:
158166

159167
### HOWTO Fix `Multiple Definitions` Linker Error
160168

161-
The current library implementation, using **xyz-Impl.h instead of standard xyz.cpp**, possibly creates certain `Multiple Definitions` Linker error in certain use cases. Although it's simple to just modify several lines of code, either in the library or in the application, the library is adding 2 more source directories
169+
The current library implementation, using `xyz-Impl.h` instead of standard `xyz.cpp`, possibly creates certain `Multiple Definitions` Linker error in certain use cases.
162170

163-
1. **scr_h** for new h-only files
164-
2. **src_cpp** for standard h/cpp files
171+
You can include these `.hpp` files
165172

166-
besides the standard **src** directory.
173+
```
174+
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
175+
#include "megaAVR_TimerInterrupt.hpp" //https://github.com/khoih-prog/megaAVR_TimerInterrupt
167176
168-
To use the **old standard cpp** way, locate this library' directory, then just
177+
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
178+
#include "megaAVR_ISR_Timer.hpp" //https://github.com/khoih-prog/megaAVR_TimerInterrupt
179+
```
169180

170-
1. **Delete the all the files in src directory.**
171-
2. **Copy all the files in src_cpp directory into src.**
172-
3. Close then reopen the application code in Arduino IDE, etc. to recompile from scratch.
181+
in many files. But be sure to use the following `.h` files **in just 1 `.h`, `.cpp` or `.ino` file**, which must **not be included in any other file**, to avoid `Multiple Definitions` Linker Error
173182

174-
To re-use the **new h-only** way, just
183+
```
184+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
185+
#include "megaAVR_TimerInterrupt.h" //https://github.com/khoih-prog/megaAVR_TimerInterrupt
175186
176-
1. **Delete the all the files in src directory.**
177-
2. **Copy the files in src_h directory into src.**
178-
3. Close then reopen the application code in Arduino IDE, etc. to recompile from scratch.
187+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
188+
#include "megaAVR_ISR_Timer.h" //https://github.com/khoih-prog/megaAVR_TimerInterrupt
189+
```
190+
191+
Check the new [**multiFileProject** example](examples/multiFileProject) for a `HOWTO` demo.
179192

180193
---
181194
---
@@ -407,17 +420,22 @@ void setup()
407420
11. [SwitchDebounce](examples/SwitchDebounce)
408421
12. [TimerDuration](examples/TimerDuration)
409422
13. [TimerInterruptTest](examples/TimerInterruptTest)
423+
14. [**multiFileProject**](examples/multiFileProject) **New**
410424

411425
---
412426

413427
### Example [ISR_16_Timers_Array_Complex](examples/ISR_16_Timers_Array_Complex)
414428

415429
```cpp
430+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
431+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
432+
#endif
433+
416434
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
417435
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
418436
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
419437
#define TIMER_INTERRUPT_DEBUG 0
420-
#define _TIMERINTERRUPT_LOGLEVEL_ 0
438+
#define _TIMERINTERRUPT_LOGLEVEL_ 3
421439

422440
// Select USING_16MHZ == true for 16MHz to Timer TCBx => shorter timer, but better accuracy
423441
// Select USING_8MHZ == true for 8MHz to Timer TCBx => shorter timer, but better accuracy
@@ -433,10 +451,13 @@ void setup()
433451
#define USE_TIMER_2 true
434452
#define USE_TIMER_3 false
435453

454+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
436455
#include "megaAVR_TimerInterrupt.h"
456+
457+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
437458
#include "megaAVR_ISR_Timer.h"
438459

439-
#include <SimpleTimer.h> // https://github.com/schinken/SimpleTimer
460+
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
440461

441462
#ifndef LED_BUILTIN
442463
#define LED_BUILTIN 13
@@ -762,9 +783,8 @@ The following is the sample terminal output when running example [ISR_16_Timers_
762783
While software timer, **programmed for 2s, is activated after more than 10.000s in loop().
763784
764785
```
765-
766786
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
767-
megaAVR_TimerInterrupt v1.4.0
787+
megaAVR_TimerInterrupt v1.5.0
768788
CPU Frequency = 16 MHz
769789
TCB Clock Frequency = 250KHz for lower accuracy but longer time
770790
Starting ITimer1 OK, millis() = 6
@@ -916,7 +936,7 @@ The following is the sample terminal output when running example [Change_Interva
916936
917937
```
918938
Starting Change_Interval on megaAVR Nano Every
919-
megaAVR_TimerInterrupt v1.4.0
939+
megaAVR_TimerInterrupt v1.5.0
920940
CPU Frequency = 16 MHz
921941
TCB Clock Frequency = 250KHz for lower accuracy but longer time
922942
Starting ITimer1 OK, millis() = 1
@@ -945,7 +965,7 @@ Changing Interval, Timer1 = 100, Timer2 = 200
945965
946966
```
947967
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
948-
megaAVR_TimerInterrupt v1.4.0
968+
megaAVR_TimerInterrupt v1.5.0
949969
CPU Frequency = 16 MHz
950970
TCB Clock Frequency = 16MHz for highest accuracy
951971
Starting ITimer1 OK, millis() = 6
@@ -1031,7 +1051,7 @@ Timer : 15, programmed : 80000, actual : 80000
10311051
```
10321052

10331053
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
1034-
megaAVR_TimerInterrupt v1.4.0
1054+
megaAVR_TimerInterrupt v1.5.0
10351055
CPU Frequency = 16 MHz
10361056
TCB Clock Frequency = 8MHz for very high accuracy
10371057
Starting ITimer1 OK, millis() = 10
@@ -1099,7 +1119,7 @@ Timer : 15, programmed : 80000, actual : 80000
10991119
11001120
```
11011121
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
1102-
megaAVR_TimerInterrupt v1.4.0
1122+
megaAVR_TimerInterrupt v1.5.0
11031123
CPU Frequency = 16 MHz
11041124
TCB Clock Frequency = 250KHz for lower accuracy but longer time
11051125
Starting ITimer1 OK, millis() = 11
@@ -1185,7 +1205,7 @@ The following is the sample terminal output when running example [Change_Interva
11851205
11861206
```
11871207
Starting Change_Interval_HF on megaAVR Nano Every
1188-
megaAVR_TimerInterrupt v1.4.0
1208+
megaAVR_TimerInterrupt v1.5.0
11891209
CPU Frequency = 16 MHz
11901210
TCB Clock Frequency = 16MHz for highest accuracy
11911211
[TISR] TCB 1
@@ -1257,15 +1277,17 @@ Submit issues to: [megaAVR_TimerInterrupt issues](https://github.com/khoih-prog/
12571277

12581278
### DONE
12591279

1260-
1. Longer Interval for timers.
1261-
2. Reduce code size if use less timers. Eliminate compiler warnings.
1262-
3. Now supporting complex object pointer-type argument.
1263-
3. 16 hardware-initiated software-enabled timers while using only 1 hardware timer.
1264-
4. Fix some bugs in v1.0.0
1265-
5. Add more examples.
1266-
6. Similar library for ESP32, ESP8266, SAMD21/SAMD51, nRF52, Mbed-OS Nano-33-BLE, STM32
1267-
7. Add support to ATmega4809-based boards, such as **Arduino UNO WiFi Rev2, AVR_NANO_EVERY, etc.**
1268-
8. Selectable **TCB Clock 16MHz, 8MHz or 250KHz** depending on necessary accuracy
1280+
1. Longer Interval for timers.
1281+
2. Reduce code size if use less timers. Eliminate compiler warnings.
1282+
3. Now supporting complex object pointer-type argument.
1283+
4. 16 hardware-initiated software-enabled timers while using only 1 hardware timer.
1284+
5. Fix some bugs in v1.0.0
1285+
6. Add more examples.
1286+
7. Similar library for ESP32, ESP8266, SAMD21/SAMD51, nRF52, Mbed-OS Nano-33-BLE, STM32
1287+
8. Add support to ATmega4809-based boards, such as **Arduino UNO WiFi Rev2, AVR_NANO_EVERY, etc.**
1288+
9. Selectable **TCB Clock 16MHz, 8MHz or 250KHz** depending on necessary accuracy
1289+
10. Fix `multiple-definitions` linker error
1290+
11. Optimize library code by using `reference-passing` instead of `value-passing`
12691291

12701292
---
12711293
---

changelog.md

+8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
## Table of Contents
1010

1111
* [Changelog](#changelog)
12+
* [Release v1.5.0](#release-v150)
1213
* [Release v1.4.0](#release-v140)
1314
* [Release v1.3.0](#release-v130)
1415
* [Release v1.2.0](#release-v120)
@@ -20,6 +21,13 @@
2021

2122
## Changelog
2223

24+
### Release v1.5.0
25+
26+
1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
27+
2. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project.
28+
3. Optimize library code by using `reference-passing` instead of `value-passing`
29+
4. Update all examples
30+
2331
### Release v1.4.0
2432

2533
1. Fix TCB Clock bug in high frequencies. Check [Interrupt interval 2X requested interval #1](https://github.com/khoih-prog/megaAVR_TimerInterrupt/issues/1)

examples/Argument_Complex/Argument_Complex.ino

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
*****************************************************************************************************************************/
1515

16+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
17+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
18+
#endif
19+
1620
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
1721
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
1822
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -32,6 +36,7 @@
3236
#define USE_TIMER_2 false
3337
#define USE_TIMER_3 false
3438

39+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
3540
#include "megaAVR_TimerInterrupt.h"
3641

3742
#if !defined(LED_BUILTIN)

examples/Argument_None/Argument_None.ino

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
*****************************************************************************************************************************/
1515

16+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
17+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
18+
#endif
19+
1620
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
1721
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
1822
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -32,6 +36,7 @@
3236
#define USE_TIMER_2 false
3337
#define USE_TIMER_3 false
3438

39+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
3540
#include "megaAVR_TimerInterrupt.h"
3641

3742
#define TIMER1_INTERVAL_MS 1000

examples/Argument_Simple/Argument_Simple.ino

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
*****************************************************************************************************************************/
1515

16+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
17+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
18+
#endif
19+
1620
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
1721
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
1822
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -32,6 +36,7 @@
3236
#define USE_TIMER_2 false
3337
#define USE_TIMER_3 false
3438

39+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
3540
#include "megaAVR_TimerInterrupt.h"
3641

3742
#if !defined(LED_BUILTIN)

examples/Change_Interval/Change_Interval.ino

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
or the entire sequence of your code which accesses the data.
2626
*/
2727

28+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
29+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
30+
#endif
31+
2832
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
2933
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
3034
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -44,6 +48,7 @@
4448
#define USE_TIMER_2 true
4549
#define USE_TIMER_3 false
4650

51+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
4752
#include "megaAVR_TimerInterrupt.h"
4853

4954
#if !defined(LED_BUILTIN)

examples/Change_Interval_HF/Change_Interval_HF.ino

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
or the entire sequence of your code which accesses the data.
2626
*/
2727

28+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
29+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
30+
#endif
31+
2832
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
2933
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
3034
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -44,6 +48,7 @@
4448
#define USE_TIMER_2 false
4549
#define USE_TIMER_3 false
4650

51+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
4752
#include "megaAVR_TimerInterrupt.h"
4853

4954
#if !defined(LED_BUILTIN)

examples/FakeAnalogWrite/FakeAnalogWrite.ino

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
2424
or the entire sequence of your code which accesses the data.
2525
*/
26+
27+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
28+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
29+
#endif
2630

2731
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
2832
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
@@ -45,6 +49,7 @@
4549
#define USE_TIMER_2 false
4650
#define USE_TIMER_3 false
4751

52+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
4853
#include "megaAVR_TimerInterrupt.h"
4954

5055
#ifndef LED_BUILTIN

examples/ISR_16_Timers_Array_Complex/ISR_16_Timers_Array_Complex.ino

+8-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
*****************************************************************************************************************************/
1515

16+
#if !( defined(__AVR_ATmega4809__) || defined(ARDUINO_AVR_UNO_WIFI_REV2) || defined(ARDUINO_AVR_NANO_EVERY) )
17+
#error This is designed only for Arduino megaAVR board! Please check your Tools->Board setting.
18+
#endif
19+
1620
// These define's must be placed at the beginning before #include "megaAVR_TimerInterrupt.h"
1721
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
1822
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
@@ -33,10 +37,13 @@
3337
#define USE_TIMER_2 true
3438
#define USE_TIMER_3 false
3539

40+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
3641
#include "megaAVR_TimerInterrupt.h"
42+
43+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
3744
#include "megaAVR_ISR_Timer.h"
3845

39-
#include <SimpleTimer.h> // https://github.com/schinken/SimpleTimer
46+
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
4047

4148
#ifndef LED_BUILTIN
4249
#define LED_BUILTIN 13

0 commit comments

Comments
 (0)