Wire the RTL8721F (amebagreen2) into the shared Ameba watchdog driver
(arch/arm/src/common/ameba/ameba_wdg.c), registered as /dev/watchdog0.
Only the per-chip base address and IRQ differ, so this adds a small
ameba_wdg_chip.h (WDG2 non-secure system watchdog at 0x4080AD80,
CPU0_NS_WDG IRQ 69, verified against the SoC hal_platform.h and
ameba_vector_table.h) plus the Make.defs/CMakeLists build hooks, the
board bring-up registration, and a wdg defconfig. The shared driver is
unchanged.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Wire the RTL8720F into the shared Ameba watchdog driver
(arch/arm/src/common/ameba/ameba_wdg.c), registered as /dev/watchdog0.
Only the per-chip base address and IRQ differ, so this adds a small
ameba_wdg_chip.h (WDG2 non-secure system watchdog at 0x40801D80,
KM4TZ_NS_WDG IRQ 52, verified against the SoC hal_platform.h and
ameba_vector_table.h) plus the Make.defs/CMakeLists build hooks, the
board bring-up registration, and a wdg defconfig. The shared driver is
unchanged.
Also corrects the RTL8720F row in the rtl8721dx chip-header reference
table (the non-secure system WDG IRQ is KM4TZ_NS_WDG = 52).
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a NuttX watchdog lower-half for the Ameba KM4 non-secure system
watchdog (WDG2), registered as /dev/watchdog0. The fwlib WDG API is
ROM-resident, so no board.mk change is needed.
The hardware cannot be stopped once enabled, so stop() is emulated via
the early interrupt (EI) auto-refreshing the counter, and capture()
delivers a pre-timeout callback through the same EI. The EI has a
three-part timing contract, all handled here: it must be armed with
EIMOD=ENABLE at WDG_Init, its EIE gate only takes effect after
WDG_Enable, and -- because the EI is level-based -- a pure capture path
must mask EIE after the one-shot callback to avoid re-entrant storming
while the reset is pending. The EI flag is cleared twice per the slow
WDG clock.
Per-chip base address and IRQ live in ameba_wdg_chip.h so the shared
driver needs no change to port to another Ameba IC.
Verified on pke8721daf: timeout reset (BOOT REASON WDG2), stop()
suppressing the reset, and capture() firing ~EICNT ms before the reset.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Add a user documentation page for the grep system command covering
overview, configuration options, usage, options, exit status and
examples. The command lives in apps/system/grep and is enabled with
CONFIG_SYSTEM_GREP (depends on CONFIG_LIBC_REGEX).
This documents the command added in
https://github.com/apache/nuttx-apps/pull/3741.
Signed-off-by: Junbo Zheng <zhengjunbo1@xiaomi.com>
Xtensa selected neither fork primitive, so vfork() was simply absent. This
wires it onto the two-primitive semantics.
There is no assembly entry point and none is needed. Every exception entry
already runs SPILL_ALL_WINDOWS, so the whole context of the calling thread is
in its exception frame and copying its stack copies a complete frame chain.
A flat build reaches that frame through SYS_save_context, issued inline so
that the recorded stack pointer belongs to a frame that stays alive for the
whole operation; a build with syscalls reaches it through xcp.sregs, recorded
by xtensa_swint() for the duration of the call.
The stack copy needs more than a relocated stack pointer here. A windowed
ABI stores each frame's caller stack pointer absolutely, in the base save
area below the frame, so a copy taken at a different address still names the
parent throughout and the child's first retw would underflow onto the
parent's stack. xtensa_fork_rebase() walks that chain and adds the
relocation offset to each link. The copy also starts one base save area
below the stack pointer rather than at it, because the frame the child
resumes into keeps its caller's spilled a0-a3 there.
Ported from the per-architecture work, reduced to the two primitives.
Co-authored-by: Xiang Xiao <xiaoxiang781216@gmail.com>
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Fix coding style violations detected by CI whole-file nxstyle scan:
- fs/smartfs/smartfs_utils.c: add missing braces after if (L334),
fix bad alignment (L414), fix switch brace alignment (L1531)
- fs/hostfs/hostfs.c: add blank line after declaration (L576)
These are pre-existing style issues in master, not introduced by
this PR, but reported because CI checks the entire touched file.
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Increase LINK_MAX from _POSIX_LINK_MAX (8) to 128 to allow
directories to have a reasonable number of subdirectories while
still enforcing a hard link limit.
Also fix pathconf(_PC_LINK_MAX) to return the actual LINK_MAX
value instead of the minimum _POSIX_LINK_MAX.
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
When inode_find() for path2 fails due to ENAMETOOLONG (or ELOOP),
the else branch incorrectly falls through to the EXDEV check based
on whether target is a mountpoint. This causes link() to report
EXDEV for overly long path2, violating POSIX which requires
ENAMETOOLONG in this case.
Fix by propagating the original inode_find() error code when it is
not ENOENT or ENOTDIR (i.e., not a simple "path does not exist"
condition).
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Root cause: _inode_search() built the absolute form of a relative
path with snprintf(buf, PATH_MAX, "%s/%s", cwd, path), silently
truncating it when cwd + "/" + path exceeded PATH_MAX. The truncated
buffer was then handed to _inode_canonicalize(), which collapsed
".." segments against the wrong cut-off suffix. A valid relative
path of PATH_MAX-1 bytes (legal per pathconf(_PC_PATH_MAX)) could
thus collapse onto a directory and open() returned EISDIR instead
of resolving the file.
Fix: size the temp buffer to hold the full uncanonicalized
"<cwd>/<path>" form so canonicalization sees the complete path.
lib_get_tempbuffer falls back to a malloc'd buffer when the size
exceeds PATH_MAX (CONFIG_LIBC_TEMPBUFFER_MALLOC). The existing
PATH_MAX check in _inode_canonicalize() still rejects any
canonicalized result that is too long, so ENAMETOOLONG semantics
are preserved.
Signed-off-by: dengwenqi <dengwenqi@xiaomi.com>
Since _inode_canonicalize() now resolves all "." and ".." segments
in the common VFS layer before inode search, the relpath passed to
each filesystem will never contain ".." segments. Remove the
now-dead ".." handling code from individual filesystem layers and
the inode search internals.
Files modified (redundant ".." path resolution removed):
- fs/hostfs/hostfs.c: remove depth-tracking escape check in
hostfs_mkpath(), simplify to direct path concatenation.
- fs/rpmsgfs/rpmsgfs.c: same as hostfs, remove depth-tracking in
rpmsgfs_mkpath().
- fs/smartfs/smartfs_utils.c: remove "." and ".." segment checks
in smartfs_finddirentry(), de-indent the remaining search logic.
- fs/inode/fs_inodesearch.c: remove _inode_isdotdot() function,
simplify _compute_path_depth() to only count forward segments,
remove dead else-if branch in _inode_search().
Files NOT modified (and why):
- fs/littlefs/littlefs/lfs.c: third-party upstream library (git
submodule), must not be modified locally.
- fs/fatfs/fatfs/source/ff.c: third-party upstream library.
- fs/lwext4/lwext4/src/ext4*.c: third-party upstream library.
- fs/cromfs/fs_cromfs.c: handles "." and ".." as directory entries
(structural, not path resolution), so its code stays.
- fs/vfs/fs_symlink.c: constructs relative paths containing ".."
(writes, not parses relpath).
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Add _inode_canonicalize() to remove '.' and '..' segments from the
absolute path before the inode tree traversal begins. This fixes the
case where paths containing '..' that resolve back to a mountpoint
root (e.g., /tmp/subdir/..) were not being handed to the filesystem.
Previously, _compute_path_depth() returned 0 for such paths, causing
the VFS to skip the mountpoint and attempt to find 'subdir' in the
pseudo filesystem -- which fails with ENOTDIR.
With canonicalization, /tmp/subdir/.. becomes /tmp before the search,
so the mountpoint is correctly matched. This fixes chdir('..'),
stat('../..'), opendir('../..'), and similar operations from within
mountpoint subdirectories.
The implementation uses an in-place two-pointer algorithm with no
additional stack allocation, safe for NuttX's small kernel stacks.
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Fix two POSIX compliance issues in mountptrename():
1. When old and new are hard links to the same file (same st_dev and
st_ino), POSIX requires rename() to succeed without removing either
link. Previously, NuttX would unlink(new) then rename(old, new),
effectively losing one link. Fix by comparing inode identity before
any destructive operation.
2. When new is a subdirectory of old (e.g., rename('a', 'a/b')), POSIX
requires EINVAL. Previously, NuttX would rmdir(new) first, then the
filesystem's rename() would fail -- but new was already deleted,
causing data loss. Fix by detecting the subdirectory relationship
(newrelpath starts with oldrelpath + '/') before any rmdir/unlink.
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
The loop condition 'namelen <= NAME_MAX' allowed filenames of
NAME_MAX+1 characters to pass validation. When the filename segment
reached exactly NAME_MAX+1 chars and was at the end of the path
string, the loop exited due to *path == '\0' and returned OK instead
of -ENAMETOOLONG.
Fix by moving the NAME_MAX check inside the loop body with an
immediate return on violation. Also fix the post-loop return to
explicitly check pathlen >= PATH_MAX instead of relying on *path
which conflated the two exit conditions.
Before: creat() with 97-char filename (NAME_MAX=96) succeeded
After: creat() with 97-char filename correctly returns ENAMETOOLONG
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Replace fs_heap_malloc/free with lib_get_tempbuffer/lib_put_tempbuffer
in smartfs_finddirentry(). This aligns smartfs with the common VFS
tempbuffer allocation pattern and is a prerequisite for the
canonicalization cleanup that removes redundant ".." handling from
individual filesystem layers.
Signed-off-by: zhaoxingyu1 <zhaoxingyu1@xiaomi.com>
The nuttx link target only listed libarch.a, board lib, arch objects and
nuttx-names.dat as prerequisites, so rebuilding an app or system library
(staging/libapps.a etc.) did not trigger a relink and the change never
reached the binary.
Add the staging libraries passed in via LINKLIBS to the prerequisite
list, matching the pattern used by arch/arm/src/Makefile.
Signed-off-by: rongbaichuan <rongbaichuan1027@163.com>
Implement PM STANDBY. Loosely based on stm32h7 with
simpler registers.
Implement PM STOP. Using a similar parameter to stm32h7's
LPDS mode bool. There is no LPDS on stm32h5 but there is
the same lower-power voltage scaling value, so rename the parameter
for stm32h5 and use SVOS5 without LPDS present.
Add arm_pminitialize implementation with default
pm subsystem initialization.
Co-authored-by: Austin.Chen <Austin.Chen@wnc.com.tw>
Signed-off-by: Liam Howatt <liamhowatt@geotab.com>
An FDPIC module is compiled by the stock arm-none-eabi GCC, which emits
correct FDPIC objects for both C and C++, but it cannot be assembled or
linked by that toolchain: its as rejects the FDPIC relocations, and its ld
carries the armelf emulation alone.
Linking FDPIC objects with the stock ld does not fail, which is the awkward
part. It produces an object marked "UNIX - System V" instead of "ARM FDPIC"
and turns every import into an R_ARM_JUMP_SLOT where the ABI wants an
R_ARM_FUNCDESC_VALUE. A jump slot is one word and a descriptor is two, a
code address and the GOT that goes with it, so the module links cleanly and
then calls out of itself with the caller's data base still in the PIC
register.
No distribution packages the arm-uclinuxfdpiceabi target, so the image
builds it, the way the Renesas stage already builds its own binutils. Only
binutils is needed, no GCC and no C library, so the stage takes about a
minute and the install is 20 MB stripped.
The tarball comes from sourceware.org, the binutils project's own host,
because ftp.gnu.org is not reliably reachable from every builder. curl runs
with --fail so that a bad fetch says so, rather than piping an error page
into tar and failing as "File format not recognized".
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Add missing blank lines after declarations and fix one bad alignment
in hostfs/rpmsgfs-related files. These are pre-existing style issues
flagged by CI's whole-file nxstyle check when our PR touches these
files. No logic change (git diff -w is blank-line-only additions).
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
Migrate hostfs path buffer allocation from fs_heap and stack
arrays to lib_get_tempbuffer/lib_put_tempbuffer.
Signed-off-by: zhaoxingyu1 <zhaoxingyu1@xiaomi.com>
Replace the global `g_lock` with a per-filesystem `fs->fs_lock`
to improve concurrency for multi-mount scenarios.
Signed-off-by: buxiasen <buxiasen@xiaomi.com>
The esp32s3-devkit:usbmsc config uses CONFIG_ESPRESSIF_SIMPLE_BOOT, so
the image is packaged with "esptool elf2image --ram-only-header". With
esptool v5.2.0, that path asserts that each flash segment satisfies
(f.tell() + 8 + BOOTLOADER_FLASH_OFFSET) % IROM_ALIGN
== segment.addr % IROM_ALIGN
When .flash.text lands right on a 64 KB (IROM_ALIGN) boundary the
assertion cannot be satisfied and elf2image fails with AssertionError,
even though NuttX itself links cleanly.
usbmsc is a plain C test and does not need the C++ runtime. Disabling
CONFIG_HAVE_CXX / CONFIG_HAVE_CXXINITIALIZE moves .flash.text off the
IROM_ALIGN boundary so the SIMPLE_BOOT image can be generated, without
changing the boot mode or the test's intent.
Signed-off-by: yukangzhi <yukangzhi@xiaomi.com>
The _inode_checkpath function uses `namelen < NAME_MAX` to validate
path segment lengths. When a filename is exactly NAME_MAX characters
long and is followed by more path segments (e.g. /dir/), the loop
exits with namelen == NAME_MAX before processing the '/' separator,
causing a spurious ENAMETOOLONG error.
Per POSIX, NAME_MAX is the maximum number of bytes in a filename not
including the terminating null, so a filename of exactly NAME_MAX
characters is valid. Change the condition to `namelen <= NAME_MAX`
so the loop can process the trailing '/' separator and correctly
reset namelen for the next path segment.
Signed-off-by: wangxingxing <wangxingxing@xiaomi.com>
Add a helper _inode_checkpath() that validates the path before the
search: it returns -ENOENT for an empty path and -ENAMETOOLONG when any
single path component exceeds NAME_MAX or the whole path exceeds
PATH_MAX. inode_search() now runs this check first so that oversized
paths and file names are rejected with the correct POSIX error code.
Signed-off-by: guohao15 <guohao15@xiaomi.com>
Add support for resolving relative path components (in particular the
".." parent references) during the inode search. A helper
_compute_path_depth() computes the remaining path depth so that a mount
point is only treated as the terminal node when the depth is positive,
and "../" components walk back up to the parent inode.
Signed-off-by: zhaoxingyu1 <zhaoxingyu1@xiaomi.com>
Replace the fs_heap_asprintf()/fs_heap_free() based allocation of the
path buffer in the inode search with the lib_get_tempbuffer()/
lib_put_tempbuffer() pool. Fixed PATH_MAX sized temporary buffers avoid
per-call heap allocation and keep the buffer allocator consistent with
the rest of the path-resolution code.
Signed-off-by: zhaoxingyu1 <zhaoxingyu1@xiaomi.com>
While walking the path components, a non-final component must refer to a
directory. When descending into a child, verify the parent inode is a
pseudo directory; if it is not, stop the search and return -ENOTDIR as
required by POSIX for a path prefix that is not a directory.
Signed-off-by: zhengyu16 <zhengyu16@xiaomi.com>
An empty pathname does not name any inode. Return -ENOENT early in
inode_search() when the path is an empty string, instead of continuing
into the search logic with a zero-length path.
Signed-off-by: zhengyu16 <zhengyu16@xiaomi.com>
When resolving a symbolic link target, call the public inode_search()
instead of the internal _inode_search() so that the link target path is
first formatted (leading '/' handling and relative-path conversion)
before the lookup. This ensures link targets are resolved through the
same normalization path as ordinary lookups.
Signed-off-by: zhengyu16 <zhengyu16@xiaomi.com>
The SDK ships no bare RTL8721F.rdev profile (unlike RTL8721Dx /
RTL8720F); it splits by flash type into RTL8721F_NOR.rdev /
RTL8721F_NAND.rdev. The default (AMEBA_PY_SOC = RTL8721F) therefore
failed the cmake `flash` target with "profile not found:
RTL8721F.rdev".
Override AMEBA_FLASH_PROFILE to RTL8721F_NOR to match the EVB flash
type and boards/arm/rtl8721f/rtl8721f_evb/scripts/Make.defs.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
ameba_setup_env.sh resolved the system interpreter via `command -v
python3`. Once a previous run put $SHIMBIN at the front of PATH, that
lookup returned $SHIMBIN/python3 and `ln -sf shim shim` created a
self-referential symlink, breaking every subsequent cmake reconfigure
with "Too many levels of symbolic links".
Scan PATH for the first python3 that is not inside $SHIMBIN and
canonicalise it with readlink -f, so the shim always points at a real
interpreter. Idempotent across reconfigures.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
The shared CMake build hardcoded a single ROM symbol linker script
(ameba_rom_symbol_acut_s.ld), so a CMake build of rtl8721f failed to
link: __rom_bss_start_ns__ / __rom_bss_end_ns__ and the rtw_* WiFi ROM
symbols were left undefined. The make build already appends rtl8721f's
four ROM symbol scripts (secure + wifi + os + NS) in
arch/arm/src/rtl8721f/ameba_board.mk; the CMake path did not.
Make the ROM symbol script set per-IC:
- ameba_gen_ldscript.sh now takes one or more ROM ld files as trailing
arguments and cat's them in order (was a single fixed argument).
- ameba_board.cmake keeps the previous single-script default and lets an
arch CMakeLists override it via AMEBA_ROM_LDS; the list is resolved to
full paths and passed to the generator.
- rtl8721f/CMakeLists.txt sets AMEBA_ROM_LDS to its four ROM symbol
scripts, matching its ameba_board.mk cat order.
rtl8721dx and rtl8720f are unchanged (still the single default script).
Verified on rtl8721f: the nsh CMake build now links the nuttx ELF
cleanly with no undefined NS-BSS or rtw_* symbols.
Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
Assisted-by: Claude <noreply@anthropic.com>
The generic ARMv7-M user SRAM helper marks memory shareable. STM32H7
Protected user data and heaps can reside in cacheable AXI or D2 SRAM, where
userspace synchronization needs LDREX/STREX to use the CPU-local exclusive
monitor.
Map protected user SRAM as Normal, cacheable, and non-shareable. Dual-core
RPTUN SRAM remains unaffected because it is mapped separately with explicit
shareable attributes.
Tested by booting a Protected image and running user and kernel work-queue
stress tests on an STM32H7 PX4 FMUv6C.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
up_allocate_heap() calculates the available user heap from SRAM_END but
previously placed the aligned region relative to SRAM123_END. That mixes
the selected primary SRAM with a fixed D2 SRAM boundary and leaves
SRAM123_END undefined for dual-core M7 and M4 configurations.
Place the user heap relative to SRAM_END so its size, MPU alignment, and
location all refer to the SRAM region selected by the chip configuration.
Tested by building and booting a Protected image on an STM32H7 PX4 FMUv6C.
Assisted-by: Codex:GPT-5
Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
The unique ID on STM32 Cortex-M33 parts is stored in flash information
memory, which cannot be accessed while the instruction cache is enabled.
Add an ICACHE state helper, temporarily disable the instruction cache
while reading the UID using 32-bit accesses, and restore it only when it
was originally enabled. This preserves the caller's cache state and
prevents a bus fault during UID access.
Assisted-by: Codex:gpt-5
Signed-off-by: jsanchez-2g <jsanchez@2g-eng.com>
Add WWDG driver support for STM32H5.
Enable the WWDG peripheral clock when WWDG is enabled.
It's based on STM32H7. This contribution has been
reduced to the minimum number of changes from the
H7 version.
Signed-off-by: Liam Howatt <liamhowatt@geotab.com>
Co-authored-by: Liam Howatt <liamhowatt@geotab.com>
CI feeds nxstyle the diff hunks with three lines of context, so style errors
that are older than this change, in the lines around the hunks, fail the
check job. They are a switch body indented two columns too deep, an
initializer brace one level in, and two declarations with no blank line
after them.
Whitespace only, no change in behaviour.
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
The ET_DYN path computes run-time addresses from link-time ones in five
places, each open-coding the arithmetic, and two of them disagree about
how: libelf_relocatedyn() adds textalloc to a relocation's r_offset in
one branch and subtracts datasec before adding datastart in the next,
while the value translation a few lines further down picks between those
two forms with an explicit test on datasec.
Collect that into libelf_addr(), which makes the test once: an address
below the data segment's link-time base belongs to text, anything at or
above it to data.
This changes nothing today. libelf_elfsize() sets
segpad = datasec - (text_vaddr + textsize)
and libelf_load() then places
datastart = textalloc + textsize + segpad
so datastart - datasec is textalloc, and the data branch reduces to
textalloc + vaddr -- exactly what the text branch returns, and exactly
what adding a single load bias did before. The two forms are the same
arithmetic written twice.
They stop being the same once text and data are placed independently,
which is what an FDPIC object requires: its two PT_LOAD segments are
relocated separately so that the read-only one can be mapped in place on
the media while only the writable one is copied. Having the translation
in one function is what makes that possible without auditing every
open-coded expression again.
Built for mps3-an547:picostest, which is CONFIG_ELF with CONFIG_PIC, and
boots identically to the same configuration without this change.
Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Implement atomic_lock/atomic_unlock using hwspinlock when
CONFIG_LIBC_ATOMIC_HWSPINLOCK is selected, and using up_irq_save/
up_irq_restore when CONFIG_LIBC_ATOMIC_IRQ is selected. Rename
arch_atomic_irq.c to arch_atomic.c.
The 64-bit atomic operations use spinlock (spin_lock_irqsave)
regardless of the selected backend, ensuring multi-core safety.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Add hardware spinlock driver implementations for cxd56, rp2040, and
lc823450 chips. These drivers provide the hwspinlock_ops_s interface
used by the atomic hwspinlock backend.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Use irq-based critical sections instead of spinlock_irq to avoid
potential deadlock in atomic contexts.
Signed-off-by: zhangyu117 <zhangyu117@xiaomi.com>
Adds GPIO defconfig on M5Stack Tab5. The example has one GPIO output
and one GPIO interrupt.
Signed-off-by: Filipe Cavalcanti <filipe.cavalcanti@espressif.com>
Add an lstat method to mountpt_operations so that mounted file systems
can report link metadata without dereferencing symbolic links.
In mountptrename() and stat_recursive(), prefer lstat() over stat()
when it is available so that rename() and the non-following stat path
operate on the link itself rather than its target, matching POSIX
semantics.
Signed-off-by: zhengyu16 <zhengyu16@xiaomi.com>