Skip to content

Commit b6b3fcd

Browse files
authored
#1 get logging working - tested on ESP32 so far (#2)
Get logging working Arduino, incorporate testing
1 parent ebe6616 commit b6b3fcd

13 files changed

Lines changed: 277 additions & 71 deletions

File tree

.github/workflows/test.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Test
2+
on: [push]
3+
4+
jobs:
5+
test:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v4
9+
- uses: actions/cache@v4
10+
with:
11+
path: |
12+
~/.cache/pip
13+
~/.platformio/.cache
14+
key: ${{ runner.os }}-pio
15+
- name: Install dependencies
16+
run: sudo apt-get update && sudo apt-get install -y libsdl2-2.0-0
17+
- uses: actions/setup-python@v5
18+
with:
19+
python-version: '3.12'
20+
- name: Install PlatformIO Core
21+
run: pip install --upgrade platformio
22+
- name: Set up QEMU
23+
id: setup-qemu
24+
run: |
25+
if [[ "$(uname -m)" == "x86_64" ]]; then
26+
QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-x86_64-linux-gnu.tar.xz"
27+
elif [[ "$(uname -m)" == "aarch64" ]]; then
28+
QEMU_URL="https://github.com/espressif/qemu/releases/download/esp-develop-8.2.0-20240122/qemu-xtensa-softmmu-esp_develop_8.2.0_20240122-aarch64-linux-gnu.tar.xz"
29+
else
30+
echo "Unsupported architecture: $(uname -m)"
31+
exit 1
32+
fi
33+
wget $QEMU_URL -O qemu.tar.xz
34+
mkdir -p qemu
35+
tar -xf qemu.tar.xz -C qemu --strip-components=1
36+
sudo mv qemu /usr/local/qemu
37+
38+
- name: Add QEMU to PATH
39+
run: echo "/usr/local/qemu/bin" >> $GITHUB_PATH
40+
41+
- name: Run unit tests
42+
run: pio test --without-uploading --project-conf=platformio-test.ini
43+
44+
static-analysis:
45+
runs-on: ubuntu-latest
46+
steps:
47+
- uses: actions/checkout@v4
48+
- uses: actions/cache@v4
49+
with:
50+
path: |
51+
~/.cache/pip
52+
~/.platformio/.cache
53+
key: ${{ runner.os }}-pio
54+
- uses: actions/setup-python@v5
55+
with:
56+
python-version: '3.12'
57+
58+
- name: Install PlatformIO Core
59+
run: pip install --upgrade platformio
60+
61+
- name: Run static analysis
62+
run: pio check

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
# TcMenuLog
22
[![PlatformIO](https://github.com/TcMenu/TcMenuLog/actions/workflows/platformio.yml/badge.svg)](https://github.com/TcMenu/TcMenuLog/actions/workflows/platformio.yml)
3+
[![Test](https://github.com/TcMenu/TcMenuLog/actions/workflows/test.yml/badge.svg)](https://github.com/TcMenu/IoAbstraction/actions/workflows/test.yml)
34
[![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-green.svg)](https://github.com/TcMenu/TcMenuLog/blob/main/LICENSE)
45
[![GitHub release](https://img.shields.io/github/release/TcMenu/TcMenuLog.svg?maxAge=3600)](https://github.com/TcMenu/TcMenuLog/releases)
56
[![davetcc](https://img.shields.io/badge/davetcc-dev-blue.svg)](https://github.com/davetcc)
67
[![JSC TechMinds](https://img.shields.io/badge/JSC-TechMinds-green.svg)](https://www.jsctm.cz)
78

89
TcMenu organisation made this library available for you to use. It takes significant effort to keep all our libraries current and working on a wide range of boards. Please consider making at least a one off donation via the sponsor button if you find it useful. In forks, please keep text to here intact.
910

10-
This library provides several useful extensions that make programming Arduino / mbed for non-trivial apps simpler. You can find examples packaged with it in the `examples` folder.
11+
## Summary
12+
13+
This library provides logging facilities that are used by all our other libraries. You can consider this like a logging API with a simple implementation that backs onto the serial port by default.
14+
15+
The library works on most Arduino devices, PicoSDK and mbed. You can see our library compatibility matrix: https://tcmenu.github.io/documentation/
16+
17+
You can find examples packaged with it in the `examples` folder. The example should work on most platforms without needing changes.
18+
19+
## Supporting another output format
20+
21+
The easiest way would be to create another implementation of `LoggingPort` that met the `Print` (or `PrintCompat`) interface, this will then integrate without changing anything. You can see examples of this in `IoLogging.h` for mbed and PicoSDK.
1122

1223
## License
1324

examples/ioLogging/ioLogging.ino

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/**
2-
* Advanced feature of library.
3-
*
4-
* This example shows how to use the very simple logging that's built into IoAbstraction.
5-
* To enable logging open IoLogging.h in the IoAbstraction directory and uncomment
6-
* #define IO_LOGGING_DEBUG
2+
* This example shows how to use the TcMenu logging framework, to log simple information
3+
* to the serial port. It should work on Arduino, mbed and PicoSDK with little to no
4+
* adjustment.
5+
*
6+
* As this example logs output, either define flag `IO_LOGGING_DEBUG` or open IoLogging.h
7+
* and uncomment `#define IO_LOGGING_DEBUG` to enable.
78
*
89
* This logging is only complied in when the above define is set, if it is not set then
910
* the logging is completely removed.
10-
*
1111
*/
1212

1313
/* The logging levels are below:
@@ -33,8 +33,6 @@
3333
At runtime a level can be turned on/off using: void serEnableLevel(SerLoggingLevel level, bool active)
3434
*/
3535

36-
#include <TaskManagerIO.h>
37-
#include <IoAbstraction.h>
3836
#include <IoLogging.h>
3937

4038
char sz[] = {"hello world"};
@@ -49,38 +47,34 @@ void setup() {
4947

5048
Serial.println("Starting ioLogging example");
5149

52-
// we can use this to start the logging delegate that logs task manager notifications at IOA_DEBUG level
53-
startTaskManagerLogDelegate();
54-
5550
// enable an extra level
5651
serEnableLevel(SER_IOA_DEBUG, true);
5752

5853
// write a string entry that is applied with F(..) so in progmem on AVR
5954
// with an integer second value.
6055
serdebugF2("In setup function - A0=", analogRead(A0));
6156

62-
taskManager.scheduleFixedRate(10, [] {
63-
// write values to log in HEX - first parameter is wrapped in F(..) using the F variant
64-
serlogFHex2(SER_DEBUG, "Two Values in hex: ", 0xFADE, 0xFACE);
65-
serlogFHex(SER_DEBUG, "One Values in hex: ", 0xFADE);
66-
serlogF4(SER_ERROR, "This is an error", 100, 200, 300);
67-
serlogF3(SER_WARNING, "This is an warning", 100, 200);
57+
// write values to log in HEX - first parameter is wrapped in F(..) using the F variant
58+
serlogFHex2(SER_DEBUG, "Two Values in hex: ", 0xFADE, 0xFACE);
59+
serlogFHex(SER_DEBUG, "One Values in hex: ", 0xFADE);
60+
serlogF4(SER_ERROR, "This is an error", 100, 200, 300);
61+
serlogF3(SER_WARNING, "This is an warning", 100, 200);
62+
63+
// log at SER_DEBUG, for legacy support
64+
serdebugF2("Int value: ", 109298384L);
65+
serdebugF2("Bool value: ", true);
6866

69-
// log at SER_DEBUG, for legacy support
70-
serdebugF2("Int value: ", 109298384L);
71-
serdebugF2("Bool value: ", true);
67+
// here we hex dump an array
68+
serlogHexDump(SER_DEBUG, "Hex dump", sz, sizeof sz);
7269

73-
// here we hex dump an array
74-
serlogHexDump(SER_DEBUG, "Hex dump", sz, sizeof sz);
70+
// the F variant always tries to use F(..) to save ram on the first parameter on AVR
71+
serdebugF("String in flash");
7572

76-
// the F variant always tries to use F(..) to save ram on the first parameter on AVR
77-
serdebugF("String in flash");
78-
79-
// this version does not use F(..) so we can pass RAM strings even on AVR
80-
serdebug(sz);
81-
}, TIME_SECONDS);
73+
// this version does not use F(..) so we can pass RAM strings even on AVR
74+
serdebug(sz);
8275
}
8376

8477
void loop() {
85-
taskManager.runLoop();
78+
delay(1000);
79+
serlogF2(SER_USER_1, "Millis: ", millis());
8680
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* This example shows how to use the text utilities that are packaged with TcMenu logging
3+
* framework. It should work on Arduino, mbed and PicoSDK with little to no adjustment.
4+
*
5+
* As this example logs output, either define flag `IO_LOGGING_DEBUG` or open IoLogging.h
6+
* and uncomment `#define IO_LOGGING_DEBUG` to enable.
7+
*
8+
* This logging is only complied in when the above define is set, if it is not set then
9+
* the logging is completely removed.
10+
*
11+
*/
12+
13+
#include <IoLogging.h>
14+
#include <TextUtilities.h>
15+
16+
char sz[32] = {0};
17+
18+
void setup() {
19+
// This example logs using IoLogging, see the following guide to enable
20+
// https://www.thecoderscorner.com/products/arduino-libraries/io-abstraction/arduino-logging-with-io-logging/
21+
IOLOG_START_SERIAL
22+
23+
// convert 102934 to 8 decimal places not padded.
24+
// the clrBuff version also clears the sz buffer first
25+
// IE does not concatenate.
26+
ltoaClrBuff(sz, 102934, 8, NOT_PADDED, sizeof sz);
27+
serlogF2(SER_DEBUG, "Str is: ", sz);
28+
29+
// concatenate 00102934 (to 8 decimal places zero padded).
30+
// this variant concatenates to a zero terminated string
31+
fastltoa(sz, 102934, 8, '0', sizeof sz);
32+
serlogF2(SER_DEBUG, "Str is: ", sz);
33+
34+
// clear the string
35+
sz[0] = 0;
36+
37+
// convert a float into sz string to 4 places.
38+
fastftoa(sz, 1024.512F, 4, sizeof sz);
39+
serlogF2(SER_DEBUG, "Float: ", sz);
40+
41+
// find a power of ten for decimal place calculation
42+
serlogF2(SER_DEBUG, "Dp To Div: ", dpToDivisor(5));
43+
44+
// find the significant places needed to represent a value
45+
serlogF2(SER_DEBUG, "Dp To Div: ", valueToSignificantPlaces(50123, false));
46+
47+
// get the single hex character of a digit between 0..15 and vice versa
48+
serlogF2(SER_DEBUG, "Hexchar: ", hexChar(12));
49+
serlogF2(SER_DEBUG, "HexVal: ", hexValueOf('D'));
50+
51+
// convert a number into a hex string
52+
sz[0]=0;
53+
54+
// convert a int into hex string
55+
intToHexString(sz, sizeof sz, 0xFACE, 4, true);
56+
serlogF2(SER_DEBUG, "Hex str: ", sz);
57+
}
58+
59+
void loop() {
60+
delay(1000);
61+
// convert the time into seconds and then print via logging to 3dp.
62+
float now = millis() / 1000.0F;
63+
sz[0]=0;
64+
fastftoa(sz, now, 3, sizeof sz);
65+
serlogF2(SER_DEBUG, "Time = ", sz);
66+
}

library.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
},
88
"authors": [
99
{
10-
"name": "DaveTcc",
11-
"url": "https://www.thecoderscorner.com",
10+
"name": "TcMenu",
11+
"url": "https://tcmenu.github.io/documentation/",
1212
"maintainer": true
1313
}
1414
],

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
name=TcMenuLog
77
version=1.0.0
8-
maintainer=https://www.thecoderscorner.com
9-
author=davetcc
8+
maintainer=https://tcmenu.github.io/documentation/
9+
author=TcMenu
1010
category=Other
1111
url=https://github.com/TcMenu/TcMenuLog
1212
sentence=Logging framework and helper text utils for the TcMenu framework.

platformio-test.ini

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[env:esp32dev]
2+
platform = espressif32
3+
framework = arduino
4+
board = esp32dev
5+
extra_scripts = post:merge-bin.py
6+
test_build_src = true
7+
8+
test_testing_command =
9+
qemu-system-xtensa
10+
-nographic
11+
-machine
12+
esp32
13+
-drive
14+
file=${platformio.build_dir}/${this.__env__}/firmware-merged.bin,if=mtd,format=raw

platformio.ini

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
[env]
22
framework = arduino
33

4-
lib_deps =
5-
davetcc/TaskManagerIO@^1.4.3
6-
davetcc/IoAbstraction@^4.0.2
7-
84
[env:megaatmega2560]
95
platform = atmelavr
106
board = megaatmega2560

src/IoLogging.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88

99
#include "IoLogging.h"
10-
#include "TaskPlatformDeps.h"
1110

1211
#ifdef IO_LOGGING_DEBUG
1312

@@ -53,30 +52,6 @@ const char* prettyLevel(SerLoggingLevel level) {
5352
}
5453
}
5554

56-
const char* niceErrorCode(tm_internal::TmErrorCode code) {
57-
switch(code) {
58-
case tm_internal::TM_INFO_REALLOC:
59-
return "mem";
60-
case tm_internal::TM_INFO_TASK_ALLOC:
61-
return "alloc";
62-
case tm_internal::TM_INFO_TASK_FREE:
63-
return "free";
64-
case tm_internal::TM_WARN_HIGH_SPINCOUNT:
65-
return "spin";
66-
case tm_internal::TM_ERROR_FULL:
67-
return "full";
68-
default:
69-
case tm_internal::TM_ERROR_LOCK_FAILURE:
70-
return "err";
71-
}
72-
}
73-
74-
void startTaskManagerLogDelegate() {
75-
tm_internal::setLoggingDelegate([](tm_internal::TmErrorCode errorCode, int task) {
76-
serlogF3(SER_IOA_DEBUG, "TMLog ", niceErrorCode(errorCode), task);
77-
});
78-
}
79-
8055
#ifdef BUILD_FOR_PICO_CMAKE
8156
PrintfLogger LoggingPort;
8257
#endif

src/IoLogging.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
* by un-commenting the define. Should NOT be used in production.
88
*/
99

10-
#include "PlatformDetermination.h"
11-
1210
// START user adjustable section.
1311

1412
// the below definition controls logging, enable logging by either defining this build flag
@@ -46,12 +44,19 @@ enum SerLoggingLevel {
4644
SER_LOG_EVERYTHING = 0xffff
4745
};
4846

47+
#if defined(__MBED__) && !defined(BUILD_FOR_PICO_CMAKE) && !defined(ARDUINO_ARCH_MBED)
48+
#define LOGGING_USES_MBED
49+
#elif !defined(BUILD_FOR_PICO_CMAKE)
50+
#include <Arduino.h>
51+
#endif
52+
4953
#ifdef IO_LOGGING_DEBUG
5054

55+
5156
/** This uint16_t stores the enabled logging levels, don't use directly */
5257
extern unsigned int enabledLevels;
5358

54-
#ifdef IOA_USE_MBED
59+
#ifdef LOGGING_USES_MBED
5560

5661
#include "PrintCompat.h"
5762
#include <FileHandle.h>
@@ -125,14 +130,14 @@ unsigned long millis(); // available from task manager
125130
#else
126131
// Arduino:
127132
// You can change the logging serial port by defining LoggingPort to your chosen serial port.
133+
#include <Arduino.h>
128134
#ifndef LoggingPort
129135
#define LoggingPort Serial
130136
#endif
131137
#define IOLOG_START_SERIAL LoggingPort.begin(115200);
132138
#define IOLOG_MBED_PORT_IF_NEEDED(tx, rx)
133139
#endif
134140

135-
136141
const char* prettyLevel(SerLoggingLevel level);
137142
#define logTimeAndLevel(title, lvl) LoggingPort.print(millis());LoggingPort.print('-');LoggingPort.print(prettyLevel(lvl));LoggingPort.print(':');LoggingPort.print(title)
138143

@@ -181,7 +186,8 @@ inline void serdebugHexDump(const char *title, const void* data, size_t len) { s
181186
#define serdebug3(x1, x2, x3) serlog3(SER_DEBUG, x1, x2, x3)
182187
#define serdebugHex(x1, x2) serlogHex(SER_DEBUG, x1, x2)
183188

184-
void startTaskManagerLogDelegate();
189+
// no longer does anything but don't want code compilation errors.
190+
#define startTaskManagerLogDelegate()
185191

186192
#else
187193
// all loging to no operations (commenting out the above define of IO_LOGGING_DEBUG to remove in production builds).

0 commit comments

Comments
 (0)