From 2d834973fc86b787535204b174303a0311e1f36f Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 19 Jan 2024 11:13:09 +0100 Subject: [PATCH 01/37] stm32h747: cm4: set VTOR at boot --- .../STM32Cube_FW/system_stm32h7xx_dualcore_boot_cm4_cm7.c | 2 +- .../TOOLCHAIN_GCC_ARM/stm32h747xI_CM4.ld | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/system_stm32h7xx_dualcore_boot_cm4_cm7.c b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/system_stm32h7xx_dualcore_boot_cm4_cm7.c index b4a4cc78263..8e0017de2aa 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/system_stm32h7xx_dualcore_boot_cm4_cm7.c +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/system_stm32h7xx_dualcore_boot_cm4_cm7.c @@ -232,7 +232,7 @@ __weak void SystemInit (void) /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM SCB->VTOR = D2_AXISRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ -#elif !defined(NO_VTOR_RELOCATE) +#else #include "nvic_addr.h" // MBED SCB->VTOR = NVIC_FLASH_VECTOR_ADDRESS; // MBED #endif diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_STM32H747xI_CM4/TOOLCHAIN_GCC_ARM/stm32h747xI_CM4.ld b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_STM32H747xI_CM4/TOOLCHAIN_GCC_ARM/stm32h747xI_CM4.ld index ea81a18b117..7d2651dcb48 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_STM32H747xI_CM4/TOOLCHAIN_GCC_ARM/stm32h747xI_CM4.ld +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_STM32H747xI_CM4/TOOLCHAIN_GCC_ARM/stm32h747xI_CM4.ld @@ -38,10 +38,16 @@ MEMORY { FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE - RAM (rwx) : ORIGIN = MBED_RAM_START + VECTORS_SIZE, LENGTH = MBED_RAM_SIZE - VECTORS_SIZE + RAM_D2 (rwx) : ORIGIN = MBED_RAM_START + VECTORS_SIZE, LENGTH = MBED_RAM_SIZE - VECTORS_SIZE RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K } +#if (CM4_BINARY_START == 0x60000000) +REGION_ALIAS("RAM", FLASH); +#else +REGION_ALIAS("RAM", RAM_D2); +#endif + /* Linker script to place sections and symbol values. Should be used together * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: From 992ed2cca5ebbce5f817d9fd25b2162ff8e77bbe Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Mon, 29 Apr 2024 10:41:37 +0200 Subject: [PATCH 02/37] stm32h7: adc: DUAL_PAD: fix definitions for GENERIC_M4 target Completes 2e1da0130 and fixes https://github.com/arduino/ArduinoCore-mbed/issues/867 --- .../TARGET_STM32H747xI/TARGET_GENERIC_STM32H747_M4/PinNames.h | 2 +- targets/TARGET_STM/tools/STM32_gen_PeripheralPins.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_GENERIC_STM32H747_M4/PinNames.h b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_GENERIC_STM32H747_M4/PinNames.h index 97d48334d7f..04a34504a70 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_GENERIC_STM32H747_M4/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_GENERIC_STM32H747_M4/PinNames.h @@ -43,7 +43,7 @@ extern "C" { #endif -#define DUAL_PAD 0xF00 +#define DUAL_PAD 0x800 typedef enum { ALT0 = 0x100, diff --git a/targets/TARGET_STM/tools/STM32_gen_PeripheralPins.py b/targets/TARGET_STM/tools/STM32_gen_PeripheralPins.py index 44a95f9c023..903ce5f7e0b 100644 --- a/targets/TARGET_STM/tools/STM32_gen_PeripheralPins.py +++ b/targets/TARGET_STM/tools/STM32_gen_PeripheralPins.py @@ -491,7 +491,7 @@ def print_header(): if DUAL_PAD: line_to_write = (""" -#define DUAL_PAD 0xF00 +#define DUAL_PAD 0x800 """) out_h_file.write(line_to_write) From d0f5c17e3f7a3094c80b6b239c407f1cf7ba6df9 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 27 Jun 2024 13:36:31 +0200 Subject: [PATCH 03/37] TLSSocketWrapper: do not force close() to block --- connectivity/netsocket/source/TLSSocketWrapper.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/connectivity/netsocket/source/TLSSocketWrapper.cpp b/connectivity/netsocket/source/TLSSocketWrapper.cpp index 1fb9c217694..c020cd9f593 100644 --- a/connectivity/netsocket/source/TLSSocketWrapper.cpp +++ b/connectivity/netsocket/source/TLSSocketWrapper.cpp @@ -757,7 +757,6 @@ nsapi_error_t TLSSocketWrapper::close() int ret = 0; if (_handshake_completed) { - _transport->set_blocking(true); ret = mbedtls_ssl_close_notify(&_ssl); if (ret) { print_mbedtls_error("mbedtls_ssl_close_notify", ret); From a902e90ca27f3833646e564964b24e2a79211a09 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 17 Jun 2024 10:19:14 +0200 Subject: [PATCH 04/37] RP2040: add pico_rand support --- .../TARGET_RP2040/CMakeLists.txt | 2 + .../TARGET_RP2040/objects.h | 7 + .../pico-sdk/rp2_common/CMakeLists.txt | 1 + .../hardware_sync/include/hardware/sync.h | 5 + .../pico_platform/include/pico/platform.h | 6 +- .../rp2_common/pico_rand/CMakeLists.txt | 13 + .../rp2_common/pico_rand/include/pico/rand.h | 185 +++++++++++ .../pico-sdk/rp2_common/pico_rand/rand.c | 305 ++++++++++++++++++ .../TARGET_RP2040/trng_api.c | 64 ++++ targets/targets.json | 3 +- 10 files changed, 587 insertions(+), 4 deletions(-) create mode 100644 targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/CMakeLists.txt create mode 100644 targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/include/pico/rand.h create mode 100644 targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/rand.c create mode 100644 targets/TARGET_RASPBERRYPI/TARGET_RP2040/trng_api.c diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/CMakeLists.txt b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/CMakeLists.txt index 4fadf6091ee..4e9bae47cef 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/CMakeLists.txt +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/CMakeLists.txt @@ -36,6 +36,7 @@ target_include_directories(mbed-rp2040 pico-sdk/common/pico_base/include pico-sdk/common/pico_binary_info/include pico-sdk/common/pico_util/include + pico-sdk/common/pico_rand/include pico-sdk/boards/include pico-sdk/generated . @@ -71,6 +72,7 @@ target_sources(mbed-rp2040 pico-sdk/rp2_common/pico_bootrom/bootrom.c pico-sdk/rp2_common/pico_runtime/runtime.c pico-sdk/rp2_common/pico_platform/platform.c + pico-sdk/rp2_common/pico_rand/rand.c pico-sdk/common/pico_sync/mutex.c pico-sdk/common/pico_time/time.c pico-sdk/common/pico_sync/lock_core.c diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/objects.h b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/objects.h index f5f44a58f4a..0231968bb52 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/objects.h +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/objects.h @@ -33,6 +33,7 @@ extern "C" { #include "pico/assert.h" #include "pico/time.h" #include "pico/types.h" +#include "pico/rand.h" #include "hardware/pwm.h" #include "hardware/adc.h" #include "hardware/resets.h" @@ -122,6 +123,12 @@ struct flash_s { uint32_t dummy; }; +#if DEVICE_TRNG +struct trng_s { + uint8_t not_used; +}; +#endif + typedef struct gpio_s gpio_t; typedef struct serial_s serial_t; diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/CMakeLists.txt b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/CMakeLists.txt index 4ca55becba2..ec89c3ff71e 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/CMakeLists.txt +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/CMakeLists.txt @@ -49,6 +49,7 @@ if (NOT PICO_BARE_METAL) pico_add_subdirectory(pico_mem_ops) pico_add_subdirectory(pico_malloc) pico_add_subdirectory(pico_printf) + pico_add_subdirectory(pico_rand) pico_add_subdirectory(pico_stdio) pico_add_subdirectory(pico_stdio_semihosting) diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/hardware_sync/include/hardware/sync.h b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/hardware_sync/include/hardware/sync.h index 8f91d55955c..4f076aba021 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/hardware_sync/include/hardware/sync.h +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/hardware_sync/include/hardware/sync.h @@ -70,6 +70,11 @@ typedef volatile uint32_t spin_lock_t; #define PICO_SPINLOCK_ID_HARDWARE_CLAIM 11 #endif +// PICO_CONFIG: PICO_SPINLOCK_ID_RAND, Spinlock ID for Random Number Generator, min=0, max=31, default=12, group=hardware_sync +#ifndef PICO_SPINLOCK_ID_RAND +#define PICO_SPINLOCK_ID_RAND 12 +#endif + // PICO_CONFIG: PICO_SPINLOCK_ID_OS1, First Spinlock ID reserved for use by low level OS style software, min=0, max=31, default=14, group=hardware_sync #ifndef PICO_SPINLOCK_ID_OS1 #define PICO_SPINLOCK_ID_OS1 14 diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_platform/include/pico/platform.h b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_platform/include/pico/platform.h index ee1d360cee9..ea16d9734e4 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_platform/include/pico/platform.h +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_platform/include/pico/platform.h @@ -151,14 +151,14 @@ extern "C" { * * For example a `uint32_t` foo that will retain its value if the program is restarted by reset. * - * uint32_t __uninitialized_ram("my_group_name") foo; + * uint32_t __uninitialized_ram(foo); * - * The section attribute is `.uninitialized_ram.` + * The section attribute is `.uninitialized_data.` * * \param group a string suffix to use in the section name to distinguish groups that can be linker * garbage-collected independently */ -#define __uninitialized_ram(group) __attribute__((section(".uninitialized_ram." #group))) group +#define __uninitialized_ram(group) __attribute__((section(".uninitialized_data." #group))) group /*! \brief Section attribute macro for placement in flash even in a COPY_TO_RAM binary * \ingroup pico_platform diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/CMakeLists.txt b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/CMakeLists.txt new file mode 100644 index 00000000000..0e72bb5ab6b --- /dev/null +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/CMakeLists.txt @@ -0,0 +1,13 @@ +pico_add_library(pico_rand) + +target_sources(pico_rand INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/rand.c +) + +target_include_directories(pico_rand_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include) + +pico_mirrored_target_link_libraries(pico_rand INTERFACE + pico_unique_id + hardware_clocks + hardware_timer + hardware_sync) diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/include/pico/rand.h b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/include/pico/rand.h new file mode 100644 index 00000000000..20fc6d6cb14 --- /dev/null +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/include/pico/rand.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _PICO_RAND_H +#define _PICO_RAND_H + +#include "pico.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file pico/rand.h + * \defgroup pico_rand pico_rand + * + * Random Number Generator API + * + * This module generates random numbers at runtime utilizing a number of possible entropy + * sources and uses those sources to modify the state of a 128-bit 'Pseudo + * Random Number Generator' implemented in software. + * + * The random numbers (32 to 128 bit) to be supplied are read from the PRNG which is used + * to help provide a large number space. + * + * The following (multiple) sources of entropy are available (of varying quality), each enabled by a #define: + * + * - The Ring Oscillator (ROSC) (\ref PICO_RAND_ENTROPY_SRC_ROSC == 1): + * \ref PICO_RAND_ROSC_BIT_SAMPLE_COUNT bits are gathered from the ring oscillator "random bit" and mixed in each + * time. This should not be used if the ROSC is off, or the processor is running from + * the ROSC. + * \note the maximum throughput of ROSC bit sampling is controlled by PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US which defaults + * to 10us, i.e. 100,000 bits per second. + * - Time (\ref PICO_RAND_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed in each time. + * - Bus Performance Counter (\ref PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER == 1): One of the bus fabric's performance + * counters is mixed in each time. + * + * \note All entropy sources are hashed before application to the PRNG state machine. + * + * The \em first time a random number is requested, the 128-bit PRNG state + * must be seeded. Multiple entropy sources are also available for the seeding operation: + * + * - The Ring Oscillator (ROSC) (\ref PICO_RAND_SEED_ENTROPY_SRC_ROSC == 1): + * 64 bits are gathered from the ring oscillator "random bit" and mixed into the seed. + * - Time (\ref PICO_RAND_SEED_ENTROPY_SRC_TIME == 1): The 64-bit microsecond timer is mixed into the seed. + * - Board Identifier (PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID == 1): The board id via \ref pico_get_unique_board_id + * is mixed into the seed. + * - RAM hash (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH (\ref PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH): The hashed contents of a + * subset of RAM are mixed in. Initial RAM contents are undefined on power up, so provide a reasonable source of entropy. + * By default the last 1K of RAM (which usually contains the core 0 stack) is hashed, which may also provide for differences + * after each warm reset. + * + * With default settings, the seed generation takes approximately 1 millisecond while + * subsequent random numbers generally take between 10 and 20 microseconds to generate. + * + * pico_rand methods may be safely called from either core or from an IRQ, but be careful in the latter case as + * the calls may block for a number of microseconds waiting on more entropy. + */ + +// --------------- +// ENTROPY SOURCES +// --------------- + +// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_ROSC, Enable/disable use of ROSC as an entropy source, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_ENTROPY_SRC_ROSC +#define PICO_RAND_ENTROPY_SRC_ROSC 1 +#endif + +// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_TIME, Enable/disable use of hardware timestamp as an entropy source, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_ENTROPY_SRC_TIME +#define PICO_RAND_ENTROPY_SRC_TIME 1 +#endif + +// PICO_CONFIG: PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER, Enable/disable use of a bus performance counter as an entropy source, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER +#define PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER 1 +#endif + +// -------------------- +// SEED ENTROPY SOURCES +// -------------------- + +// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_ROSC, Enable/disable use of ROSC as an entropy source for the random seed, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_SEED_ENTROPY_SRC_ROSC +#define PICO_RAND_SEED_ENTROPY_SRC_ROSC PICO_RAND_ENTROPY_SRC_ROSC +#endif + +// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_TIME, Enable/disable use of hardware timestamp as an entropy source for the random seed, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_SEED_ENTROPY_SRC_TIME +#define PICO_RAND_SEED_ENTROPY_SRC_TIME PICO_RAND_ENTROPY_SRC_TIME +#endif + +// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID, Enable/disable use of board id as part of the random seed, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID +#define PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID 0 +#endif + +// PICO_CONFIG: PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH, Enable/disable use of a RAM hash as an entropy source for the random seed, type=bool, default=1, group=pico_rand +#ifndef PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH +#define PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH 1 +#endif + +// --------------------------------- +// PICO_RAND_ENTROPY_SRC_ROSC CONFIG +// --------------------------------- + +// PICO_CONFIG: PICO_RAND_ROSC_BIT_SAMPLE_COUNT, Number of samples to take of the ROSC random bit per random number generation , min=1, max=64, default=1, group=pico_rand +#ifndef PICO_RAND_ROSC_BIT_SAMPLE_COUNT +#define PICO_RAND_ROSC_BIT_SAMPLE_COUNT 1 +#endif + +// PICO_CONFIG: PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US, Define a default minimum time between sampling the ROSC random bit, min=5, max=20, default=10, group=pico_rand +#ifndef PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US +// (Arbitrary / tested) minimum time between sampling the ROSC random bit +#define PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US 10u +#endif + +// --------------------------------------------- +// PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER CONFIG +// --------------------------------------------- + +// PICO_CONFIG: PICO_RAND_BUS_PERF_COUNTER_INDEX, Bus performance counter index to use for sourcing entropy, min=0, max=3, group=pico_rand +// this is deliberately undefined by default, meaning the code will pick that appears unused +//#define PICO_RAND_BUS_PERF_COUNTER_INDEX 0 + +// PICO_CONFIG: PICO_RAND_BUS_PERF_COUNTER_EVENT, Bus performance counter event to use for sourcing entropy, default=arbiter_sram5_perf_event_access, group=pico_rand +#ifndef PICO_RAND_BUS_PERF_COUNTER_EVENT +#define PICO_RAND_BUS_PERF_COUNTER_EVENT arbiter_sram5_perf_event_access +#endif + +// ------------------------------------------ +// PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH CONFIG +// ------------------------------------------ + +// PICO_CONFIG: PICO_RAND_RAM_HASH_END, end of address in RAM (non-inclusive) to hash during pico_rand seed initialization, default=SRAM_END, group=pico_rand +#ifndef PICO_RAND_RAM_HASH_END +#define PICO_RAND_RAM_HASH_END SRAM_END +#endif +// PICO_CONFIG: PICO_RAND_RAM_HASH_START, start of address in RAM (inclusive) to hash during pico_rand seed initialization, default=PICO_RAND_RAM_HASH_END - 1024, group=pico_rand +#ifndef PICO_RAND_RAM_HASH_START +#define PICO_RAND_RAM_HASH_START (PICO_RAND_RAM_HASH_END - 1024u) +#endif + +// We provide a maximum of 128 bits entropy in one go +typedef struct rng_128 { + uint64_t r[2]; +} rng_128_t; + +/*! \brief Get 128-bit random number + * \ingroup pico_rand + * + * This method may be safely called from either core or from an IRQ, but be careful in the latter case as + * the call may block for a number of microseconds waiting on more entropy. + * + * \param rand128 Pointer to storage to accept a 128-bit random number + */ +void get_rand_128(rng_128_t *rand128); + +/*! \brief Get 64-bit random number + * \ingroup pico_rand + * + * This method may be safely called from either core or from an IRQ, but be careful in the latter case as + * the call may block for a number of microseconds waiting on more entropy. + * + * \return 64-bit random number + */ +uint64_t get_rand_64(void); + +/*! \brief Get 32-bit random number + * \ingroup pico_rand + * + * This method may be safely called from either core or from an IRQ, but be careful in the latter case as + * the call may block for a number of microseconds waiting on more entropy. + * + * \return 32-bit random number + */ +uint32_t get_rand_32(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/rand.c b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/rand.c new file mode 100644 index 00000000000..c73b80321ee --- /dev/null +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/pico-sdk/rp2_common/pico_rand/rand.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2022 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* xoroshiro128ss(), rotl(): + + Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + + To the extent possible under law, the author has dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + See + + splitmix64() implementation: + + Written in 2015 by Sebastiano Vigna (vigna@acm.org) + To the extent possible under law, the author has dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + See +*/ + +#include "pico/rand.h" +#if PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID +#include "pico/unique_id.h" +#endif +#include "pico/time.h" +#include "hardware/clocks.h" +#include "hardware/structs/rosc.h" +#include "hardware/structs/bus_ctrl.h" +#include "hardware/sync.h" + +static bool rng_initialised = false; + +// Note: By design, do not initialise any of the variables that hold entropy, +// they may have useful junk in them, either from power-up or a previous boot. +static rng_128_t __uninitialized_ram(rng_state); +#if PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH +static uint64_t __uninitialized_ram(ram_hash); +#endif + +#if PICO_RAND_ENTROPY_SRC_ROSC | PICO_RAND_SEED_ENTROPY_SRC_ROSC +static uint64_t __uninitialized_ram(rosc_samples); +#endif + +#if PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER +static uint8_t bus_counter_idx; +#endif + +/* From the original source: + + This is a fixed-increment version of Java 8's SplittableRandom generator + See http://dx.doi.org/10.1145/2714064.2660195 and + http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html + + It is a very fast generator passing BigCrush, and it can be useful if + for some reason you absolutely want 64 bits of state; otherwise, we + rather suggest to use a xoroshiro128+ (for moderately parallel + computations) or xorshift1024* (for massively parallel computations) + generator. + + Note: This can be called with any value (i.e. including 0) +*/ +static __noinline uint64_t splitmix64(uint64_t x) { + uint64_t z = x + 0x9E3779B97F4A7C15ull; + z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ull; + z = (z ^ (z >> 27)) * 0x94D049BB133111EBull; + return z ^ (z >> 31); +} + +/* From the original source: + + This is xoroshiro128** 1.0, one of our all-purpose, rock-solid, + small-state generators. It is extremely (sub-ns) fast and it passes all + tests we are aware of, but its state space is large enough only for + mild parallelism. + + For generating just floating-point numbers, xoroshiro128+ is even + faster (but it has a very mild bias, see notes in the comments). + + The state must be seeded so that it is not everywhere zero. If you have + a 64-bit seed, we suggest to seed a splitmix64 generator and use its + output to fill s. +*/ +static inline uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +static __noinline uint64_t xoroshiro128ss(rng_128_t *local_rng_state) { + const uint64_t s0 = local_rng_state->r[0]; + uint64_t s1 = local_rng_state->r[1]; + + // Because the state is *modified* outside of this function, there is a + // 1 in 2^128 chance that it could be all zeroes (which is not allowed). + while (s0 == 0 && s1 == 0) { + s1 = time_us_64(); // should not be 0, but loop anyway + } + + const uint64_t result = rotl(s0 * 5, 7) * 9; + + s1 ^= s0; + local_rng_state->r[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b + local_rng_state->r[1] = rotl(s1, 37); // c + + return result; +} + +#if PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH +static uint64_t sdbm_hash64_sram(uint64_t hash) { + // save some time by hashing a word at a time + for (uint i = (PICO_RAND_RAM_HASH_START + 3) & ~3; i < PICO_RAND_RAM_HASH_END; i+=4) { + uint32_t c = *(uint32_t *) i; + hash = (uint64_t) c + (hash << 6) + (hash << 16) - hash; + } + return hash; +} +#endif + +#if PICO_RAND_SEED_ENTROPY_SRC_ROSC | PICO_RAND_ENTROPY_SRC_ROSC +/* gather an additional n bits of entropy, and shift them into the 64 bit entropy counter */ +static uint64_t capture_additional_rosc_samples(uint n) { + static absolute_time_t next_sample_time; + + // provide an override if someone really wants it, but disabling ROSC as an entropy source makes more sense +#if !PICO_RAND_DISABLE_ROSC_CHECK + // check that the ROSC is running but that the processors are NOT running from it + hard_assert((rosc_hw->status & ROSC_STATUS_ENABLED_BITS) && + ((clocks_hw->clk[clk_sys].ctrl & CLOCKS_CLK_SYS_CTRL_AUXSRC_BITS) != (CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_ROSC_CLKSRC << CLOCKS_CLK_SYS_CTRL_AUXSRC_LSB))); +#endif + + bool in_exception = __get_current_exception(); + assert(n); // save us having to special case samples for this + uint64_t samples = 0; + for(uint i=0; irandombit & 1u; + // use of relative time to now, rather than offset from before makes things + // a bit less predictable at the cost of some speed. + next_sample_time = make_timeout_time_us(PICO_RAND_MIN_ROSC_BIT_SAMPLE_TIME_US); + bit_done = true; + if (i == n - 1) { + // samples has our random bits, so let's mix them in now + samples = rosc_samples = (rosc_samples << n) | samples; + } + } + spin_unlock(lock, save); + } while (!bit_done); + } + return samples; +} +#endif + +static void initialise_rand(void) { + rng_128_t local_rng_state = local_rng_state; + uint which = 0; +#if PICO_RAND_SEED_ENTROPY_SRC_RAM_HASH + ram_hash = sdbm_hash64_sram(ram_hash); + local_rng_state.r[which] ^= splitmix64(ram_hash); + which ^= 1; +#endif + +#if PICO_RAND_SEED_ENTROPY_SRC_BOARD_ID + static_assert(PICO_UNIQUE_BOARD_ID_SIZE_BYTES == sizeof(uint64_t), + "Code below requires that 'board_id' is 64-bits in size"); + + // Note! The safety of the length assumption here is protected by a 'static_assert' above + union unique_id_u { + pico_unique_board_id_t board_id_native; + uint64_t board_id_u64; + } unique_id; + // Note! The safety of the length assumption here is protected by a 'static_assert' above + pico_get_unique_board_id(&unique_id.board_id_native); + local_rng_state.r[which] ^= splitmix64(unique_id.board_id_u64); + which ^= 1; +#endif + +#if PICO_RAND_SEED_ENTROPY_SRC_ROSC + // this is really quite slow (10ms per iteration), and I'm not sure that it adds value over the 64 random bits +// uint ref_khz = clock_get_hz(clk_ref) / 100; +// for (int i = 0; i < 5; i++) { +// // Apply hash of the rosc frequency, limited but still 'extra' entropy +// uint measurement = frequency_count_raw(CLOCKS_FC0_SRC_VALUE_ROSC_CLKSRC, ref_khz); +// local_rng_state.r[which] ^= splitmix64(measurement); +// (void) xoroshiro128ss(&local_rng_state); //churn to mix seed sources +// } + + // Gather a full ROSC sample array with sample bits + local_rng_state.r[which] ^= splitmix64(capture_additional_rosc_samples(8 * sizeof(rosc_samples))); + which ^= 1; +#endif + +#if PICO_RAND_SEED_ENTROPY_SRC_TIME + // Mix in hashed time. This is [possibly] predictable boot-to-boot + // but will vary application-to-application. + local_rng_state.r[which] ^= splitmix64(time_us_64()); + which ^= 1; +#endif + + spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_RAND); + uint32_t save = spin_lock_blocking(lock); + if (!rng_initialised) { +#if PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER +#if !PICO_RAND_BUSCTRL_COUNTER_INDEX + int idx = -1; + for(uint i = 0; i < count_of(bus_ctrl_hw->counter); i++) { + if (bus_ctrl_hw->counter[i].sel == BUSCTRL_PERFSEL0_RESET) { + idx = (int)i; + break; + } + } + hard_assert(idx != -1); + bus_counter_idx = (uint8_t)idx; +#else + bus_counter_idx = (uint8_t)PICO_RAND_BUSCTRL_COUNTER_INDEX; +#endif + bus_ctrl_hw->counter[bus_counter_idx].sel = PICO_RAND_BUS_PERF_COUNTER_EVENT; +#endif + (void) xoroshiro128ss(&local_rng_state); + rng_state = local_rng_state; + rng_initialised = true; + } + spin_unlock(lock, save); +} + +uint64_t get_rand_64(void) { + if (!rng_initialised) { + // Do not provide 'RNs' until the system has been initialised. Note: + // The first initialisation can be quite time-consuming depending on + // the amount of RAM hashed, see RAM_HASH_START and RAM_HASH_END + initialise_rand(); + } + + static volatile uint8_t check_byte; + rng_128_t local_rng_state = rng_state; + uint8_t local_check_byte = check_byte; + // Modify PRNG state with the run-time entropy sources, + // hashed to reduce correlation with previous modifications. + uint which = 0; +#if PICO_RAND_ENTROPY_SRC_TIME + local_rng_state.r[which] ^= splitmix64(time_us_64()); + which ^= 1; +#endif +#if PICO_RAND_ENTROPY_SRC_ROSC + local_rng_state.r[which] ^= splitmix64(capture_additional_rosc_samples(PICO_RAND_ROSC_BIT_SAMPLE_COUNT)); + which ^= 1; +#endif +#if PICO_RAND_ENTROPY_SRC_BUS_PERF_COUNTER + uint32_t bus_counter_value = bus_ctrl_hw->counter[bus_counter_idx].value; + // counter is saturating, so clear it if it has reached saturation + if (bus_counter_value == BUSCTRL_PERFCTR0_BITS) { + bus_ctrl_hw->counter[bus_counter_idx].value = 0; + } + local_rng_state.r[which] ^= splitmix64(bus_counter_value); + which ^= 1; +#endif + + spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_RAND); + uint32_t save = spin_lock_blocking(lock); + if (local_check_byte != check_byte) { + // someone got a random number in the interim, so mix it in + local_rng_state.r[0] ^= rng_state.r[0]; + local_rng_state.r[1] ^= rng_state.r[1]; + } + // Generate a 64-bit RN from the modified PRNG state. + // Note: This also "churns" the 128-bit state for next time. + uint64_t rand64 = xoroshiro128ss(&local_rng_state); + rng_state = local_rng_state; + check_byte++; + spin_unlock(lock, save); + + return rand64; +} + +void get_rand_128(rng_128_t *ptr128) { + ptr128->r[0] = get_rand_64(); + ptr128->r[1] = get_rand_64(); +} + +uint32_t get_rand_32(void) { + return (uint32_t) get_rand_64(); +} diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/trng_api.c b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/trng_api.c new file mode 100644 index 00000000000..b0886badcc8 --- /dev/null +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/trng_api.c @@ -0,0 +1,64 @@ +/* mbed Microcontroller Library + * Copyright (c) 2018 GigaDevice Semiconductor Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + */ +#if DEVICE_TRNG + +#include "trng_api.h" + +/** Initialize the TRNG peripheral + * + * @param obj The TRNG object + */ +void trng_init(trng_t *obj) +{ + (void)obj; +} + +/** Deinitialize the TRNG peripheral + * + * @param obj The TRNG object + */ +void trng_free(trng_t *obj) +{ + (void)obj; +} + +/** Get random data from TRNG peripheral + * + * @param obj The TRNG object + * @param output The pointer to an output array + * @param length The size of output data, to avoid buffer overwrite + * @param output_length The length of generated data + * @return 0 success, -1 fail + */ +int trng_get_bytes(trng_t *obj, uint8_t *output, size_t length, size_t *output_length) +{ + (void)obj; + *output_length = 0; + uint32_t random[16]; + + while (*output_length < length) { + get_rand_128((rng_128_t*)random); + for (uint8_t i = 0; (i < 16) && (*output_length < length) ; i++) { + *output++ = random[i]; + *output_length += 1; + random[i] = 0; + } + } + return 0; +} +#endif /* DEVICE_TRNG */ diff --git a/targets/targets.json b/targets/targets.json index 9a124223369..83fa8c930a3 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -9700,7 +9700,8 @@ "USTICKER", "WATCHDOG", "USBDEVICE", - "RESET_REASON" + "RESET_REASON", + "TRNG" ] }, "NANO_RP2040_CONNECT": { From b6356335fe51486b09503d758713663bf32b8b64 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 4 Jun 2024 13:08:07 +0200 Subject: [PATCH 05/37] Revert "QSPI: call is_mem_ready before trying to set write enable bit" This reverts commit 3724f4267a7fbf993aaf4cadb3e0249b210af908. --- .../blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp index cd21a7354db..ee8bab5556c 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp @@ -1243,11 +1243,6 @@ int QSPIFBlockDevice::_set_write_enable() uint8_t status_value = 0; int status = -1; - if (false == _is_mem_ready()) { - tr_error("Device not ready, set_write_enable failed"); - return -1; - } - do { if (QSPI_STATUS_OK != _qspi_send_general_command(QSPIF_INST_WREN, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0)) { tr_error("Sending WREN command FAILED"); From 87ecffb4f3809ceb1383fc0959b539aa5b28a2c4 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 4 Jun 2024 14:29:00 +0200 Subject: [PATCH 06/37] NiclaVision: enable red blink on mbed_die() --- .../TARGET_STM32H747xI/TARGET_NICLA_VISION/PinNames.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_NICLA_VISION/PinNames.h b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_NICLA_VISION/PinNames.h index 9f14a66d67e..42d24cd79d2 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_NICLA_VISION/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/TARGET_NICLA_VISION/PinNames.h @@ -467,6 +467,11 @@ typedef enum { NC = (int)0xFFFFFFFF } PinName; +// Standardized LED and button names +#define LED1 LED_RED +#define LED2 LED_GREEN +#define LED3 LED_BLUE + #ifdef __cplusplus } #endif From 898963ac170acf669aff3c8399381b1e71390529 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 2 Jul 2024 16:13:42 +0200 Subject: [PATCH 07/37] QSPI: call is_mem_ready before trying to set write enable bit for AT25SF128A This reverts commit f6d960e023a8d2300f3e850f5d721e87eeb95948. --- .../blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp index ee8bab5556c..b005aeb0f1e 100644 --- a/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp +++ b/storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp @@ -1243,7 +1243,13 @@ int QSPIFBlockDevice::_set_write_enable() uint8_t status_value = 0; int status = -1; + if (_AT25SF128A_quirk && (false == _is_mem_ready())) { + tr_error("Device not ready, set_write_enable failed"); + return -1; + } + do { + if (QSPI_STATUS_OK != _qspi_send_general_command(QSPIF_INST_WREN, QSPI_NO_ADDRESS_COMMAND, NULL, 0, NULL, 0)) { tr_error("Sending WREN command FAILED"); break; From f98b0fc9c71648b6f9aecc5780e393ea73b0cfc2 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 2 Jul 2024 16:30:07 +0200 Subject: [PATCH 08/37] emac_stm32: properly invalidate DCache before disabling it --- .../TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c | 3 +++ .../TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c | 1 + 2 files changed, 4 insertions(+) diff --git a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c index 0572fae7a2a..8b9cc8bcd03 100644 --- a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c +++ b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_OPTA/stm32h7_eth_init.c @@ -66,7 +66,10 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) #if !(defined(DUAL_CORE) && defined(CORE_CM4)) /* Disable DCache for STM32H7 family */ + core_util_critical_section_enter(); + SCB_CleanInvalidateDCache(); SCB_DisableDCache(); + core_util_critical_section_exit(); #endif /* GPIO Ports Clock Enable */ diff --git a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c index 643fc5acd36..7f5b4206cb5 100644 --- a/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c +++ b/connectivity/drivers/emac/TARGET_STM/TARGET_STM32H7/TARGET_PORTENTA_H7/stm32h7_eth_init.c @@ -68,6 +68,7 @@ void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) #if !(defined(DUAL_CORE) && defined(CORE_CM4)) /* Disable DCache for STM32H7 family */ core_util_critical_section_enter(); + SCB_CleanInvalidateDCache(); SCB_DisableDCache(); core_util_critical_section_exit(); #endif From 5114c7f56a82c37021cdd92f07bc1a2c62e85e64 Mon Sep 17 00:00:00 2001 From: maidnl Date: Mon, 8 Jul 2024 12:07:40 +0200 Subject: [PATCH 09/37] emac: stop/start dhcp on interface bringup --- connectivity/lwipstack/source/LWIPInterface.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index a1cfcf31c41..dfefebcb8bd 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -169,8 +169,12 @@ nsapi_error_t LWIP::Interface::set_dhcp() #if LWIP_DHCP if (dhcp_has_to_be_set) { + if(dhcp_started) { + dhcp_stop(&netif); + dhcp_started = false; + } + err_t err = dhcp_start(&netif); - dhcp_has_to_be_set = false; if (err) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { From e0cad5c4277b3c5ee9cb01a9529df9333612bbeb Mon Sep 17 00:00:00 2001 From: maidnl Date: Mon, 8 Jul 2024 12:08:48 +0200 Subject: [PATCH 10/37] emac: stm32: check inteface status before link_out() This allows handling of HAL_ETH_STATE_ERROR, usually on interface teardown/up with strict timings --- .../drivers/emac/TARGET_STM/stm32xx_emac.cpp | 27 +++++++++++++++++++ .../drivers/emac/TARGET_STM/stm32xx_emac.h | 7 +++++ .../lwipstack/source/LWIPInterfaceEMAC.cpp | 15 +++++++++-- .../netsocket/include/netsocket/EMAC.h | 11 ++++++++ .../STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c | 8 +----- 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp index 0230a90665c..0e7d64ad349 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.cpp @@ -402,6 +402,33 @@ bool STM32_EMAC::low_level_init_successful() } #endif // ETH_IP_VERSION_V2 +/** + * This function get the state of emac interface + */ +int STM32_EMAC::get_interface_status() { + return HAL_ETH_GetState(&EthHandle); +} + +/** + * This function returns true if the status of the interface is in the + * correct state for the trasmission + */ +bool STM32_EMAC::is_ready_to_tx() { + return (HAL_ETH_GetState(&EthHandle) == HAL_ETH_STATE_READY); +} + +/** + * This function reset the emac interface in case the status is in error + * Apparently there was not anything to recover from an error state + */ +void STM32_EMAC::restart() { + if(HAL_ETH_STATE_ERROR == HAL_ETH_GetState(&EthHandle)){ + HAL_ETH_Stop(&EthHandle); + HAL_ETH_Start(&EthHandle); + } +} + + /** * This function should do the actual transmission of the packet. The packet is * contained in the memory buffer chain that is passed to the function. diff --git a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h index cfa67521774..ecc280b2f84 100644 --- a/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h +++ b/connectivity/drivers/emac/TARGET_STM/stm32xx_emac.h @@ -148,6 +148,13 @@ class STM32_EMAC : public EMAC { */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr); + /* return the status of the interface as integer */ + int get_interface_status() override; + /* return true if the interface is in the correct state to transmit */ + bool is_ready_to_tx() override; + /* restart only if the interface is in error state */ + void restart() override; + // Called from driver functions ETH_HandleTypeDef EthHandle; osThreadId_t thread; /**< Processing thread */ diff --git a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp index 56fbcc0d904..ed4397879ef 100644 --- a/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp +++ b/connectivity/lwipstack/source/LWIPInterfaceEMAC.cpp @@ -27,15 +27,26 @@ #if LWIP_ETHERNET + err_t LWIP::Interface::emac_low_level_output(struct netif *netif, struct pbuf *p) { + bool ret = false; /* Increase reference counter since lwip stores handle to pbuf and frees it after output */ pbuf_ref(p); LWIP::Interface *mbed_if = static_cast(netif->state); - bool ret = mbed_if->emac->link_out(p); - return ret ? ERR_OK : ERR_IF; + + if(mbed_if->emac->is_ready_to_tx()) { + ret = mbed_if->emac->link_out(p); + } + else { + mbed_if->emac->restart(); + ret = mbed_if->emac->link_out(p); + } + + err_t rv = ret ? ERR_OK : ERR_IF; + return rv; } void LWIP::Interface::emac_input(emac_mem_buf_t *buf) diff --git a/connectivity/netsocket/include/netsocket/EMAC.h b/connectivity/netsocket/include/netsocket/EMAC.h index 515629b5a61..885bc92c017 100644 --- a/connectivity/netsocket/include/netsocket/EMAC.h +++ b/connectivity/netsocket/include/netsocket/EMAC.h @@ -176,6 +176,17 @@ class EMAC { * @param mem_mngr Pointer to memory manager */ virtual void set_memory_manager(EMACMemoryManager &mem_mngr) = 0; + + virtual bool is_ready_to_tx() { + return true; + } + + virtual void restart() { + } + + virtual int get_interface_status() { + return -1; + } }; diff --git a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c index decff79455a..df797092fc1 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c +++ b/targets/TARGET_STM/TARGET_STM32H7/STM32Cube_FW/STM32H7xx_HAL_Driver/stm32h7xx_hal_eth.c @@ -2341,13 +2341,7 @@ HAL_StatusTypeDef HAL_ETH_SetWakeUpFilter(ETH_HandleTypeDef *heth, uint32_t *pFi */ HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth) { - HAL_ETH_StateTypeDef ret; - HAL_ETH_StateTypeDef gstate = heth->gState; - HAL_ETH_StateTypeDef rxstate =heth->RxState; - - ret = gstate; - ret |= rxstate; - return ret; + return heth->gState; } /** From cc7e1c9089316674297e9499b7c1b0c2e937cc2e Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 11 Sep 2024 12:24:01 +0200 Subject: [PATCH 11/37] RP2040: add second_stage_ota section to linker script - This was previously done inside mbed-os-to-arduino script --- .../TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld index ec8bac7e404..8295f3269d5 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld @@ -54,6 +54,10 @@ SECTIONS __flash_binary_start = .; } > FLASH + .second_stage_ota : { + KEEP (*(.second_stage_ota)) + } > FLASH + .boot2 : { __boot2_start__ = .; KEEP (*(.boot2)) From 1844a65b257fab1fa83e41906e5dd73f4e612ecd Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 11 Sep 2024 12:27:03 +0200 Subject: [PATCH 12/37] RP2040: add simbols to linker script to compute .uninitialized_data section size --- .../TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld | 2 ++ 1 file changed, 2 insertions(+) diff --git a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld index 8295f3269d5..b748bab5fad 100644 --- a/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld +++ b/targets/TARGET_RASPBERRYPI/TARGET_RP2040/TOOLCHAIN_GCC_ARM/memmap_default.ld @@ -183,7 +183,9 @@ SECTIONS .uninitialized_data (COPY): { . = ALIGN(4); + __uninitialized_data_start__ = .; *(.uninitialized_data*) + __uninitialized_data_end__ = .; } > RAM /* Start and end symbols must be word-aligned */ From 81a7d47a15e76701b206bce907526b9d9d5888cc Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 2 Oct 2024 11:31:36 +0200 Subject: [PATCH 13/37] Watchdog: kick only if watchdog is running --- drivers/source/Watchdog.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/source/Watchdog.cpp b/drivers/source/Watchdog.cpp index 3f21b94dfb1..daca0181483 100644 --- a/drivers/source/Watchdog.cpp +++ b/drivers/source/Watchdog.cpp @@ -72,9 +72,11 @@ bool Watchdog::stop() void Watchdog::kick() { - core_util_critical_section_enter(); - hal_watchdog_kick(); - core_util_critical_section_exit(); + if (_running) { + core_util_critical_section_enter(); + hal_watchdog_kick(); + core_util_critical_section_exit(); + } } bool Watchdog::is_running() const From e959ae057b31849f779904ce97bfabc68658f53e Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 17 Jun 2024 17:11:58 +0200 Subject: [PATCH 14/37] WHD: reduce the number of join retry --- .../drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp index 509a2c0981e..c933203d363 100644 --- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp +++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp @@ -260,7 +260,7 @@ nsapi_error_t WhdSTAInterface::connect() { ScopedMutexLock lock(_iface_shared.mutex); -#define MAX_RETRY_COUNT ( 5 ) +#define MAX_RETRY_COUNT ( 1 ) int i; whd_result_t res; From efd54c8990ba5b437eb4eb8b786b7e48941b03f1 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 21 Oct 2024 11:27:36 +0200 Subject: [PATCH 15/37] WHD: add join timeout parameter to WiFiSTAInterface and drivers --- .../emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp | 7 ++++--- .../emac/COMPONENT_WHD/interface/WhdSTAInterface.h | 6 ++++++ .../COMPONENT_WHD/wifi-host-driver/inc/whd_wifi_api.h | 2 +- .../COMPONENT_WHD/wifi-host-driver/src/whd_wifi_api.c | 9 ++++++--- connectivity/netsocket/include/netsocket/WiFiInterface.h | 7 +++++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp index c933203d363..f7631a05831 100644 --- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp +++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp @@ -211,7 +211,8 @@ WhdSTAInterface::WhdSTAInterface(WHD_EMAC &emac, OnboardNetworkStack &stack, Olm _security(NSAPI_SECURITY_NONE), _whd_emac(emac), _olm(&olm), - _iface_shared(shared) + _iface_shared(shared), + _timeout(7000) { } @@ -334,7 +335,7 @@ nsapi_error_t WhdSTAInterface::connect() res = (whd_result_t)whd_wifi_join(_whd_emac.ifp, &ssid, security, - (const uint8_t *)_pass, strlen(_pass)); + (const uint8_t *)_pass, strlen(_pass), _timeout); } else { @@ -345,7 +346,7 @@ nsapi_error_t WhdSTAInterface::connect() res = (whd_result_t)whd_wifi_join(_whd_emac.ifp, &ssid, security, - (const uint8_t *)_pass, key_length); + (const uint8_t *)_pass, key_length, _timeout); } if (res == WHD_SUCCESS) { break; diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h index 4dd10989472..bfe933bac74 100644 --- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h +++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h @@ -119,6 +119,11 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { return 0; } + nsapi_error_t set_timeout(uint32_t timeout) + { + _timeout = timeout; + } + /** Set blocking status of interface. * Nonblocking mode unsupported. * @@ -257,6 +262,7 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { nsapi_security_t _security; WHD_EMAC &_whd_emac; OlmInterface *_olm; + uint32_t _timeout; whd_interface_shared_info_t &_iface_shared; }; diff --git a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_wifi_api.h b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_wifi_api.h index f3b73214cbb..291bd23de8e 100755 --- a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_wifi_api.h +++ b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_wifi_api.h @@ -281,7 +281,7 @@ extern uint32_t whd_wifi_stop_scan(whd_interface_t ifp); * Error code if an error occurred */ extern uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length); + const uint8_t *security_key, uint8_t key_length, uint32_t timeout); /** Joins a specific Wi-Fi network * diff --git a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/src/whd_wifi_api.c b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/src/whd_wifi_api.c index 5294104ab4d..8a8f411ef98 100755 --- a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/src/whd_wifi_api.c +++ b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/src/whd_wifi_api.c @@ -294,6 +294,8 @@ static const uint16_t mcs_data_rate_lookup_table[32][2][2] = }, }; +static whd_wifi_join_timeout = DEFAULT_JOIN_ATTEMPT_TIMEOUT; + /****************************************************** * Static Function prototypes @@ -1334,7 +1336,7 @@ static uint32_t whd_wifi_join_wait_for_complete(whd_interface_t ifp, cy_semaphor while (!done) { - result = cy_rtos_get_semaphore(semaphore, DEFAULT_JOIN_ATTEMPT_TIMEOUT / 10, WHD_FALSE); + result = cy_rtos_get_semaphore(semaphore, whd_wifi_join_timeout / 10, WHD_FALSE); whd_assert("Get semaphore failed", (result == CY_RSLT_SUCCESS) || (result == CY_RTOS_TIMEOUT) ); REFERENCE_DEBUG_ONLY_VARIABLE(result); @@ -1345,7 +1347,7 @@ static uint32_t whd_wifi_join_wait_for_complete(whd_interface_t ifp, cy_semaphor } cy_rtos_get_time(¤t_time); - done = (whd_bool_t)( (current_time - start_time) >= DEFAULT_JOIN_ATTEMPT_TIMEOUT ); + done = (whd_bool_t)( (current_time - start_time) >= whd_wifi_join_timeout ); } if (result != WHD_SUCCESS) @@ -1574,7 +1576,7 @@ uint32_t whd_wifi_join_specific(whd_interface_t ifp, const whd_scan_result_t *ap } uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security_t auth_type, - const uint8_t *security_key, uint8_t key_length) + const uint8_t *security_key, uint8_t key_length, uint32_t timeout) { cy_semaphore_t join_sema; whd_result_t result; @@ -1616,6 +1618,7 @@ uint32_t whd_wifi_join(whd_interface_t ifp, const whd_ssid_t *ssid, whd_security ssid_params->SSID_len = htod32(ssid->length); memcpy(ssid_params->SSID, ssid->value, ssid_params->SSID_len); result = whd_cdc_send_ioctl(ifp, CDC_SET, WLC_SET_SSID, buffer, 0); + whd_wifi_join_timeout = timeout; if (result == WHD_SUCCESS) { diff --git a/connectivity/netsocket/include/netsocket/WiFiInterface.h b/connectivity/netsocket/include/netsocket/WiFiInterface.h index 4fd7fc6fb8a..c13cab4312b 100644 --- a/connectivity/netsocket/include/netsocket/WiFiInterface.h +++ b/connectivity/netsocket/include/netsocket/WiFiInterface.h @@ -59,6 +59,13 @@ class WiFiInterface: public virtual NetworkInterface { */ virtual nsapi_error_t set_channel(uint8_t channel) = 0; + /** Set the Wi-Fi network join timeout. + * + * @param timeout joint timeout in milliseconds (Default: 7000). + * @return NSAPI_ERROR_OK on success, or error code on failure. + */ + virtual nsapi_error_t set_timeout(uint32_t timeout) = 0; + /** Get the current radio signal strength for active connection. * * @return Connection strength in dBm (negative value), From 4369443525c662ddb2ecb15dd9cdba0098e1f01d Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 28 Oct 2024 09:56:31 +0100 Subject: [PATCH 16/37] TLSSocketWrapper: add read/write event flags This allows to properly handle timeouts during read write operations --- .../netsocket/include/netsocket/TLSSocketWrapper.h | 4 ++++ connectivity/netsocket/source/TLSSocketWrapper.cpp | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/connectivity/netsocket/include/netsocket/TLSSocketWrapper.h b/connectivity/netsocket/include/netsocket/TLSSocketWrapper.h index 2dc3b4b0004..79fe5c564de 100644 --- a/connectivity/netsocket/include/netsocket/TLSSocketWrapper.h +++ b/connectivity/netsocket/include/netsocket/TLSSocketWrapper.h @@ -379,6 +379,10 @@ class TLSSocketWrapper : public Socket { Socket *_transport; int _timeout = -1; + // Event flags + static const int READ_FLAG = 0x1u; + static const int WRITE_FLAG = 0x2u; + #ifdef MBEDTLS_X509_CRT_PARSE_C mbedtls_x509_crt *_cacert = nullptr; mbedtls_x509_crt *_clicert = nullptr; diff --git a/connectivity/netsocket/source/TLSSocketWrapper.cpp b/connectivity/netsocket/source/TLSSocketWrapper.cpp index c020cd9f593..3a66be2e5ec 100644 --- a/connectivity/netsocket/source/TLSSocketWrapper.cpp +++ b/connectivity/netsocket/source/TLSSocketWrapper.cpp @@ -381,7 +381,7 @@ nsapi_error_t TLSSocketWrapper::continue_handshake() ret = mbedtls_ssl_handshake(&_ssl); if (_timeout && (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)) { uint32_t flag; - flag = _event_flag.wait_any(1, _timeout); + flag = _event_flag.wait_any(WRITE_FLAG | READ_FLAG, _timeout); if (flag & osFlagsError) { break; } @@ -461,7 +461,7 @@ nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size) break; } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) { uint32_t flag; - flag = _event_flag.wait_any(1, _timeout); + flag = _event_flag.wait_any(WRITE_FLAG, _timeout); if (flag & osFlagsError) { // Timeout break break; @@ -522,7 +522,7 @@ nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size) break; } else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) { uint32_t flag; - flag = _event_flag.wait_any(1, _timeout); + flag = _event_flag.wait_any(READ_FLAG, _timeout); if (flag & osFlagsError) { // Timeout break break; @@ -855,7 +855,7 @@ nsapi_error_t TLSSocketWrapper::listen(int) void TLSSocketWrapper::event() { - _event_flag.set(1); + _event_flag.set(READ_FLAG | WRITE_FLAG); if (_sigio) { _sigio(); } From 6174f40a6124d9999ebcfe304f7dcfb295ecdca9 Mon Sep 17 00:00:00 2001 From: Guilherme Ricioli Date: Mon, 15 Apr 2024 17:40:59 -0300 Subject: [PATCH 17/37] Add methods for setting hostname In the same way it is done for setting MAC address, add methods for setting hostname. The underlying network stack can then request this to the local DNS through DHCP. --- .../include/netsocket/EMACInterface.h | 8 ++++++ .../include/netsocket/NetworkInterface.h | 16 ++++++++++++ .../netsocket/include/netsocket/nsapi_types.h | 10 +++++++ .../netsocket/source/EMACInterface.cpp | 26 +++++++++++++++++++ .../netsocket/source/NetworkInterface.cpp | 10 +++++++ .../doubles/NetworkInterface_stub.cpp | 10 +++++++ .../test_NetworkInterface.cpp | 11 ++++++++ 7 files changed, 91 insertions(+) diff --git a/connectivity/netsocket/include/netsocket/EMACInterface.h b/connectivity/netsocket/include/netsocket/EMACInterface.h index 8cf47cb7036..c06aeb850e5 100644 --- a/connectivity/netsocket/include/netsocket/EMACInterface.h +++ b/connectivity/netsocket/include/netsocket/EMACInterface.h @@ -83,6 +83,12 @@ class EMACInterface : public virtual NetworkInterface { /** @copydoc NetworkInterface::disconnect */ nsapi_error_t disconnect() override; + /** @copydoc NetworkInterface::get_hostname */ + const char *get_hostname() override; + + /** @copydoc NetworkInterface::set_hostname */ + nsapi_error_t set_hostname(const char *hostname) override; + /** @copydoc NetworkInterface::get_mac_address */ const char *get_mac_address() override; @@ -146,6 +152,8 @@ class EMACInterface : public virtual NetworkInterface { OnboardNetworkStack::Interface *_interface = nullptr; bool _dhcp = true; bool _blocking = true; + bool _hostname_set = false; + char _hostname[NSAPI_HOSTNAME_SIZE]; bool _hw_mac_addr_set = false; char _mac_address[NSAPI_MAC_SIZE]; char _ip_address[NSAPI_IPv6_SIZE] {}; diff --git a/connectivity/netsocket/include/netsocket/NetworkInterface.h b/connectivity/netsocket/include/netsocket/NetworkInterface.h index 9071a1e40bd..81f60119508 100644 --- a/connectivity/netsocket/include/netsocket/NetworkInterface.h +++ b/connectivity/netsocket/include/netsocket/NetworkInterface.h @@ -90,6 +90,22 @@ class NetworkInterface: public DNS { */ virtual void set_as_default(); + /** Get hostname. + * + * @return Hostname if configured, null otherwise + */ + virtual const char *get_hostname(); + + /** Set hostname. + * + * @param hostname Hostname string + * @retval NSAPI_ERROR_OK on success + * @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported + * @retval NSAPI_ERROR_PARAMETER if hostname is not valid + * @retval NSAPI_ERROR_BUSY if hostname couldn't be set + */ + virtual nsapi_error_t set_hostname(const char *hostname); + /** Get the local MAC address. * * Provided MAC address is intended for info or debug purposes and diff --git a/connectivity/netsocket/include/netsocket/nsapi_types.h b/connectivity/netsocket/include/netsocket/nsapi_types.h index 3b496d5087a..28dbcc9a38d 100644 --- a/connectivity/netsocket/include/netsocket/nsapi_types.h +++ b/connectivity/netsocket/include/netsocket/nsapi_types.h @@ -196,6 +196,16 @@ typedef enum nsapi_security { */ #define NSAPI_IP_BYTES NSAPI_IPv6_BYTES +/** Maximum size of hostname + * + * According to RFC 1034 [1], Section 3.1 "Name space specifications and + * terminology", 63 is the maximum size of a hostname. +1 for the string + * terminator. + * + * [1] https://www.rfc-editor.org/rfc/rfc1034 + */ +#define NSAPI_HOSTNAME_SIZE 64 + /** Maximum size of MAC address representation */ #define NSAPI_MAC_SIZE 18 diff --git a/connectivity/netsocket/source/EMACInterface.cpp b/connectivity/netsocket/source/EMACInterface.cpp index f48bc0a185a..de8d9753d7c 100644 --- a/connectivity/netsocket/source/EMACInterface.cpp +++ b/connectivity/netsocket/source/EMACInterface.cpp @@ -88,6 +88,32 @@ nsapi_error_t EMACInterface::disconnect() return NSAPI_ERROR_NO_CONNECTION; } +const char *EMACInterface::get_hostname() +{ + if (_hostname_set) { + return _hostname; + } + return nullptr; +} + +nsapi_error_t EMACInterface::set_hostname(const char *hostname) +{ + if (!hostname || strlen(hostname) > NSAPI_HOSTNAME_SIZE - 1) { + return NSAPI_ERROR_PARAMETER; + } + + if (_interface) { + // can't set hostname once initialized + return NSAPI_ERROR_BUSY; + } + + memset(_hostname, 0, NSAPI_HOSTNAME_SIZE); + strncpy(_hostname, hostname, NSAPI_HOSTNAME_SIZE - 1); + _hostname_set = true; + + return NSAPI_ERROR_OK; +} + const char *EMACInterface::get_mac_address() { if (_interface && _interface->get_mac_address(_mac_address, sizeof(_mac_address))) { diff --git a/connectivity/netsocket/source/NetworkInterface.cpp b/connectivity/netsocket/source/NetworkInterface.cpp index 0f237f0e190..649df0f9b30 100644 --- a/connectivity/netsocket/source/NetworkInterface.cpp +++ b/connectivity/netsocket/source/NetworkInterface.cpp @@ -29,6 +29,16 @@ void NetworkInterface::set_as_default() } +const char *NetworkInterface::get_hostname() +{ + return 0; +} + +nsapi_error_t NetworkInterface::set_hostname(const char *hostname) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkInterface::get_mac_address() { return 0; diff --git a/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp b/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp index 020a551ba97..c849704a35b 100644 --- a/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp +++ b/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp @@ -21,6 +21,16 @@ // Default network-interface state +const char *NetworkInterface::get_hostname() +{ + return 0; +} + +nsapi_error_t NetworkInterface::set_hostname(const char *hostname) +{ + return NSAPI_ERROR_UNSUPPORTED; +} + const char *NetworkInterface::get_mac_address() { return 0; diff --git a/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp b/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp index 1a928c36ee1..27433ffaa1f 100644 --- a/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp +++ b/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp @@ -68,6 +68,17 @@ TEST_F(TestNetworkInterface, constructor) } // get_default_instance is tested along with the implementations of NetworkInterface. +TEST_F(TestNetworkInterface, get_hostname) +{ + char *n = 0; + EXPECT_EQ(iface->get_hostname(), n); +} + +TEST_F(TestNetworkInterface, set_hostname) +{ + char *hostname; + EXPECT_EQ(iface->set_hostname(hostname), NSAPI_ERROR_UNSUPPORTED); +} TEST_F(TestNetworkInterface, get_mac_address) { From 0895c1a7b666877a838d51ff66565571c8087edd Mon Sep 17 00:00:00 2001 From: Guilherme Ricioli Date: Tue, 16 Apr 2024 10:50:48 -0300 Subject: [PATCH 18/37] Request hostname through DHCP If hostname is provided, request it to local DNS through DHCP. --- connectivity/lwipstack/source/LWIPInterface.cpp | 6 ++++++ connectivity/netsocket/include/netsocket/NetworkInterface.h | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index dfefebcb8bd..64869a3538d 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -437,6 +437,7 @@ LWIP::Interface::Interface() : nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface) { #if LWIP_ETHERNET + const char *hostname; Interface *interface = new (std::nothrow) Interface(); if (!interface) { return NSAPI_ERROR_NO_MEMORY; @@ -445,6 +446,11 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN interface->memory_manager = &memory_manager; interface->ppp_enabled = false; + hostname = user_network_interface->get_hostname(); + if (hostname) { + netif_set_hostname(&interface->netif, hostname); + } + #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) netif->interface.hwaddr[0] = MBED_MAC_ADDR_0; netif->interface.hwaddr[1] = MBED_MAC_ADDR_1; diff --git a/connectivity/netsocket/include/netsocket/NetworkInterface.h b/connectivity/netsocket/include/netsocket/NetworkInterface.h index 81f60119508..22355767cef 100644 --- a/connectivity/netsocket/include/netsocket/NetworkInterface.h +++ b/connectivity/netsocket/include/netsocket/NetworkInterface.h @@ -102,7 +102,9 @@ class NetworkInterface: public DNS { * @retval NSAPI_ERROR_OK on success * @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported * @retval NSAPI_ERROR_PARAMETER if hostname is not valid - * @retval NSAPI_ERROR_BUSY if hostname couldn't be set + * @retval NSAPI_ERROR_BUSY if hostname couldn't be set (e.g. for + * LwIP stack, hostname can only be set before calling + * \c EthernetInterface::connect method) */ virtual nsapi_error_t set_hostname(const char *hostname); From f8cc3e452b3e9d06b067d82a1121711b54f2fd17 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 3 Oct 2024 18:05:26 +0200 Subject: [PATCH 19/37] WhdSTA allow hostname configuration --- .../drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp index f7631a05831..e90c12b3197 100644 --- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp +++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp @@ -281,7 +281,7 @@ nsapi_error_t WhdSTAInterface::connect() _iface_shared.if_status_flags |= IF_STATUS_STA_UP; _iface_shared.default_if_cfg = DEFAULT_IF_STA; if (!_interface) { - nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface); + nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface, this); if (err != NSAPI_ERROR_OK) { _interface = NULL; return err; From 4292f8b7c4aa38b68d22c413f91bdc95192cfad6 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 29 Oct 2024 11:30:00 +0100 Subject: [PATCH 20/37] Add user network interface check before reading hostname --- connectivity/lwipstack/source/LWIPInterface.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp index 64869a3538d..da964543c79 100644 --- a/connectivity/lwipstack/source/LWIPInterface.cpp +++ b/connectivity/lwipstack/source/LWIPInterface.cpp @@ -446,9 +446,11 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN interface->memory_manager = &memory_manager; interface->ppp_enabled = false; - hostname = user_network_interface->get_hostname(); - if (hostname) { - netif_set_hostname(&interface->netif, hostname); + if (user_network_interface) { + hostname = user_network_interface->get_hostname(); + if (hostname) { + netif_set_hostname(&interface->netif, hostname); + } } #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) From 310f0dd40c5b070ea2077c8a580f777a5cf17951 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 7 Jan 2025 09:47:09 +0100 Subject: [PATCH 21/37] WHD: fix WhdSTAInterface, add return value to set_timeout --- .../drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h index bfe933bac74..8d8f5407591 100644 --- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h +++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.h @@ -122,6 +122,7 @@ class WhdSTAInterface : public WiFiInterface, public EMACInterface { nsapi_error_t set_timeout(uint32_t timeout) { _timeout = timeout; + return NSAPI_ERROR_OK; } /** Set blocking status of interface. From fa1e9697ca3b74489bd2eb08ab9ab1ffeee2a298 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 31 Jan 2025 16:34:05 +0100 Subject: [PATCH 22/37] WHD: remove v from WHD_VERSION define --- .../wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_version.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_version.h b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_version.h index 1caef23b67d..5f69d8c3e08 100755 --- a/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_version.h +++ b/connectivity/drivers/wifi/COMPONENT_WHD/wifi-host-driver/inc/whd_version.h @@ -15,6 +15,7 @@ * limitations under the License. */ -#define WHD_VERSION "v1.94.0" +/* This define is used by arduino::WiFiClass::firmwareVersion() do not prepend v */ +#define WHD_VERSION "1.94.0" #define WHD_BRANCH "v1.94.0" #define WHD_DATE "2021-04-27 16:54:34 +0800" From 933694e0f35451d21eed77a93fa346570de20878 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 4 Feb 2025 14:31:59 +0100 Subject: [PATCH 23/37] ICMPSocket: add ping --- .../netsocket/include/netsocket/ICMPSocket.h | 4 ++ connectivity/netsocket/source/ICMPSocket.cpp | 61 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/connectivity/netsocket/include/netsocket/ICMPSocket.h b/connectivity/netsocket/include/netsocket/ICMPSocket.h index 1837bc8e096..5e1ee8fb03a 100644 --- a/connectivity/netsocket/include/netsocket/ICMPSocket.h +++ b/connectivity/netsocket/include/netsocket/ICMPSocket.h @@ -37,6 +37,10 @@ class ICMPSocket : public InternetDatagramSocket { */ ICMPSocket(); +#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED + int ping(SocketAddress &socketAddress, uint32_t timeout); +#endif + #if !defined(DOXYGEN_ONLY) protected: diff --git a/connectivity/netsocket/source/ICMPSocket.cpp b/connectivity/netsocket/source/ICMPSocket.cpp index f6c9b98de10..d8ea9548350 100644 --- a/connectivity/netsocket/source/ICMPSocket.cpp +++ b/connectivity/netsocket/source/ICMPSocket.cpp @@ -16,12 +16,73 @@ */ #include "ICMPSocket.h" +#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED +#include "drivers/Timer.h" +#include "lwip/prot/icmp.h" +#include "lwip/inet_chksum.h" +#include "lwip/prot/ip4.h" +#endif ICMPSocket::ICMPSocket() { _socket_stats.stats_update_proto(this, NSAPI_ICMP); } +#if MBED_CONF_LWIP_RAW_SOCKET_ENABLED +int ICMPSocket::ping(SocketAddress &socketAddress, uint32_t timeout) +{ + struct __attribute__((__packed__)) { + struct icmp_echo_hdr header; + uint8_t data[32]; + } request; + + ICMPH_TYPE_SET(&request.header, ICMP_ECHO); + ICMPH_CODE_SET(&request.header, 0); + request.header.chksum = 0; + request.header.id = 0xAFAF; + request.header.seqno = random(); + + for (size_t i = 0; i < sizeof(request.data); i++) { + request.data[i] = i; + } + + request.header.chksum = inet_chksum(&request, sizeof(request)); + + int res = sendto(socketAddress, &request, sizeof(request)); + if (res <= 0){ + return -1; + } + + mbed::Timer timer; + timer.start(); + int elapsed = -1; + do { + struct __attribute__((__packed__)) { + struct ip_hdr ipHeader; + struct icmp_echo_hdr header; + } response; + + int rxSize = recvfrom(&socketAddress, &response, sizeof(response)); + if (rxSize < 0) { + // time out + break; + } + + if (rxSize < sizeof(response)) { + // too short + continue; + } + + if ((response.header.id == request.header.id) && (response.header.seqno == request.header.seqno)) { + elapsed = std::chrono::duration_cast(timer.elapsed_time()).count(); + timer.stop(); + } + } while (elapsed == -1 && std::chrono::duration_cast(timer.elapsed_time()).count() < timeout); + + return elapsed; +} +#endif + nsapi_protocol_t ICMPSocket::get_proto() { return NSAPI_ICMP; From 0a46788865cf2e9ea2026c30f82651e5198ffcfe Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 31 Oct 2024 11:05:18 +0100 Subject: [PATCH 24/37] GEMALTO CINTERION: cleanup stack before connection Allows to re-connect after a disconnection --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp index 78955c599e1..76c788cdaf5 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularContext.cpp @@ -35,6 +35,11 @@ nsapi_error_t GEMALTO_CINTERION_CellularContext::connect(const char *sim_pin, co { nsapi_error_t error = NSAPI_ERROR_OK; + if (_stack) { + delete _stack; + _stack = NULL; + } + set_sim_pin(sim_pin); set_credentials(apn, uname, pwd); From b302e3da3f048fe6c180d283b6238e15e1937a02 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 31 Oct 2024 12:00:51 +0100 Subject: [PATCH 25/37] GEMALTO CINTERION: close socket on timeout --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index ac2a54282a2..41a01859e7f 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -59,7 +59,7 @@ void GEMALTO_CINTERION_CellularStack::urc_sis() } if (urc_code == 0) { int urc_info_id = _at.read_int(); - if (urc_info_id == 48) { + if (urc_info_id == 48 || urc_info_id == 20) { tr_info("Socket closed %d", sock_id); sock->closed = true; if (sock->_cb) { From 05d8c2674faee57dd449a42abce47d6dc800baf7 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 31 Oct 2024 12:01:47 +0100 Subject: [PATCH 26/37] GEMALTO CINTERION: add debug for urc_sis --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index 41a01859e7f..9a3f22dc3cc 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -47,6 +47,8 @@ void GEMALTO_CINTERION_CellularStack::urc_sis() int sock_id = _at.read_int(); int urc_code = _at.read_int(); CellularSocket *sock = find_socket(sock_id); + + tr_info("urc_sis socket id %d urc code %d\n\r", sock_id, urc_code); if (sock) { // Currently only UDP is supported so there is need to handle only some error codes here, // and others are detected on sendto/recvfrom responses. @@ -59,6 +61,7 @@ void GEMALTO_CINTERION_CellularStack::urc_sis() } if (urc_code == 0) { int urc_info_id = _at.read_int(); + tr_info("urcInfoId %d\n\r", urc_info_id); if (urc_info_id == 48 || urc_info_id == 20) { tr_info("Socket closed %d", sock_id); sock->closed = true; From 183dd7ccf9eccf86f9390fa1d9c3f5dde6ef4614 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 31 Oct 2024 12:03:00 +0100 Subject: [PATCH 27/37] GEMALTO CINTERION: add configuration for urcs during read --- .../CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index 9a3f22dc3cc..a96cb2b3608 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -527,8 +527,13 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul return (_at.get_last_error() == NSAPI_ERROR_OK) ? accept_len : NSAPI_ERROR_DEVICE_ERROR; } -#define DISABLE_URCs _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","off") -#define RESTORE_URCs_AND_RETURN(ret) do { _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","on"); return ret; } while(0) +#if defined GEMALTO_CINTERION_DISABLE_URC_READING + #define DISABLE_URCs _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","off") + #define RESTORE_URCs_AND_RETURN(ret) do { _at.at_cmd_discard("^SCFG", "=", "%s%s","Tcp/WithURCs","on"); return ret; } while(0) +#else + #define DISABLE_URCs + #define RESTORE_URCs_AND_RETURN(ret) do { return ret; } while(0) +#endif nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address, void *buffer, nsapi_size_t size) From 2e7a2a975acc9a74c5495a85c7602e2a616b35ca Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 13 Nov 2024 08:28:13 +0100 Subject: [PATCH 28/37] GEMALTO CINTERION: fix enable cmux command --- .../cellular/source/framework/AT/AT_CellularDevice.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp b/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp index 08229ba49ba..3eccc4a5c0e 100644 --- a/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp +++ b/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp @@ -50,6 +50,7 @@ AT_CellularDevice::AT_CellularDevice(FileHandle *fh, char *delim): _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT), _modem_debug_on(false), + _cmux_status(false), _property_array(NULL) { MBED_ASSERT(fh); @@ -243,10 +244,10 @@ nsapi_error_t AT_CellularDevice::get_sim_state(SimState &state) nsapi_error_t AT_CellularDevice::enable_cmux() { -setup_at_handler(); - + setup_at_handler(); _at.lock(); for (int retry = 1; retry <= 3; retry++) { + is_ready(); _at.clear_error(); _at.flush(); _at.at_cmd_discard("E0", ""); @@ -259,10 +260,9 @@ setup_at_handler(); tr_debug("Wait 100ms to init modem"); rtos::ThisThread::sleep_for(100ms); // let modem have time to get ready } - return _at.unlock_return_error(); + return _at.unlock_return_error(); } - bool AT_CellularDevice::is_cmux_enabled() { return _cmux_status; @@ -272,6 +272,7 @@ void AT_CellularDevice::set_cmux_status_flag(bool cmux_status) { _cmux_status = cmux_status; } + nsapi_error_t AT_CellularDevice::set_pin(const char *sim_pin) { // if SIM is already in ready state then settings the PIN From 1de85b5e0f2490bf25b464234f70fc991dabcfbe Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 13 Nov 2024 08:29:14 +0100 Subject: [PATCH 29/37] GEMALTO CINTERION: override shutdown function --- .../cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp | 6 ++++++ .../drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h | 1 + 2 files changed, 7 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp index 1f82199106e..c00c1880e4f 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp @@ -92,6 +92,12 @@ nsapi_error_t GEMALTO_CINTERION::init() return NSAPI_ERROR_OK; } +nsapi_error_t GEMALTO_CINTERION::shutdown() +{ + CellularDevice::shutdown(); + return NSAPI_ERROR_OK; +} + GEMALTO_CINTERION::Module GEMALTO_CINTERION::get_module() { return _module; diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h index 21d5888383d..e77078cb49d 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h @@ -55,6 +55,7 @@ class GEMALTO_CINTERION : public AT_CellularDevice { protected: virtual nsapi_error_t init(); + virtual nsapi_error_t shutdown(); private: static Module _module; From 531e738b0a49a34254c80007059a9ba4b79b2524 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 13 Nov 2024 08:30:47 +0100 Subject: [PATCH 30/37] GEMALTO CINTERION: use default timeout to close sockets --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index a96cb2b3608..f96ae481f0d 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -252,14 +252,10 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id) { tr_debug("Cinterion close %d", sock_id); - _at.set_at_timeout(FAILURE_TIMEOUT); - _at.at_cmd_discard("^SISC", "=", "%d", sock_id); _at.clear_error(); // clear SISS even though SISC fails - _at.restore_at_timeout(); - return _at.get_last_error(); } From a82b0c53579c44149b1700105e324749a5f6a29f Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 14 Nov 2024 15:57:07 +0100 Subject: [PATCH 31/37] GEMALTO CINTERION: add soft_power_off() and soft_reset() --- .../include/cellular/framework/API/CellularDevice.h | 11 +++++++++++ .../include/cellular/framework/AT/AT_CellularDevice.h | 2 ++ .../source/framework/AT/AT_CellularDevice.cpp | 5 +++++ .../cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp | 10 ++++++++++ .../cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h | 2 ++ 5 files changed, 30 insertions(+) diff --git a/connectivity/cellular/include/cellular/framework/API/CellularDevice.h b/connectivity/cellular/include/cellular/framework/API/CellularDevice.h index 0c8d1a2db2c..69455e1567c 100644 --- a/connectivity/cellular/include/cellular/framework/API/CellularDevice.h +++ b/connectivity/cellular/include/cellular/framework/API/CellularDevice.h @@ -201,6 +201,17 @@ class CellularDevice { */ virtual nsapi_error_t soft_power_off() = 0; + /** Resets the modem via AT command + * + * @remark CellularStateMachine disconnect or destruct does not reset the modem, + * but you need to do that yourself. + * + * @pre You must call shutdown to prepare the modem for reset. + * + * @return NSAPI_ERROR_OK on success + */ + virtual nsapi_error_t soft_reset() = 0; + /** Open the SIM card by setting the pin code for SIM. * * @param sim_pin PIN for the SIM card diff --git a/connectivity/cellular/include/cellular/framework/AT/AT_CellularDevice.h b/connectivity/cellular/include/cellular/framework/AT/AT_CellularDevice.h index fa011a09681..0006b6c3911 100755 --- a/connectivity/cellular/include/cellular/framework/AT/AT_CellularDevice.h +++ b/connectivity/cellular/include/cellular/framework/AT/AT_CellularDevice.h @@ -80,6 +80,8 @@ class AT_CellularDevice : public CellularDevice { virtual nsapi_error_t soft_power_off(); + virtual nsapi_error_t soft_reset(); + virtual nsapi_error_t set_pin(const char *sim_pin); virtual nsapi_error_t get_sim_state(SimState &state); diff --git a/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp b/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp index 3eccc4a5c0e..d7dae05aa23 100644 --- a/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp +++ b/connectivity/cellular/source/framework/AT/AT_CellularDevice.cpp @@ -187,6 +187,11 @@ nsapi_error_t AT_CellularDevice::soft_power_off() return NSAPI_ERROR_OK; } +nsapi_error_t AT_CellularDevice::soft_reset() +{ + return NSAPI_ERROR_OK; +} + ATHandler *AT_CellularDevice::get_at_handler() { return &_at; diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp index c00c1880e4f..40e74ab98fb 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp @@ -98,6 +98,16 @@ nsapi_error_t GEMALTO_CINTERION::shutdown() return NSAPI_ERROR_OK; } +nsapi_error_t GEMALTO_CINTERION::soft_power_off() +{ + return _at.at_cmd_discard("^SMSO=", "fast"); +} + +nsapi_error_t GEMALTO_CINTERION::soft_reset() +{ + return _at.at_cmd_discard("+CFUN", "=1,1"); +} + GEMALTO_CINTERION::Module GEMALTO_CINTERION::get_module() { return _module; diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h index e77078cb49d..edc980209e2 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h @@ -56,6 +56,8 @@ class GEMALTO_CINTERION : public AT_CellularDevice { protected: virtual nsapi_error_t init(); virtual nsapi_error_t shutdown(); + virtual nsapi_error_t soft_power_off(); + virtual nsapi_error_t soft_reset(); private: static Module _module; From 68cb8fbfae3ddd4eb400c87f5923a7be6344902f Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 14 Nov 2024 15:57:44 +0100 Subject: [PATCH 32/37] GEMALTO CINTERION: disable runtime model detection cellular_properties must be configured in ctor to properly configure all network urcs --- .../GEMALTO/CINTERION/GEMALTO_CINTERION.cpp | 39 ++++++------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp index 40e74ab98fb..3754ad50ec9 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.cpp @@ -29,6 +29,17 @@ GEMALTO_CINTERION::Module GEMALTO_CINTERION::_module; GEMALTO_CINTERION::GEMALTO_CINTERION(FileHandle *fh) : AT_CellularDevice(fh) { +#if defined(MBED_CONF_GEMALTO_CINTERION_ELS61) + init_module_els61(); +#elif defined(MBED_CONF_GEMALTO_CINTERION_BGS2) + init_module_bgs2(); +#elif defined(MBED_CONF_GEMALTO_CINTERION_EMS31) + init_module_ems31(); +#elif defined(MBED_CONF_GEMALTO_CINTERION_EHS5E) + init_module_ehs5e(); +#else + init_module_tx62(); +#endif } AT_CellularContext *GEMALTO_CINTERION::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req) @@ -60,35 +71,7 @@ nsapi_error_t GEMALTO_CINTERION::init() if (err != NSAPI_ERROR_OK) { return err; } - - CellularInformation *information = open_information(); - if (!information) { - return NSAPI_ERROR_NO_MEMORY; - } - char model[sizeof("EHS5-E") + 1]; // sizeof need to be long enough to hold just the model text - nsapi_error_t ret = information->get_model(model, sizeof(model)); - close_information(); - if (ret != NSAPI_ERROR_OK) { - tr_error("Cellular model not found!"); - return NSAPI_ERROR_DEVICE_ERROR; - } - if (memcmp(model, "ELS61", sizeof("ELS61") - 1) == 0) { - init_module_els61(); - } else if (memcmp(model, "BGS2", sizeof("BGS2") - 1) == 0) { - init_module_bgs2(); - } else if (memcmp(model, "EMS31", sizeof("EMS31") - 1) == 0) { - init_module_ems31(); - } else if (memcmp(model, "EHS5-E", sizeof("EHS5-E") - 1) == 0) { - init_module_ehs5e(); - } else if (memcmp(model, "TX62", sizeof("TX62") - 1) == 0) { - init_module_tx62(); - } else { - tr_error("Cinterion model unsupported %s", model); - return NSAPI_ERROR_UNSUPPORTED; - } - tr_info("Cinterion model %s (%d)", model, _module); set_at_urcs(); - return NSAPI_ERROR_OK; } From faef4149c90d9e16c7fd5a626efc5894bf2e5098 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 14 Nov 2024 15:59:37 +0100 Subject: [PATCH 33/37] GEMALTO CONTERION: add ping --- .../GEMALTO_CINTERION_CellularStack.cpp | 17 +++++++++++++++++ .../CINTERION/GEMALTO_CINTERION_CellularStack.h | 1 + 2 files changed, 18 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index f96ae481f0d..938cdbfef28 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -224,6 +224,23 @@ void GEMALTO_CINTERION_CellularStack::PSMDisable() { } } +int GEMALTO_CINTERION_CellularStack::ping(const char *host, int ttl) +{ + MBED_ASSERT(host); + + _at.lock(); + _at.set_at_timeout(ttl + 1000); + _at.cmd_start_stop("^SISX", "=", "%s%d%s%d%d", "Ping", _cid, host, 1, ttl); + _at.resp_start("^SISX: \"Ping\","); + _at.skip_param(3); //pingInfoType, conProfileId, ip-address + int rTT = _at.read_int(); //roundTripTime + _at.resp_stop(); + _at.clear_error(); + _at.restore_at_timeout(); + _at.unlock(); + return rTT; +} + nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_stack_init() { _at.lock(); diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h index f89da8c3140..159ea68aa9e 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h @@ -43,6 +43,7 @@ class GEMALTO_CINTERION_CellularStack : public AT_CellularStack { void stopGNSS(); void PSMEnable(); void PSMDisable(); + int ping(const char *host, int ttl); protected: From 6ce8016a535714f0ddd48333dfe047e216a8542d Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 14 Nov 2024 16:00:17 +0100 Subject: [PATCH 34/37] GEMALTO CINTERION: fix gethostbyname() Add missing _at.unlock() --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index 938cdbfef28..8f7b44818a2 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -309,6 +309,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::gethostbyname(const char *host, S } else { //Null string received tr_info("Read %d bytes. Null string", size); + _at.unlock(); return NSAPI_ERROR_NO_ADDRESS; } } From 63775e3ce04c9aac0eed316168f770d4e295e256 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 14 Nov 2024 16:03:10 +0100 Subject: [PATCH 35/37] CellularStateMachine: wait and retry if signal quality is unknown --- .../cellular/source/framework/device/CellularStateMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connectivity/cellular/source/framework/device/CellularStateMachine.cpp b/connectivity/cellular/source/framework/device/CellularStateMachine.cpp index 37416ca72ea..a87c9e0d02a 100644 --- a/connectivity/cellular/source/framework/device/CellularStateMachine.cpp +++ b/connectivity/cellular/source/framework/device/CellularStateMachine.cpp @@ -458,7 +458,7 @@ void CellularStateMachine::state_signal_quality() { _cb_data.error = _network.get_signal_quality(_signal_quality.rssi, &_signal_quality.ber); - if (_cb_data.error != NSAPI_ERROR_OK) { + if ((_cb_data.error != NSAPI_ERROR_OK) || (_signal_quality.rssi == CellularNetwork::SignalQuality::SignalQualityUnknown)) { retry_state_or_fail(); } else { _cb_data.data = &_signal_quality; From 4033c21979e39741dd4c97c0c7f8a76f6eed1433 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 15 Nov 2024 11:37:52 +0100 Subject: [PATCH 36/37] GEMALTO CINTERION fix RECV urc while reading cornercase --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index 8f7b44818a2..d164f85eb27 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -598,6 +598,8 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(Cell if (len == 0) { tr_debug("Socket %d no data", socket->id); _at.resp_stop(); + _at.process_oob(); + socket->pending_bytes = 0; RESTORE_URCs_AND_RETURN(NSAPI_ERROR_WOULD_BLOCK); } if (len == -1) { From ec7cc4e660b366364d8b11e4ee6480c41141ff04 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 26 Mar 2025 15:08:40 +0100 Subject: [PATCH 37/37] GEMALTO CINTERION: add 1ms sleep in socket sendto --- .../GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp index d164f85eb27..898f81cf66e 100644 --- a/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp +++ b/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.cpp @@ -19,6 +19,7 @@ #include "GEMALTO_CINTERION_CellularStack.h" #include "GEMALTO_CINTERION.h" #include "CellularLog.h" +#include "platform/mbed_thread.h" #include "rtos.h" using namespace std::chrono_literals; @@ -538,6 +539,8 @@ nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(Cellul socket->tx_ready = false; } + thread_sleep_for(1); // wait for modem to process the data; + return (_at.get_last_error() == NSAPI_ERROR_OK) ? accept_len : NSAPI_ERROR_DEVICE_ERROR; }