Skip to content
Closed
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
13 changes: 13 additions & 0 deletions boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ giga.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg
giga.debug.cortex-debug.custom.request=attach
giga.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd

giga.build.ota.sketch_offset=0xA0000
giga.recipe.hooks.objcopy.postobjcopy.3.pattern="{compiler.path}{compiler.elf2hex.cmd}" -I binary -O elf32-littlearm -B arm --add-section .sketch={build.path}/{build.project_name}.{upload.extension} --change-section-address .sketch={build.ota.sketch_offset} "{runtime.platform.path}/firmwares/zephyr-{build.variant}.bin" "{build.path}/{build.project_name}.ota.elf"
giga.recipe.hooks.objcopy.postobjcopy.4.pattern="{compiler.path}{compiler.elf2hex.cmd}" -O binary --gap-fill 0xFF "{build.path}/{build.project_name}.ota.elf" "{build.path}/{build.project_name}.ota"

##########################################################################################

nano33ble.name=Arduino Nano 33 BLE
Expand Down Expand Up @@ -311,6 +315,10 @@ portentah7.bootloader.interface=0
portentah7.bootloader.file=zephyr-{build.variant}.bin
portentah7.bootloader.address=0x08040000

portentah7.build.ota.sketch_offset=0xA0000
portentah7.recipe.hooks.objcopy.postobjcopy.3.pattern="{compiler.path}{compiler.elf2hex.cmd}" -I binary -O elf32-littlearm -B arm --add-section .sketch={build.path}/{build.project_name}.{upload.extension} --change-section-address .sketch={build.ota.sketch_offset} "{runtime.platform.path}/firmwares/zephyr-{build.variant}.bin" "{build.path}/{build.project_name}.ota.elf"
portentah7.recipe.hooks.objcopy.postobjcopy.4.pattern="{compiler.path}{compiler.elf2hex.cmd}" -O binary --gap-fill 0xFF "{build.path}/{build.project_name}.ota.elf" "{build.path}/{build.project_name}.ota"

portentah7.debug.tool=gdb
portentah7.debug.server.openocd.scripts.0=interface/{programmer.protocol}.cfg
portentah7.debug.server.openocd.scripts.1={programmer.transport_script}
Expand Down Expand Up @@ -493,6 +501,7 @@ portentac33.bootloader.interface=0
portentac33.bootloader.address=0x10000
portentac33.bootloader.dfuse=-Q


##########################################################################################

opta.name=Arduino Opta
Expand Down Expand Up @@ -561,6 +570,10 @@ opta.debug.server.openocd.scripts.2=target/stm32h7x_dual_bank.cfg
opta.debug.cortex-debug.custom.request=attach
opta.debug.svd_file={runtime.platform.path}/svd/STM32H747_CM7.svd

opta.build.ota.sketch_offset=0xA0000
opta.recipe.hooks.objcopy.postobjcopy.3.pattern="{compiler.path}{compiler.elf2hex.cmd}" -I binary -O elf32-littlearm -B arm --add-section .sketch={build.path}/{build.project_name}.{upload.extension} --change-section-address .sketch={build.ota.sketch_offset} "{runtime.platform.path}/firmwares/zephyr-{build.variant}.bin" "{build.path}/{build.project_name}.ota.elf"
opta.recipe.hooks.objcopy.postobjcopy.4.pattern="{compiler.path}{compiler.elf2hex.cmd}" -O binary --gap-fill 0xFF "{build.path}/{build.project_name}.ota.elf" "{build.path}/{build.project_name}.ota"

##########################################################################################

nano_matter.name=Arduino Nano Matter
Expand Down
3 changes: 2 additions & 1 deletion cores/arduino/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ int digitalPinToInterrupt(pin_size_t pin);
#define portOutputRegister(x) (x)
#define portInputRegister(x) (x)

void analogReadResolution(int bits);
#if defined(CONFIG_PWM) || defined(CONFIG_DAC)
void analogWriteResolution(int bits);
#endif

