Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/scripts/sketch_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,12 @@ function build_sketch { # build_sketch <ide_path> <user_path> <path-to-ino> [ext
cp -f "$ci_yml_source/ci.yml" "$build_dir/ci.yml" 2>/dev/null || true
fi

if [ -n "$COMPILE_COMMANDS_DIR" ] && [ -f "$build_dir/compile_commands.json" ]; then
mkdir -p "$COMPILE_COMMANDS_DIR"
jq --arg t "$target" '[.[] | . + {_target: $t}]' \
"$build_dir/compile_commands.json" > "$COMPILE_COMMANDS_DIR/${target}_${sketchname}.json"
fi

if [ -n "$log_compilation" ]; then
#Extract the program storage space and dynamic memory usage in bytes and percentage in separate variables from the output, just the value without the string
flash_bytes=$(grep -oE 'Sketch uses ([0-9]+) bytes' "$output_file" | awk '{print $3}')
Expand Down
36 changes: 36 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ jobs:
echo "LOG_LEVEL=none" >> $GITHUB_ENV
fi

- name: Enable compile commands collection
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
run: echo "COMPILE_COMMANDS_DIR=${{ github.workspace }}/compile_commands" >> $GITHUB_ENV

- name: Download affected sketches
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
Expand All @@ -181,6 +185,15 @@ jobs:
path: cli_compile_${{ matrix.chunk }}.json
overwrite: true

- name: Upload compile commands
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: compile_commands_${{ matrix.chunk }}
path: compile_commands/
if-no-files-found: warn
overwrite: true

# Windows and MacOS
build-arduino-win-mac:
name: Arduino on ${{ matrix.os }}
Expand Down Expand Up @@ -246,6 +259,29 @@ jobs:
git commit -m "Updated cli compile json files"
git push origin HEAD:gh-pages

# Merge compile_commands.json from all chunks into a single file
merge-compile-commands:
name: Merge compile commands
needs: build-arduino-linux
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Download compile commands artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
pattern: compile_commands_*
merge-multiple: true
path: compile_commands

- name: Merge compile commands
run: jq -s 'add | unique_by(.file + "_" + ._target) | [.[] | del(._target)]' compile_commands/*.json > compile_commands.json

- name: Upload merged compile commands
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: compile_commands
path: compile_commands.json

#Upload PR number as artifact
upload-pr-number:
name: Upload PR number
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ set(CORE_SRCS
cores/esp32/stdlib_noniso.c
cores/esp32/Stream.cpp
cores/esp32/StreamString.cpp
cores/esp32/StringUtils.cpp
cores/esp32/Tone.cpp
cores/esp32/HWCDC.cpp
cores/esp32/USB.cpp
Expand Down
28 changes: 14 additions & 14 deletions cores/esp32/FirmwareMSC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ static size_t msc_update_get_required_disk_sectors() {
if (msc_run_partition) {
fw_size = get_firmware_size(msc_run_partition);
data_sectors += FAT_SIZE_TO_SECTORS(fw_size);
log_d("APP size: %u (%u sectors)", fw_size, FAT_SIZE_TO_SECTORS(fw_size));
log_d("APP size: %lu (%lu sectors)", (unsigned long)fw_size, (unsigned long)FAT_SIZE_TO_SECTORS(fw_size));
} else {
log_w("APP partition not found. Reading disabled");
}
if (msc_ota_partition) {
data_sectors += FAT_SIZE_TO_SECTORS(msc_ota_partition->size);
log_d("OTA size: %u (%u sectors)", msc_ota_partition->size, FAT_SIZE_TO_SECTORS(msc_ota_partition->size));
log_d("OTA size: %lu (%lu sectors)", (unsigned long)msc_ota_partition->size, (unsigned long)FAT_SIZE_TO_SECTORS(msc_ota_partition->size));
} else {
log_w("OTA partition not found. Writing disabled");
}
Expand All @@ -116,9 +116,9 @@ static size_t msc_update_get_required_disk_sectors() {
mcs_is_fat16 = false;
}
log_d("FAT sector size: %u", DISK_SECTOR_SIZE);
log_d("FAT data sectors: %u", data_sectors);
log_d("FAT data sectors: %lu", (unsigned long)data_sectors);
log_d("FAT table sectors: %u", msc_table_sectors);
log_d("FAT total sectors: %u (%uKB)", total_sectors, (total_sectors * DISK_SECTOR_SIZE) / 1024);
log_d("FAT total sectors: %lu (%luKB)", (unsigned long)total_sectors, (unsigned long)(total_sectors * DISK_SECTOR_SIZE) / 1024);
return total_sectors;
}

Expand All @@ -128,7 +128,7 @@ static bool msc_update_setup_disk(const char *volume_label, uint32_t serial_numb
uint8_t ram_sectors = msc_table_sectors + 2;
msc_ram_disk = (uint8_t *)calloc(ram_sectors, DISK_SECTOR_SIZE);
if (!msc_ram_disk) {
log_e("Failed to allocate RAM Disk: %u bytes", ram_sectors * DISK_SECTOR_SIZE);
log_e("Failed to allocate RAM Disk: %lu bytes", (unsigned long)ram_sectors * DISK_SECTOR_SIZE);
return false;
}
fw_start_sector = ram_sectors;
Expand Down Expand Up @@ -219,7 +219,7 @@ static esp_err_t msc_update_write(const esp_partition_t *partition, uint32_t off
esp_err_t err = ESP_OK;
if ((offset & (SPI_FLASH_SEC_SIZE - 1)) == 0) {
err = esp_partition_erase_range(partition, offset, SPI_FLASH_SEC_SIZE);
log_v("ERASE[0x%08X]: %s", offset, (err != ESP_OK) ? "FAIL" : "OK");
log_v("ERASE[0x%08" PRIX32 "]: %s", offset, (err != ESP_OK) ? "FAIL" : "OK");
if (err != ESP_OK) {
return err;
}
Expand All @@ -229,7 +229,7 @@ static esp_err_t msc_update_write(const esp_partition_t *partition, uint32_t off

//called when error was encountered while updating
static void msc_update_error() {
log_e("UPDATE_ERROR: %u", msc_update_bytes_written);
log_e("UPDATE_ERROR: %" PRIu32, msc_update_bytes_written);
arduino_firmware_msc_event_data_t p;
p.error.size = msc_update_bytes_written;
arduino_usb_event_post(ARDUINO_FIRMWARE_MSC_EVENTS, ARDUINO_FIRMWARE_MSC_ERROR_EVENT, &p, sizeof(arduino_firmware_msc_event_data_t), portMAX_DELAY);
Expand All @@ -241,11 +241,11 @@ static void msc_update_error() {

//called when all firmware bytes have been received
static void msc_update_end() {
log_d("UPDATE_END: %u", msc_update_entry->file_size);
log_d("UPDATE_END: %" PRIu32, msc_update_entry->file_size);
msc_update_state = MSC_UPDATE_END;
size_t ota_size = get_firmware_size(msc_ota_partition);
if (ota_size != msc_update_entry->file_size) {
log_e("OTA SIZE MISMATCH %u != %u", ota_size, msc_update_entry->file_size);
log_e("OTA SIZE MISMATCH %lu != %" PRIu32, (unsigned long)ota_size, msc_update_entry->file_size);
msc_update_error();
return;
}
Expand All @@ -260,7 +260,7 @@ static void msc_update_end() {
}

static int32_t msc_write(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_t bufsize) {
//log_d("lba: %u, offset: %u, bufsize: %u", lba, offset, bufsize);
//log_d("lba: %" PRIu32 ", offset: %" PRIu32 ", bufsize: %" PRIu32, lba, offset, bufsize);
if (lba < fw_start_sector) {
//write to sectors that are in RAM
memcpy(msc_ram_disk + (lba * DISK_SECTOR_SIZE) + offset, buffer, bufsize);
Expand Down Expand Up @@ -297,10 +297,10 @@ static int32_t msc_write(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_
msc_update_state = MSC_UPDATE_RUNNING;
msc_update_start_sector = lba;
msc_update_bytes_written = 0;
log_d("UPDATE_START: %u (0x%02X)", lba, lba - msc_boot->sectors_per_alloc_table);
log_d("UPDATE_START: %" PRIu32 " (0x%02" PRIX32 ")", lba, lba - msc_boot->sectors_per_alloc_table);
arduino_usb_event_post(ARDUINO_FIRMWARE_MSC_EVENTS, ARDUINO_FIRMWARE_MSC_START_EVENT, &p, sizeof(arduino_firmware_msc_event_data_t), portMAX_DELAY);
if (msc_update_write(msc_ota_partition, ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, buffer, bufsize) == ESP_OK) {
log_v("UPDATE_WRITE: %u %u", ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, bufsize);
log_v("UPDATE_WRITE: %" PRIu32 " %" PRIu32, ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, bufsize);
msc_update_bytes_written = ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset + bufsize;
p.write.offset = ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset;
p.write.size = bufsize;
Expand All @@ -315,7 +315,7 @@ static int32_t msc_write(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_
bufsize = msc_update_entry->file_size - msc_update_bytes_written;
}
if (msc_update_write(msc_ota_partition, ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, buffer, bufsize) == ESP_OK) {
log_v("UPDATE_WRITE: %u %u", ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, bufsize);
log_v("UPDATE_WRITE: %" PRIu32 " %" PRIu32, ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset, bufsize);
msc_update_bytes_written = ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset + bufsize;
p.write.offset = ((lba - msc_update_start_sector) * DISK_SECTOR_SIZE) + offset;
p.write.size = bufsize;
Expand All @@ -333,7 +333,7 @@ static int32_t msc_write(uint32_t lba, uint32_t offset, uint8_t *buffer, uint32_
}

static int32_t msc_read(uint32_t lba, uint32_t offset, void *buffer, uint32_t bufsize) {
//log_d("lba: %u, offset: %u, bufsize: %u", lba, offset, bufsize);
//log_d("lba: %" PRIu32 ", offset: %" PRIu32 ", bufsize: %" PRIu32, lba, offset, bufsize);
if (lba < fw_start_sector) {
memcpy(buffer, msc_ram_disk + (lba * DISK_SECTOR_SIZE) + offset, bufsize);
} else if (msc_run_partition && lba < fw_end_sector) {
Expand Down
2 changes: 1 addition & 1 deletion cores/esp32/HEXBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ size_t HEXBuilder::hex2bytes(unsigned char *out, size_t maxlen, const char *in)
size_t HEXBuilder::bytes2hex(char *out, size_t maxlen, const unsigned char *in, size_t len) {
for (size_t i = 0; i < len; i++) {
if (i * 2 + 1 < maxlen) {
sprintf(out + (i * 2), "%02x", in[i]);
snprintf(out + (i * 2), 3, "%02x", in[i]);
}
}
return len * 2 + 1;
Expand Down
2 changes: 1 addition & 1 deletion cores/esp32/HWCDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static void hw_cdc_isr_handler(void *arg) {
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
}
//send event?
//ets_printf("TX:%u\n", queued_size);
//ets_printf("TX:%lu\n", (unsigned long)queued_size);
event.tx.len = queued_size;
arduino_hw_cdc_event_post(ARDUINO_HW_CDC_EVENTS, ARDUINO_HW_CDC_TX_EVENT, &event, sizeof(arduino_hw_cdc_event_data_t), &xTaskWoken);
}
Expand Down
20 changes: 10 additions & 10 deletions cores/esp32/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ void HardwareSerial::_createEventTask(void *args) {
ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE
);
if (_eventTask == NULL) {
log_e(" -- UART%d Event Task not Created!", _uart_nr);
log_e(" -- UART%u Event Task not Created!", _uart_nr);
}
}

Expand Down Expand Up @@ -295,26 +295,26 @@ void HardwareSerial::_uartEventTask(void *args) {
}
break;
case UART_FIFO_OVF:
log_w("UART%d FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
log_w("UART%u FIFO Overflow. Consider adding Hardware Flow Control to your Application.", uart->_uart_nr);
currentErr = UART_FIFO_OVF_ERROR;
break;
case UART_BUFFER_FULL:
log_w("UART%d Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
log_w("UART%u Buffer Full. Consider increasing your buffer size of your Application.", uart->_uart_nr);
currentErr = UART_BUFFER_FULL_ERROR;
break;
case UART_BREAK:
log_v("UART%d RX break.", uart->_uart_nr);
log_v("UART%u RX break.", uart->_uart_nr);
currentErr = UART_BREAK_ERROR;
break;
case UART_PARITY_ERR:
log_v("UART%d parity error.", uart->_uart_nr);
log_v("UART%u parity error.", uart->_uart_nr);
currentErr = UART_PARITY_ERROR;
break;
case UART_FRAME_ERR:
log_v("UART%d frame error.", uart->_uart_nr);
log_v("UART%u frame error.", uart->_uart_nr);
currentErr = UART_FRAME_ERROR;
break;
default: log_v("UART%d unknown event type %d.", uart->_uart_nr, event.type); break;
default: log_v("UART%u unknown event type %u", uart->_uart_nr, event.type); break;
}
if (currentErr != UART_NO_ERROR) {
if (uart->_onReceiveErrorCB) {
Expand Down Expand Up @@ -652,7 +652,7 @@ bool HardwareSerial::setMode(SerialMode mode) {
// Note: ESP32-C6, C61, ESP32-P4 and ESP32-C5 have LP UART that will use only RTC_FAST or XTAL/2 as Clock Source
bool HardwareSerial::setClockSource(SerialClkSrc clkSrc) {
if (_uart) {
log_e("No Clock Source change was done. This function must be called before beginning UART%d.", _uart_nr);
log_e("No Clock Source change was done. This function must be called before beginning UART%u", _uart_nr);
return false;
}
return uartSetClockSource(_uart_nr, (uart_sclk_t)clkSrc);
Expand All @@ -669,7 +669,7 @@ size_t HardwareSerial::setRxBufferSize(size_t new_size) {
// Valid value is higher than the FIFO length
if (new_size <= FIFOLen) {
new_size = FIFOLen + 1;
log_w("RX Buffer set to minimum value: %d.", new_size);
log_w("RX Buffer set to minimum value: %lu.", (unsigned long)new_size);
}

_rxBufferSize = new_size;
Expand All @@ -688,7 +688,7 @@ size_t HardwareSerial::setTxBufferSize(size_t new_size) {
// Valid values are zero or higher than the FIFO length
if (new_size > 0 && new_size <= FIFOLen) {
new_size = FIFOLen + 1;
log_w("TX Buffer set to minimum value: %d.", new_size);
log_w("TX Buffer set to minimum value: %lu.", (unsigned long)new_size);
}
// if new_size is higher than SOC_UART_FIFO_LEN, TX Ringbuffer will be active and it will be used to report back "availableToWrite()"
_txBufferSize = new_size;
Expand Down
12 changes: 7 additions & 5 deletions cores/esp32/MacAddress.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <Arduino.h>
#include <MacAddress.h>
#include <stdio.h>
#include <Print.h>
#include <inttypes.h>

//Default constructor, blank mac address.
MacAddress::MacAddress() : MacAddress(MAC6) {}
Expand Down Expand Up @@ -132,14 +134,14 @@ void MacAddress::toBytes(uint8_t *buf) {
}

//Print MAC address into a C string.
//MAC: Buffer must be at least 18 chars
//MAC: Buffer must be at least 18 chars for MAC6 and 24 for MAC8
int MacAddress::toString(char *buf) {
if (_type == MAC6) {
return sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], _mac.bytes[4], _mac.bytes[5]);
return snprintf(buf, 18, "%02X:%02X:%02X:%02X:%02X:%02X", _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], _mac.bytes[4], _mac.bytes[5]);
} else {
return sprintf(
buf, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], _mac.bytes[4], _mac.bytes[5], _mac.bytes[6],
_mac.bytes[7]
return snprintf(
buf, 24, "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X", _mac.bytes[0], _mac.bytes[1], _mac.bytes[2], _mac.bytes[3], _mac.bytes[4], _mac.bytes[5],
_mac.bytes[6], _mac.bytes[7]
);
}
}
Expand Down
7 changes: 3 additions & 4 deletions cores/esp32/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,11 @@ size_t Print::print(unsigned long n, int base) {
}

size_t Print::print(long long n, int base) {
int t = 0;
if (base == 10 && n < 0) {
t = print('-');
n = -n;
return print('-') + printNumber(static_cast<unsigned long long>(-(n + 1)) + 1ULL, base);
}
return printNumber(static_cast<unsigned long long>(n), base) + t;

return printNumber(static_cast<unsigned long long>(n), base);
}

size_t Print::print(unsigned long long n, int base) {
Expand Down
73 changes: 73 additions & 0 deletions cores/esp32/StringUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2026 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "StringUtils.h"

#define U64_STR_SIZE 21 // 20 digits + '\0'
#define I64_STR_SIZE 22 // '-' + 19 digits + '\0'

char *u64_to_str(uint64_t value, char *buffer) {
char *end = buffer + 20;
char *p = end;
*p = '\0';

// reverse fill
do {
*--p = '0' + (value % 10);
value /= 10;
} while (value);

// shift to beginning
char *dst = buffer;
while ((*dst++ = *p++)) {}

return buffer;
}

char *i64_to_str(int64_t value, char *buffer) {
if (value >= 0) {
return u64_to_str((uint64_t)value, buffer);
}

// Safe magnitude (handles INT64_MIN)
uint64_t magnitude = (uint64_t)(-(value + 1)) + 1;

u64_to_str(magnitude, buffer);

// prepend '-'
char *end = buffer;
while (*end) {
end++; // find null terminator
}
while (end >= buffer) { // shift right including '\0'
*(end + 1) = *end;
if (end == buffer) {
break;
}
end--;
}
buffer[0] = '-';

return buffer;
}

String u64_to_String(uint64_t value) {
char buf[U64_STR_SIZE];
return String(u64_to_str(value, buf));
}

String i64_to_String(int64_t value) {
char buf[I64_STR_SIZE];
return String(i64_to_str(value, buf));
}
Loading
Loading