A MIMXRT1176 flight controller built to the Pixhawk FMUv6X-RT standard, so
the port also covers the NXP MR-VMU-RT1176.
Board data comes from PX4, which already carries it as a NuttX board config:
the clock tree, the LPUART1 pinmux, and the Macronix octal flash
configuration block the boot ROM reads at offset 0x400.
The board ships with the PX4 bootloader in the first 128 KB of QSPI, so the
image links at 0x30020000 and is loaded by it rather than written to the
flash base. The console is CDC/ACM as on teensy-4.x, so a USB cable is the
only thing needed to run NuttX here.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
There is a issue that exist on esptool and was fixed on version
5.3.0: https://github.com/espressif/esptool/releases/tag/v5.3.0
elf2image: Correct pad length for ram-only-header flash segments (Sylvio Alves - c637749)
Signed-off-by: Alan C. Assis <acassis@gmail.com>
hci_event() consumed the event header and dispatched on the event code
without checking that a header had been received, and hci_le_meta_event()
did the same for the subevent code. Each handler then cast the remaining
buffer to its event structure and read fields out of it, so a short event
was parsed from whatever followed it in memory - including the fields
that identify a connection and carry its encryption state.
Check that the header is present before reading it, that the parameters
the event declares were actually received, and that enough parameters
remain for the structure the selected handler casts to. Events failing a
check are dropped with a diagnostic rather than parsed.
le_adv_report() continues to do its own checking, because the report
count and the per-report lengths vary within that event.
Ref: Core v6.0, Vol 4, Part E, 5.4.4 (HCI Event packets)
Ref: Core v6.0, Vol 4, Part E, 7.7 (Events)
Testing: builds for sim:bluetooth with Make; every commit in this series
verified to build individually. Not yet exercised at runtime - the
scriptable controller injects truncated events separately.
Signed-off-by: Alan C. Assis <acassis@gmail.com>
Assisted-by: Claude Code Opus 5
Arming a pin as a light-sleep wake source destroyed whatever it was
configured as, permanently.
esp_pm_gpio_wakeup_prepare() has to reconfigure each masked pin to plain
INPUT and hand it to gpio_wakeup_enable(), because the wakeup path only
supports level triggering. It then never put anything back. A pin that
was also a normal peripheral interrupt -- a sensor's data-ready line, say
-- came out of the first light sleep with its trigger mode gone and never
interrupted again. Nothing failed loudly; the device just went silent.
Fixed generically rather than per-board:
- esp_configgpio() now remembers the last attr applied to each pin, and
a new esp_getconfiggpio() hands it back. This is what lets the PM
code restore a pin without having to know what the pin is for.
- esp_pm_gpio_wakeup_prepare() saves each masked pin's attr before
overwriting it, and a new esp_pm_gpio_wakeup_restore() puts it back
as soon as esp_pm_light_sleep_start() returns.
Tied to the physical sleep/wake cycle deliberately, not to PM state
transitions. An earlier attempt used a board-level pm_register()/notify()
callback and never fired at all, because the board sits in PM_STANDBY
without transitioning back to PM_NORMAL -- there is no state change to
hang the restore on. The return from esp_pm_light_sleep_start() is the
one event that always happens exactly once per sleep.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
#20231 added a comment ahead of the sensor's power-on SW_RESET that
named esp32s3-specific things in otherwise generic driver code:
esptool/RTS-pin reset vocabulary, a literal path to
boards/xtensa/esp32s3/common/src/esp32s3_board_lsm6ds3trc.c, and the
espressif-arch esp_gpioirqenable() function.
None of that is specific to this driver's actual logic, which is
reached by any board wiring this sensor's INT1 through its own
config->attach() callback, whatever the arch. Reworded to describe
the reset/level-trigger requirement in those generic terms instead,
and dropped an ESP32S3-collar bring-up anecdote that does not belong
in driver documentation.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-sonnet-5
The driver has the same code as the one of the STM32H7. When the PHY did
not clear the reset bit in time, stm32_phyinit() returned the result of
the last MDIO read. The bus reads all ones when the PHY does not answer
yet, and that read succeeds, so the function returned OK and the driver
went on with its default of 10 Mbps and half duplex, while the PHY could
negotiate 100 Mbps and full duplex.
Return -ETIMEDOUT, so that bringing the interface up fails and the
failure is not hidden.
It builds for nucleo-h563zi:netnsh, but it was not tested on hardware.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
A frame that a packet socket consumes was given to pkt_input() and then
logged as "Dropped, Unknown type" because it is neither IP nor ARP. With
a PTP grandmaster on the network that is one warning for each frame, and
the log of RAM fills in seconds, so it hides the messages of the start of
the system.
Do not log the frames of the type of PTP or of IPv6 when packet sockets
are enabled, as the driver of the legacy STM32 does.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
When the PHY did not clear the reset bit in time, stm32_phyinit()
returned the result of the last MDIO read. The bus reads all ones when
the PHY does not answer yet, and that read succeeds, so the function
returned OK and the driver went on with its default of 10 Mbps and half
duplex, while the PHY negotiated 100 Mbps and full duplex. The interface
was up and could not talk to anyone.
Return -ETIMEDOUT, so that bringing the interface up fails and the
failure is not hidden.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
POSIX requires getdelim()/getline() to allocate a new buffer whenever
*lineptr is NULL, regardless of the value of *n. The previous code read
the buffer size from *n unconditionally and only fell back to the initial
size when *n was zero, so a caller that passes *lineptr == NULL together
with an uninitialized (non-zero) *n caused lib_malloc() to be invoked with
that garbage size and typically fail with ENOMEM.
Treat a NULL *lineptr the same as a zero *n: (re)allocate from the known
BUFSIZE_INIT and ignore the untrusted *n. This matches the glibc
behaviour that portable code relies on (for example toybox grep, which
calls getdelim() with an uninitialized size variable).
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Add esp_get_irq() to retrieve the IRQ associated with an interrupt
handle.
This allows the ESP OS abstraction to recover the IRQ when freeing an
interrupt from its handle.
The corresponding change in esp-hal-3rdparty is required to use this
API when freeing interrupts.
Related: #20216
Signed-off-by: Ahmed Ashraf NourEldeen <a.programmer55559@gmail.com>
Add esp_get_irq() to retrieve the IRQ associated with an interrupt
handle.
This allows the ESP OS abstraction to recover the IRQ when freeing an
interrupt from its handle.
The corresponding change in esp-hal-3rdparty is required to use this
API when freeing interrupts.
Related: #20216
Signed-off-by: Ahmed Ashraf NourEldeen <a.programmer55559@gmail.com>
MCAN controller keeps track of empty TX HW FIFO slots in priv->txfsem
semaphore. The semaphore is incremented from TX complete interrupt
and taken before new frame is inserted to the HW FIFO.
There may be a situation when TX HW FIFO is not full but the
semaphore is not yet incremented because the driver didn't handle the
interrupt. I managed to reproduce this issue when sending large
data chunks over CAN bus and keeping the buffers full for most of
the transmission process. This situation leads to the debug assertion
although technically it's not a big issue -> the sending function
waits on the semaphore until it's posted by the interrupt handler.
Moreover, the sanity checks should not be necessary because
mcan_buffer_reserve function will take care of fixing the semaphore
value if it doesn't match with the FIFO.
The entire semaphore logic is a bit weird and probably not
necessary. All we need to do is to check SAM_MCAN_TXFQS register
if there is at least one free slot in the queue. But this would
require a bigger SAMv7 MCAN rewrite, this is rather a hot fix.
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
Harmonize including the variant specific gpio header in imxrt_gpio.h, correct
a mistake in include paths.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
The flexspi_nor_config_s was missing four fields, resulting the fields after the
missing ones being read from wrong positions.
Align the struct properly according to the reference manual.
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
On imxrt1180 there are 240 IRQs. Add the missiong ones:
IRQ 238 ECAT EtherCAT Reset out (ECAT_RESET_OUT pin-mux signal)
IRQ 239 EdgeLock EdgeLock interrupt
Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
bt_conn_receive() read the 4-octet L2CAP header out of the first fragment
of a PDU without checking that 4 octets had been received, and then
computed the outstanding length by subtracting the fragment length from
the declared PDU length.
Two problems follow. A fragment shorter than the header was parsed from
whatever happened to follow it in the buffer. And a fragment carrying
more data than the PDU it declares made the subtraction wrap, because
conn->rx_len is 16 bits: the connection was then left expecting up to
65535 further octets, holding the partial PDU and accumulating later
fragments against an expectation that could never be satisfied.
Check that the fragment is long enough to hold a header before reading
it, and that it does not exceed the PDU it declares before computing what
remains. Drop the fragment and reset the reassembly state otherwise.
Ref: Core v6.0, Vol 3, Part A, 3.1 (B-frame format)
Ref: Core v6.0, Vol 4, Part E, 5.4.2 (HCI ACL Data packets)
Testing: builds for sim:bluetooth with Make; every commit in this series
verified to build individually. Not yet exercised at runtime - the
scriptable controller adds the truncated and oversized fragment cases
separately.
Signed-off-by: Alan C. Assis <acassis@gmail.com>
Assisted-by: Claude Code Opus 5
The part has a hardware random number generator and nothing registers
it, so up_randompool_initialize() is never seeded from hardware. There
is no CAAM, TRNG or RNG driver anywhere in arch/arm/src/imxrt, and the
RT117x headers describe the block only as an address-map comment.
imxrt_caam.c brings up job ring zero and instantiates the RNG state
handle when the boot ROM has not, retrying with a longer entropy sample
until the self test passes. imxrt_rng.c registers /dev/random and
/dev/urandom on top, and is the i.MX9 driver's sibling: same health
checks, same FIPS 140-2 continuous test, same refusal to return a short
read and call it entropy.
The instantiation descriptor posts no job ring completion, so the state
handle is what reports it, and the ring is taken back to a known state
to latch it. Job ring zero is started and the cache and watchdog bits
set first: RDSTA and JRSTART both read zero out of reset on this part.
Scoped to RT117x, which is the family that carries CAAM.
Built for imxrt1170-evk:nsh with the driver on, and for imxrt1060-evk:nsh
to confirm the shared clock-gate header still builds without it.
Run on an FMU-v6X-RT (i.MX RT1176): /dev/random and /dev/urandom both
return, the first read after a cold boot included, and five consecutive
reads are distinct.
Signed-off-by: Royyan Zahir <royzah@gmail.com>
Correct switch and declaration indentation, separate declarations from code,
and wrap a long comment in the SPI driver. Fix the timer driver and both
STM32L5 board LED implementations checked by the commonization PR.
These are formatting changes only.
Signed-off-by: raiden00pl <raiden00@railab.me>
Select STM32_HAVE_IP_USART_M33_V3 and drop the family serial and
low-level console sources in favor of the common Cortex-M33 v3
implementation. Provide the USART clock and RCC gate definitions in
stm32_rcc_m33.h.
Add the LPUART BRR computation (256 * fCK / baud) to the common serial
and low-level console code, taken from the STM32L5 driver.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
Enable STM32_COMMON_M33 for STM32L5 and drop the family reset, NVIC,
SysTick, idle, and heap sources in favor of the common Cortex-M33 v1
implementation.
Rename the family RCC header to stm32_rcc_m33.h for the common RCC
dispatch and define STM32_PRIMARY_SRAM_SIZE for the common heap
allocator.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
Select STM32_HAVE_IP_GPIO_M33_V1 and STM32_HAVE_IP_EXTI_M33_V1 and
drop the family GPIO and EXTI sources and headers in favor of the
common Cortex-M33 v1 implementation.
Define both EXTI register banks and retain the named bit definitions.
Use shared line and selector helpers without per-line conditionals.
Clear each GPIO selector with the same byte mask, as the H5 driver does.
Cover both 32-bit banks and H5 line inventories for later migration.
The common EXTI driver also routes the selected port through EXTICR,
which the family driver never programmed, so GPIO interrupts now work
on ports other than GPIOA.
Signed-off-by: raiden00pl <raiden00@railab.me>
Assisted-by: Claude Code
The FIFO watermark flag is a level: it stays high until the worker
actually drains the FIFO below the threshold. Configuring INT1 as RISING
made that a race the driver could lose permanently.
lsm6ds3trc_interrupt() disables its IRQ on entry and re-enables it after
the worker has run. With an edge trigger, if the line is still high when
the IRQ is re-enabled -- which is precisely what happens whenever a drain
does not take the FIFO below the watermark -- there is no new low-to-high
transition left to detect, and the line goes mute forever. Observed as a
board that serviced exactly one watermark after boot and then never
again, reproducible 2 out of 2 reflashes.
ONHIGH matches the physical meaning of the pin and is immune to it: a
level trigger re-asserts on its own for as long as the condition holds,
and the disable/enable pairing around servicing is what stops that from
live-locking.
Validated with more than 900 consecutive drains (~100 min) including real
sleep -> GPIO-wake -> resume transitions, the exact case that used to
wedge.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-opus-5
- Switch board image directive from .. image:: to .. figure:: with
:scale: 50 % and a caption line, matching the format used by other
Ameba board docs (rtl8721dx, rtl8721f).
- Move rtl8730e_evb.png from img/ subdirectory to the same level as
index.rst, consistent with other boards.
- Add gpio configuration section describing the three registered pins
(PB19 output /dev/gpio0, PB20 input /dev/gpio1, PB11 interrupt
/dev/gpio2), usage examples and pin encoding notes.
- Add GPIO to the "Supported in this NuttX port" feature list.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
Wire the shared ameba_gpio driver to the RTL8730E CA32 core.
The CA32 replaces the vendor CA32 OS as BL33; the SDK startup that
normally initialises GPIO_PORTx[] never runs under NuttX. The three
GPIO port base addresses are patched at runtime inside
rtl8730e_gpio_initialize() before any ROM GPIO function is called.
GPIO_INTStatusGet and GPIO_INTStatusClearEdge are absent from the
RTL8730E ROM and are provided as static inline helpers in the new
ameba_gpio_chip.h.
Key changes:
- ameba_gpio_chip.h (new): chip parameters, split AMEBA_APBPERIPH_GPIO
/ AMEBA_APBPERIPH_GPIO_CLK bits, inline INTStatus helpers
- ameba_gpio.c: add AMEBA_APBPERIPH_GPIO_CLK fallback macro so chips
with separate periph/clock enable bits work without driver changes
- Make.defs: enable ameba_gpio.c + rtl8730e_flash_stubs.c + lib_rom.a
under CONFIG_AMEBA_GPIO; consolidate flash_stubs into GPIO||FLASH_FS
- ameba_board.mk: remove duplicate lib_rom.a (Make.defs is authoritative)
- rtl8730e_flash_stubs.c: make _strcmp weak; delegate Pinmux_Config to
lib_rom.a's _Pinmux_Config so GPIO pad mux is configured correctly
- Kconfig: source common/ameba/Kconfig to expose CONFIG_AMEBA_GPIO
- dramboot.ld: include .sramdram.only.data in .data so GPIO_PORTx[] is
copied to RAM by the normal arm_data_initialize() path
- scripts/Make.defs: extend --no-warn-mismatch to GPIO and WiFi configs
- rtl8730e_gpio.c (new): pin table (PB19 output /dev/gpio0, PB20 input
/dev/gpio1, PB11 falling-edge interrupt /dev/gpio2) + GPIO_PORTx patch
- configs/gpio/ (new): defconfig for GPIO example verification
- nxstyle.c: add _Pinmux_ to mixed-case whitelist (ROM symbol)
Hardware verified on RTL8730E CA32:
- PB19 output write 0/1, readback matches
- PB20 input reads PB19-driven level
- PB11 falling-edge interrupt triggers correctly
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The interval and the width of the pulse train of the PPS output were
programmed as the number of increments of the system time minus one,
but the MAC takes them as they are. Each period was one increment (10 ns
with HCLK at 200 MHz) shorter than a second, so the pulses came 10 ns
early each second, about 36 us in an hour, and the output drifted away
from the system time.
Program the interval and the width without subtracting one.
On a run of 8.2 hours against a grandmaster clock the pulse moved 0.29 ms
ahead of the system time, which is 10 ns per second, while the system time
stayed within 1 us of the grandmaster. With the change, a run of 11 hours
showed no drift of the pulse against the system time, within 3 us per hour
on samples of 1 ms of resolution.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
esp_pmstandby() fed up_step_idletime() the sleep duration it *asked* for
(time_in_us) rather than the one it actually got (rtc_diff_us), and did so
unconditionally. Both halves are wrong.
esp_pm_light_sleep_start() already stalls and restores the systimer
itself, but only where SOC_SLEEP_SYSTIMER_STALL_WORKAROUND is defined --
esp32c3 and esp32p4. On every other SoC, esp32s3 included, the systimer
keeps counting straight through light sleep, so the time is already in
the clock and stepping it again adds it twice.
Measured on an esp32s3-xiao: over 54 min with 1919 light sleeps totalling
454.7 s, the monotonic clock ran 443.2 s fast -- 0.97 of the time slept,
i.e. counted exactly twice, leaving the clock 13.8% fast. Anything that
reconstructs wall time from CLOCK_MONOTONIC inherits that error; for this
collar it corrupted every IMU sample timestamp.
Invisible until light sleep started happening for real, because a board
that never sleeps never steps the clock.
Note for upstream: the risc-v copy here only switches to the measured
duration and does not gate on SOC_SLEEP_SYSTIMER_STALL_WORKAROUND. The
two should be reconciled before this is proposed -- it is kept as-is so
the asymmetry is visible rather than silently decided.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-opus-5
A single failed burst read of FIFO_DATA_OUT was enough to take the board
down.
The drain path gave up on error, unlocked and returned, leaving the FIFO
above its watermark. INT1 is level triggered on exactly that condition,
so the line stayed asserted, the worker was re-entered the instant the
IRQ was re-enabled, failed again, and that hot loop starved every other
task until the board wedged -- console cut off mid-line, no crash dump.
Observed killing a board within seconds of the first failure.
Fix: if the read fails, empty the FIFO through Bypass and restore the
previous mode bits, which deasserts INT1. That costs one batch of
samples and acquisition resumes on the next watermark. Restoring the
saved bits rather than recomputing them preserves the FIFO-only ODR set
by fifo_configure().
Losing a batch is a far better outcome than losing the board.
The underlying cause of these timeouts on esp32s3 was light sleep cutting
the transfer in half; that is fixed separately in esp32s3_i2c.c. This
commit is the driver recovering gracefully from a failed read whatever
its cause, which it was not before.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
The worker declared its drain buffer as int16_t raw[FIFO_MAX_WORDS], and
FIFO_MAX_WORDS scales with CONFIG_SENSORS_LSM6DS3TRC_FIFO_WATERMARK.
At the Kconfig default watermark of 8 that is 192 bytes and nobody ever
noticed. At the watermark this collar uses, 250, it is 6000 bytes inside
an 8192-byte HPWORK stack -- 73% of it, before the call frame and the
whole I2C stack underneath. Any board raising the watermark walks into a
stack overflow in a shared work queue, which is about the worst place to
find one.
Allocated once at registration so the drain path stays allocation-free,
and the driver fails registration cleanly if it cannot get the memory.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
lsm6ds3trc_register() attached the INT1 handler without ever putting the
sensor into a known state, which made every reboot a coin toss.
The LSM6DS3TR-C has its own supply and its own reset. An MCU reset --
watchdog, RTS pin, esptool, a plain "reboot" -- does not reset it, so it
comes back still holding whatever the previous session configured: for
this driver, INT1_CTRL.INT1_FTH still set and a FIFO still over its
watermark, i.e. INT1 already asserted at registration time.
With the (correct) ONHIGH level trigger, arming an already-active line
storms immediately. The board then wedges during bring-up with no
console output and no crash dump -- it looked like a boot that stopped
right after Wi-Fi init and never reached NSH. That symptom cost a long
detour: it was blamed in turn on a stuck I2C bus, on corrupted NVS/Wi-Fi
calibration, and finally on a failing USB-serial adapter, because the one
thing that reliably cleared it was unplugging the board -- which is
simply the only way to power-cycle the *sensor*.
SW_RESET (CTRL3_C bit 0) clears INT1_CTRL and FIFO_CTRL back to 0, which
deasserts INT1. It self-clears in ~50 us; poll for it rather than
assume, and retry the write a few times, since the bus has been seen to
return -EIO on the very first transaction after a cold boot.
Carry on if the reset never takes. An unreset sensor risks the storm
this exists to prevent, but refusing to register leaves the application
with no /dev/uorb/sensor_accel0 at all, which is fatal to it -- a single
-EIO here took the whole collar down once. Losing the sensor to guard
against a maybe-storm is the wrong trade.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
esp_gpio_irq() registers per-pin GPIO interrupts through
gpio_isr_handler_add(), never through esp_setup_irq(), so
esp_get_handle() never finds them and up_disable_irq()/up_enable_irq()
silently no-op for any GPIO-derived irq number. Fall back to
esp_gpioirqdisable()/esp_gpioirqenable() (translating irq back to a
pin via ESP_IRQ2PIN()) when the normal interrupt-matrix lookup misses.
This surfaced through drivers/sensors/lsm6ds3trc_uorb.c: its ISR
schedules a worker to drain the sensor's FIFO over I2C and disables
its own IRQ until the worker re-enables it, so a level-triggered
source (e.g. a PM GPIO wake source left in level mode) doesn't
refire continuously and starve every task, HPWORK included, before
the worker ever gets to run. That disable/enable only works now that
up_disable_irq()/up_enable_irq() actually do something for GPIO irqs.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-sonnet-5
Add 8 missing AF4 I2C2/I2C4 pin remap defines to
stm32h56xxx_pinmap.h, per ST's datasheet. Needed by boards that wire
I2C2/I2C4 to these pins; without them such configs fail to compile.
Reduced from a larger internal patch; the stm32_i2c.c part of that
patch is already upstream, so only this pinmap gap remained.
Co-authored-by: David Vidrie Leon <davidvidrie@geotab.com>
Signed-off-by: Marwan Madkour <marwanmadkour@geotab.com>
Light sleep gates the APB clock the I2C peripheral runs on. A transfer
in flight stops mid-message and never raises its completion interrupt, so
the caller blocks in i2c_sem_waitdone() until ESP32S3_I2CTIMEOTICKS
expires and gets -ETIMEDOUT for a bus that was working perfectly.
The caller is what causes it. Blocking in i2c_sem_waitdone() is exactly
what makes the idle task runnable, and the idle task is what decides to
sleep -- so the longer the transfer, the likelier it is to be cut in half
by its own wait. Nothing about this is driver-specific.
Seen on an esp32s3-xiao reading an LSM6DS3TR-C FIFO: 6000 bytes in one
transaction, some 135 ms of bus time at 400 kHz, failing with -110 over
and over. A WHO_AM_I probe and the FIFO status read, both short, never
failed once in the same runs -- only the long burst did.
The consequences went well past one failed read. With the FIFO left
undrained the sensor's level-triggered INT1 stayed asserted, the worker
was re-entered the moment the IRQ was re-enabled, and that hot loop
starved every other task until the board wedged with no console output
and no crash dump.
pm_stay(PM_IDLE_DOMAIN, PM_IDLE) is the lightest lock that suffices:
greedy_governor_checkstate() walks up from PM_NORMAL and stops at the
first state holding a wakelock, so a stay at PM_IDLE keeps the domain out
of PM_STANDBY and PM_SLEEP while still allowing the plain WFI idle.
There is no early return between the stay and the relax.
Validated over 3 h 45 of continuous acquisition across two sessions:
wakes and drains stayed 1:1 (302/302, then 375/375), zero I2C failures of
any kind, and light sleep itself unaffected -- 11.8% of wall time asleep
in both, median sleep 2.08 s.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-opus-5
libelf_uninit() only called libelf_freesymtab() when the module had an
uninitializer. But the exported symbol table is built by
libelf_insertsymtab() for every loaded module, and nothing in the tree
sets modinfo.uninitializer anymore: modules have registered their
teardown through .fini_array since a9cb28cd23. The condition is
therefore always false and every rmmod()/dlclose() leaks the exports
array together with the strdup-ed symbol names.
Call libelf_freesymtab() unconditionally, and clear the exports
pointers next to it instead of under a vestigial procfs guard that
dates back to the removed module initializer field.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
libelf_remove() takes the module out of the registry but never frees
the registry entry, so every successful rmmod()/dlclose() leaks
sizeof(struct module_s), the name included. The lib_free() call was
dropped by e9550783d3 when the removal path was reworked.
Free the entry after the registry lock is released.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
/proc/pm/state0 reported a flat 0 s in its SLEEP column on a board that
was demonstrably light-sleeping, because this port never told the PM core
it had slept.
pm_stats() (drivers/power/pm/pm_changestate.c) splits the time since the
last transition into dom->wake[state] or dom->sleep[state] depending on
whether the state it is handed is PM_RESTORE. up_idlepm() called
esp_pmstandby() and carried straight on, so every second -- including the
ones spent in light sleep -- was billed to wake[]. The statistics
CONFIG_PM_PROCFS advertises were simply never true here.
Read from an esp32s3-xiao that had just spent 89 s in PM_STANDBY:
DOMAIN0 WAKE SLEEP TOTAL
standby 89s 83% 0s 0% 89s 83%
Only PM_STANDBY needs this. PM_SLEEP is deep sleep and does not return
at all -- the chip resets -- so there is nothing to attribute on its way
back.
pm_changestate(domain, PM_RESTORE) is the documented way to say this: it
skips the driver prepare/veto phase, records the statistic, notifies
drivers of the restore, and deliberately does not overwrite the domain's
state, so the domain stays in PM_STANDBY as it should.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-opus-5
up_idlepm() put the domain back in PM_NORMAL with pm_changestate() but
left its local oldstate holding whatever it was before sleeping, usually
PM_STANDBY. The pm_checkstate() below then returned PM_STANDBY again,
the "newstate != oldstate" test compared PM_STANDBY against a stale
PM_STANDBY, and the whole block was skipped -- including the
esp_pmstandby() call that is the only thing in here that ever sleeps.
So after the very first wakeup the board reported PM_NORMAL essentially
forever, and light-slept only when something else happened to perturb
oldstate, such as an application taking and releasing a PM_IDLE wakelock
around a transmission window.
Measured on the esp32s3-xiao collar before this fix: 4.1 s of actual
light sleep in 2 h of near-total idleness, a 1780:1 awake-to-asleep
ratio. After it: ~13.5% of wall time asleep, thousands of sleeps, no
storms.
The dead "newstate = PM_NORMAL" assignment that used to sit here was
presumably meant to be this; it is overwritten by pm_checkstate() a few
lines below and never had any effect.
Note that fixing this is what exposed two further bugs that had been
dormant behind a board that never slept: the systimer double-count in
esp_pmstandby(), and I2C transfers being cut in half by sleep. Both are
fixed in their own commits.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Assisted-by: Claude:claude-opus-5
Increase MOD_LINELEN from 64 to 256 so complete /proc/modules lines fit the formatting buffer on 64-bit targets.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Add the required blank line between the intcount declaration and the
following statement.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
irq_callback() passed snprintf()'s would-have-written length to
procfs_memcpy(). If an IRQ line exceeded IRQ_LINELEN, the copy could read
beyond the formatting buffer.
Use procfs_snprintf() so the copy is limited to the bytes actually written.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
modprocfs_callback() formatted each line into line[64] with snprintf()
and passed snprintf()'s return value, the length the line would have
had, to procfs_memcpy() as the source length. A module name longer
than a few characters therefore made the copy read past the end of
the line buffer and hand kernel heap memory to the reader, and grew
totalsize by the difference.
Use procfs_snprintf(), which returns the length actually written, as
the other procfs entries already do.
Assisted-by: OpenAI Codex
Signed-off-by: yushuailong <yyyusl@qq.com>
Follow-up to apache/nuttx#20194. The KissFFT page only described how
NuttX vendors the package. State that it is a small open-source FFT
implementation used in many embedded projects.
Signed-off-by: Abhishek Mishra <mishra.abhishek2808@gmail.com>
Support STM32_ETH_TIMESTAMP_TX on the STM32H7, as the legacy STM32 do,
with the timestamp returned through SO_TIMESTAMPING.
When a packet socket asks for the transmit timestamp of a frame, keep a
copy of the frame and ask the MAC to timestamp it in the descriptor. When
the transmission is done, take the timestamp from the descriptor and give
the copy back to the network stack with it, that delivers it to the error
queue of the socket. The MAC writes the timestamp over the address of the
buffer in the descriptor, so the driver keeps the buffer of these
descriptors. The copies that still wait for their timestamp are released
when the interface goes down.
With a PTP daemon using the peer-to-peer delay mechanism against a
grandmaster clock, the path delay measured was between 9.0 and 9.1 us.
Signed-off-by: Daniel P. Carvalho <danieloak@gmail.com>
Assisted-by: Claude:claude-sonnet-5
Record the vhost-net link in the board's Peripheral Support list and
describe the netnsh configuration alongside nsh, including how to bring
the interface up on both sides.
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
nsh plus networking over the rptun/virtio-net link to the A53: enables
DRIVERS_VHOST_NET with the buffer sizing the link needs (IOB pool and chains,
NET_LL_GUARDSIZE covering the ethernet and virtio-net headers) and ICMP
sockets for ping. Also gives CI an in-tree configuration that compiles the
vhost-net driver.
Verified on t3-gem-o1: ifup, then ping from the peer with 0% loss.
Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
Implements the device end of virtio-net, so a peer running the stock
virtio-net driver sees this side as a network card, and registers a netdev
lowerhalf.
Ring layout follows the peer's numbering: vq[0] is its RX queue, which we fill
to transmit, and vq[1] its TX queue, which we harvest. No features are
negotiated, so every frame carries the zeroed legacy virtio_net_hdr.
Peer buffers are reached by raw 64-bit address through an arch-provided
translation window -- the AM67 RAT, identity mapping elsewhere -- splitting
copies that straddle it.
Also gives DRIVERS_VHOST a prompt; it was promptless and so unselectable
without a driver forcing it.
Verified on t3-gem-o1 against an unmodified Linux virtio_net: eth0 registers,
ifup brings it to RUNNING, and the peer pings it 5/5 at 0.27 ms and 60/60 with
0% loss.
Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
vhost_get_vq_buffers() converts descriptor addresses through the shared-memory
I/O region, which truncates silently when the CPU cannot address all of the
peer's memory -- a 32-bit remote core against a 64-bit host, where
metal_phys_addr_t is 32-bit and Linux posts buffers above 4 GB.
Returns the raw 64-bit address and length instead, so class drivers can
translate through platform window hardware. Completion is unchanged.
Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Ulaş Sertan Kemeç <sertan.usk@gmail.com>
Adopt the zbus message bus on the linum-stm32h753bi (first adopter
board):
- scripts/flash.ld: include the iterable sections common fragments
(2 lines: common-rom.ld inside .text, common-ram.ld inside .data).
- configs/zbus/defconfig: board configuration enabling zbus with all
observer types, the zbus example and its cmocka test suite
(./tools/configure.sh linum-stm32h753bi:zbus).
- Board documentation: describe the new configuration.
Validated on hardware: the 16-test cmocka suite passes twice in the
same boot and the zbus example produces the expected output.
Assisted-by: Claude Code
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>