#include <variant.h>

Expand Down
11 changes: 4 additions & 7 deletions cores/arduino/zephyrCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ int analogWriteResolution() {
#ifdef CONFIG_PWM

void analogWrite(pin_size_t pinNumber, int value) {
const int maxInput = BIT(_analog_write_resolution) - 1U;
size_t idx = pwm_pin_index(pinNumber);

if (idx >= ARRAY_SIZE(arduino_pwm)) {
Expand All @@ -327,19 +328,15 @@ void analogWrite(pin_size_t pinNumber, int value) {
}

_reinit_peripheral_if_needed(pinNumber, arduino_pwm[idx].dev);
value = map(value, 0, 1 << _analog_write_resolution, 0, arduino_pwm[idx].period);
value = CLAMP(value, 0, maxInput);

if (((uint32_t)value) > arduino_pwm[idx].period) {
value = arduino_pwm[idx].period;
} else if (value < 0) {
value = 0;
}
const uint32_t pulse = map(value, 0, maxInput, 0, arduino_pwm[idx].period);

/*
* A duty ratio determines by the period value defined in dts
* and the value arguments. So usually the period value sets as 255.
*/
(void)pwm_set_pulse_dt(&arduino_pwm[idx], value);
(void)pwm_set_pulse_dt(&arduino_pwm[idx], pulse);
}

#endif
Expand Down
13 changes: 8 additions & 5 deletions extra/debug.conf
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
CONFIG_DEBUG=y

# Enable assertions
CONFIG_ASSERT=y
#CONFIG_ASSERT_VERBOSE=y
# CONFIG_ASSERT=y
# CONFIG_ASSERT_VERBOSE=y

# Enable stack overflow detection
CONFIG_STACK_SENTINEL=y
CONFIG_STACK_CANARIES=y
# Enable stack overflow detection (STACK_SENTINEL needs !MPU_STACK_GUARD)
#CONFIG_STACK_SENTINEL=y
#CONFIG_STACK_CANARIES=y

# Enable thread monitoring and debugging
CONFIG_THREAD_MONITOR=y
Expand All @@ -25,7 +25,10 @@ CONFIG_SHELL=y
#CONFIG_NET_SHELL=y
#CONFIG_NET_L2_WIFI_SHELL=y
CONFIG_SHELL_STACK_SIZE=8192
CONFIG_LOG_BACKEND_UART_AUTOSTART=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

# Enable runtime statistics
CONFIG_SYS_HEAP_RUNTIME_STATS=y
CONFIG_THREAD_RUNTIME_STATS=y

2 changes: 2 additions & 0 deletions loader/llext_exports.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <strings.h>
#include <zephyr/llext/symbol.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/sys/reboot.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -268,6 +269,7 @@ EXPORT_SYMBOL(k_work_schedule);

EXPORT_SYMBOL(time);
EXPORT_SYMBOL(sys_clock_settime);
EXPORT_SYMBOL(sys_reboot);
EXPORT_SYMBOL(mktime);

EXPORT_SYMBOL(printf);
Expand Down
177 changes: 142 additions & 35 deletions loader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ LOG_MODULE_REGISTER(sketch);
#include <zephyr/usb/usb_device.h>

#include <zephyr/devicetree/fixed-partitions.h>
#include <zephyr/fs/fs.h>

#define HEADER_LEN 16

#define OTA_SENTINEL_PATH "/ota:/OTA_UPDATE_PENDING"
#define OTA_UPDATE_PATH "/ota:/UPDATE.BIN"

struct sketch_header_v1 {
uint8_t ver; // @ 0x07
uint32_t len; // @ 0x08
Expand Down Expand Up @@ -110,6 +114,103 @@ __attribute__((retain)) const uintptr_t sketch_max_size = DT_REG_SIZE(DT_NODELAB
#endif
__attribute__((retain)) const uintptr_t loader_max_size = LOADER_MAX_SIZE;

#if defined(CONFIG_FILE_SYSTEM)
static int try_ota_update(const struct flash_area *fa) {
struct fs_dirent entry;
int rc;

/* Check for pending OTA update */
if (fs_stat(OTA_SENTINEL_PATH, &entry) != 0) {
printk("OTA: no update pending\n");
return 0;
}

printk("OTA: update pending, validating...\n");

/* Open UPDATE.BIN */
struct fs_file_t file;
fs_file_t_init(&file);
rc = fs_open(&file, OTA_UPDATE_PATH, FS_O_READ);
if (rc < 0) {
printk("OTA: failed to open %s, rc %d\n", OTA_UPDATE_PATH, rc);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}

/* Get file size */
fs_seek(&file, 0, FS_SEEK_END);
off_t file_size = fs_tell(&file);
fs_seek(&file, 0, FS_SEEK_SET);

if (file_size < HEADER_LEN) {
printk("OTA: file too small (%ld bytes)\n", (long)file_size);
fs_close(&file);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}

/* Read and validate sketch header */
char header[HEADER_LEN];
rc = fs_read(&file, header, HEADER_LEN);
if (rc != HEADER_LEN) {
printk("OTA: failed to read header\n");
fs_close(&file);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}

struct sketch_header_v1 *hdr = (struct sketch_header_v1 *)(header + 7);
if (hdr->ver != 0x1 || hdr->magic != 0x2341) {
printk("OTA: invalid sketch header (ver=0x%x magic=0x%x)\n", hdr->ver, hdr->magic);
fs_close(&file);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}

size_t sketch_len = hdr->len;
printk("OTA: sketch length = %u bytes\n", (unsigned)sketch_len);

/* Erase flash partition */
printk("OTA: erasing flash partition (%u bytes)...\n", (unsigned)fa->fa_size);
rc = flash_area_erase(fa, 0, fa->fa_size);
if (rc) {
printk("OTA: flash erase failed, rc %d\n", rc);
fs_close(&file);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}

/* Write sketch data from file to flash in chunks */
fs_seek(&file, 0, FS_SEEK_SET);
uint8_t chunk[4096];
off_t offset = 0;
size_t remaining = sketch_len;
ssize_t n;
while (remaining > 0 &&
(n = fs_read(&file, chunk, remaining < sizeof(chunk) ? remaining : sizeof(chunk))) > 0) {
rc = flash_area_write(fa, offset, chunk, n);
if (rc) {
printk("OTA: flash write failed at offset %ld, rc %d\n", (long)offset, rc);
fs_close(&file);
fs_unlink(OTA_SENTINEL_PATH);
return -1;
}
offset += n;
remaining -= n;
}
fs_close(&file);

printk("OTA: wrote %ld bytes to flash\n", (long)offset);

/* Delete sentinel and update file */
fs_unlink(OTA_SENTINEL_PATH);
fs_unlink(OTA_UPDATE_PATH);

printk("OTA: update complete\n");
return 0;
}
#endif /* CONFIG_FILE_SYSTEM */

static int loader(const struct shell *sh) {
const struct flash_area *fa;
int rc;
Expand Down Expand Up @@ -139,6 +240,40 @@ static int loader(const struct shell *sh) {
// This is not a valid sketch, but try to start a shell anyway
}

#if TARGET_HAS_USB_CDC
int debug = (!sketch_valid) || (sketch_hdr->flags & SKETCH_FLAG_DEBUG);
#if CONFIG_SHELL
if (strcmp(k_thread_name_get(k_current_get()), "main") == 0) {
// disables default shell on UART
shell_uninit(shell_backend_uart_get_ptr(), NULL);
// enables USB and starts the shell
usb_enable(NULL);
int dtr;
do {
// wait for the serial port to open
uart_line_ctrl_get(usb_dev, UART_LINE_CTRL_DTR, &dtr);
k_sleep(K_MSEC(100));
} while (!dtr);
enable_shell_usb();
}
#elif CONFIG_LOG
#if !CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT
if (debug) {
usb_enable(NULL);
}
#endif
for (int i = 0; i < log_backend_count_get(); i++) {
const struct log_backend *backend;
backend = log_backend_get(i);
log_backend_init(backend);
log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_DEFAULT_LEVEL);
if (!debug) {
break;
}
}
#endif
#endif

#if defined(CONFIG_BOARD_ARDUINO_UNO_Q)
void matrixBegin(void);
void matrixEnd(void);
Expand Down Expand Up @@ -216,43 +351,15 @@ static int loader(const struct shell *sh) {
}
#endif

size_t sketch_buf_len = sketch_hdr->len;

#if TARGET_HAS_USB_CDC
int debug = (!sketch_valid) || (sketch_hdr->flags & SKETCH_FLAG_DEBUG);
#if CONFIG_SHELL
if (debug && strcmp(k_thread_name_get(k_current_get()), "main") == 0) {
// disables default shell on UART
shell_uninit(shell_backend_uart_get_ptr(), NULL);
// enables USB and starts the shell
usb_enable(NULL);
int dtr;
do {
// wait for the serial port to open
uart_line_ctrl_get(usb_dev, UART_LINE_CTRL_DTR, &dtr);
k_sleep(K_MSEC(100));
} while (!dtr);
enable_shell_usb();
return 0;
}
#elif CONFIG_LOG
#if !CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT
if (debug) {
usb_enable(NULL);
}
#endif
for (int i = 0; i < log_backend_count_get(); i++) {
const struct log_backend *backend;
backend = log_backend_get(i);
log_backend_init(backend);
log_backend_enable(backend, backend->cb->ctx, CONFIG_LOG_DEFAULT_LEVEL);
if (!debug) {
break;
}
}
#endif
#if defined(CONFIG_FILE_SYSTEM)
try_ota_update(fa);
/* Re-read header in case OTA replaced the sketch */
flash_area_read(fa, 0, header, sizeof(header));
sketch_hdr = (struct sketch_header_v1 *)(header + 7);
#endif

size_t sketch_buf_len = sketch_hdr->len;

if (sketch_hdr->flags & SKETCH_FLAG_LINKED) {
#ifdef CONFIG_BOARD_ARDUINO_PORTENTA_C33
#if CONFIG_MPU
Expand Down
1 change: 1 addition & 0 deletions loader/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_MAIN_THREAD_PRIORITY=14

CONFIG_EVENTS=y
CONFIG_REBOOT=y
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,28 @@ CONFIG_NET_TCP=y
CONFIG_NET_SOCKETS=y
CONFIG_POSIX_API=y

CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_MKFS=y
CONFIG_DISK_ACCESS=y
CONFIG_DISK_DRIVER_FLASH=y

CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_FS_LITTLEFS_PROG_SIZE=4096
CONFIG_FS_LITTLEFS_CACHE_SIZE=4096

CONFIG_FAT_FILESYSTEM_ELM=y
CONFIG_FS_FATFS_EXFAT=n
CONFIG_FS_FATFS_MKFS=y
CONFIG_FS_FATFS_LFN=y
CONFIG_FS_FATFS_LFN_MODE_HEAP=y
CONFIG_FS_FATFS_CODEPAGE=437
CONFIG_FS_FATFS_MIN_SS=4096
CONFIG_FS_FATFS_MAX_SS=4096
CONFIG_FS_FATFS_MAX_LFN=255
CONFIG_FS_FATFS_FSTAB_AUTOMOUNT=y
CONFIG_FS_FATFS_CUSTOM_MOUNT_POINT_COUNT=2
CONFIG_FS_FATFS_CUSTOM_MOUNT_POINTS="wlan,ota"

CONFIG_ENTROPY_GENERATOR=y
CONFIG_TEST_RANDOM_GENERATOR=y

Expand Down
Loading
Loading