C++ strict mode drops the GNU ", ##__VA_ARGS__" comma elision, so
GET_ARG_COUNT() and REVERSE_ARG() misselect their dispatch entry with
zero varargs. Centralize the empty-argument handling in GET_ARG_COUNT
(via __VA_OPT__ for C++) and make REVERSE_ARG and FOREACH_ARG dispatch
through CONCATENATE(prefix, GET_ARG_COUNT(...)), removing the two
duplicated 33-entry selector lists.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
string(REPLACE) splits on every space, so a flag such as
-I"/path with spaces" becomes several bogus compile options.
Use separate_arguments(UNIX_COMMAND), matching EXTRA_FLAGS.
Signed-off-by: Zhaoqi Xu <lzy00419@outlook.com>
Both files put the body of the relocation switch at the same indent as the
switch braces, so nxstyle reports forty-four errors in each and any patch
whose hunks land near them fails the check job.
Giving the body its level takes the bit diagrams in the comments one column
past the line limit. The rulers say Instr rather than Instructions, which is
enough and is what the same rulers further down already do. A comment that
had no code on its line becomes a sentence of its own, and two that were a
column out are put right.
Whitespace and comments only. Compiled before and after for cortex-m7 and
cortex-m33: the disassembly is identical.
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
mtd_partition(mtd, firstblock, nblocks) takes the partition offset and
size in units of the underlying device "blocks" (geo.blocksize), not
erase blocks. Several board drivers accumulated partoffset and computed
the partition size in erase-block units and passed them straight to
mtd_partition(), so on devices where blocksize != erasesize (W25/SST25:
256B vs 4KB, SAMD5E5 progmem: 512B vs 8KB) every partition came out
erasesize/blocksize (16x) too small and misaligned.
Convert partoffset and partszbytes to geo.blocksize units at the
mtd_partition() call site while keeping the erase-block accumulation.
Affected boards:
- stm32f103-minimum (W25)
- at32f437-mini (W25)
- stm32f429i-disco (SST25F064, enabled in the extflash defconfig)
- metro-m4 (SAMD5E5 progmem)
Also fix pre-existing nxstyle violations in the touched files so the
change passes checkpatch (see CONTRIBUTING.md).
Assisted-by: DeepSeek Harness:deepseek-v4-flash
Signed-off-by: rongbaichuan <rongbaichuan1027@163.com>
Required to run the qemu-intel64 citest/NTFC configuration on CI; the
image only shipped qemu-system-arm and qemu-system-misc.
Signed-off-by: raiden00pl <raiden00@railab.me>
The Tab5 ships in two hardware variants and the board supported only
one of them. The earlier units carry an ILI9881C panel and a GT911
touch controller, the later ones a ST7121/ST7123 panel and a ST7123
touch controller, and the two always come as a pair. On an earlier
unit the panel stays lit but black, and the touch bring-up fails with
"failed to register ST7123: -5".
Add the ILI9881C initialization table, taken from the Espressif BSP,
along with the display timings it needs, which differ from the ST7123
ones in the DPI clock (60 MHz instead of 70 MHz) and in every porch.
The panel identification lives on command page 1 and is read and
logged during bring-up, so the boot log says which panel answered.
Add the GT911 to the touch controller choice. These units have a
pull-up to 3V3 on the touch interrupt line that keeps the controller
from scanning, so the line is driven low instead of being used as an
interrupt, and contacts are picked up when the device is read. The
controller identification is logged the same way.
Split esp32p4_touch.c into one file per controller, which is how the
panels are already handled, and document both variants together with
the I2C scan that tells which one is fitted. The defaults are
unchanged, so an existing configuration still selects the ST7121
panel and the ST7123 touch controller.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Two defects keep the driver from reporting touches on a board that
cannot use the interrupt line.
The register write built two messages joined by I2C_M_NOSTART. That
puts the same bytes on the wire as a single three byte message, but
resuming a transfer without a start condition is optional, and a
controller that does not implement it fails the transfer. On the
ESP32-P4 every write returned -ETIMEDOUT, so the buffer status clear
at 0x814E never reached the controller and gt9xx_read_touch_data()
returned an error for every read. Send the register address and the
value as a single message.
read() returned a full struct touch_sample_s even when the controller
reported no contact, with npoints set to zero. A caller that judges
the read by its return value takes that for valid data: the LVGL
touchscreen driver reads a second sample to decide whether to keep
reading, always gets one, so it sets continue_reading on every pass
and lv_indev_read() never returns. The display then stops refreshing
after the first frame while the touch reads spin. Return -EAGAIN when
there is no contact and the file was opened with O_NONBLOCK, which is
what the touchscreen upper half does in the same situation. A
blocking reader keeps the previous behaviour.
While here, add the blank line after the declaration in gt9xx_poll() that
nxstyle asks for. It predates this change, but the CI runs checkpatch over
every file a commit touches, so it has to go.
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
Pre-existing violations in this file, reported by checkpatch because the
preceding commit touches it:
nrf53_gpiote.c:185: Missing blank line after declarations
nrf53_gpiote.c:213: Bad alignment
nrf53_gpiote.c:216: Bad alignment
nrf53_gpiote.c:259: Bad right brace alignment
Add the blank line after the declarations in the channel-callback block,
indent the two `break;` statements into their case bodies, and align the
brace closing the per-port `for` loop with its opening at line 209 (it
sat at seven spaces, so neither the loop's eight nor anything else).
Whitespace only — no functional change, brace count unchanged.
Signed-off-by: AlmAck <gluca86@gmail.com>
The driver presents a single channel space of GPIOTE_CHANNELS entries
across the application core's two GPIOTE peripherals, and splits it:
inst = (channel < GPIOTE_PER_CHANNEL) ? 0 : 1;
rchan = (inst == 1) ? channel : (channel - GPIOTE_PER_CHANNEL);
rchan is the channel index within the selected instance, used to build
the per-channel register offsets, so it must be
rchan = channel - GPIOTE_PER_CHANNEL * inst
The ternary has the two arms the other way round: a channel on instance
0 gets rchan = channel - GPIOTE_PER_CHANNEL, which is negative, and a
channel on instance 1 gets an index still offset by a full instance.
The interrupt handler in this same file already applies that mapping in
the opposite direction, converting a per-instance channel back to the
global one:
off = i + GPIOTE_PER_CHANNEL * inst;
so the two were inconsistent, and it is the rchan sites that were wrong.
Per the nRF5340 Product Specification, 'GPIOTE - GPIO tasks and
events', the application core has two GPIOTE instances, GPIOTE0 (secure,
base 0x5000D000) and GPIOTE1 (non-secure, base 0x4002F000), each with
eight channels and its own CONFIG[n] array at offset 0x510 + 4n for
n = 0..7. This matches GPIOTE_PER_CHANNEL == 8, the two base addresses
in hardware/nrf53_memorymap_cpuapp.h, and NRF53_GPIOTE_CONFIG_OFFSET()
in hardware/nrf53_gpiote.h, so rchan is required to be in 0..7 and a
negative value cannot address a CONFIG register.
With a negative rchan the CONFIG register write for a channel on
instance 0 lands below the instance base instead of in CONFIG[n], so the
channel is never configured and its GPIOTE interrupt is never enabled.
On nrf5340-dk this makes the board buttons dead.
Both call sites are corrected.
Signed-off-by: AlmAck <gluca86@gmail.com>
Correct the misspelled up_timer_initialize() and up_initialize()
API names in the tickless OS documentation to match the declarations
in include/nuttx/arch.h.
Signed-off-by: arnavsharma990 <2006arnavsharma@gmail.com>
The XIAO ESP32-S3 Sense's onboard microSD slot (Seeed XIAOML Kit) is
wired to SPI2 through the GPIO matrix: SCK=GPIO7, MOSI=GPIO9,
MISO=GPIO8 (confirmed against espressif/arduino-esp32's
XIAO_ESP32S3/pins_arduino.h) and CS=GPIO21 (confirmed against this
project's own working xiaoml_bench_logger.ino, which tries CS
candidates {21, 3} in that order -- GPIO3 is a documented fallback,
not the real pin; a Seeed wiki page that names GPIO3 as CS turned out
to be wrong and was the initial, unsuccessful attempt here).
Wires up board_sdmmc_spi_initialize() (common esp32s3 board code,
CONFIG_MMCSD_SPI) into this board's bringup, and adds the
esp32s3_spi2_status() callback (SPI_STATUS_PRESENT for SPIDEV_MMCSD(0))
that esp32s3-devkit and other in-tree boards already provide -- the
esp32s3-xiao board had no SPI board file at all before this.
Validated on the bench: CMD0/CMD41/CMD58 handshake succeeds, SD ver2
card identified (SanDisk 32GB, 62333952 sectors), mounts as vfat,
survives umount+remount with a written file intact.
Needed board defconfig additions (not included in this NuttX-tree
commit; see the 61680_FW project repo for the board config that turns
this on):
CONFIG_ESP32S3_SPI2=y
CONFIG_ESP32S3_SPI2_CSPIN=21
CONFIG_ESP32S3_SPI2_CLKPIN=7
CONFIG_ESP32S3_SPI2_MOSIPIN=9
CONFIG_ESP32S3_SPI2_MISOPIN=8
CONFIG_MMCSD=y
CONFIG_NSH_MMCSDSPIPORTNO=2
CONFIG_FS_FAT=y
CONFIG_FAT_LFN=y
CONFIG_FAT_LCNAMES=y
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Felipe Moura <mouraf@fiteclabs.org.br>
bt_conn_send() splits an outgoing L2CAP PDU into HCI ACL fragments no
larger than g_btdev.le_mtu, the controller's HCI ACL data packet length.
The first fragment caps its length correctly:
len = remaining;
if (len > g_btdev.le_mtu)
{
len = g_btdev.le_mtu;
}
The continuation loop below uses '<' instead of '>', so a continuation
shorter than le_mtu has its length raised to le_mtu rather than left
alone. Both len and remaining are uint16_t, which turns a wrong length
into an underflow:
With le_mtu 251 and a 300-byte PDU, the first fragment takes 251 bytes
and leaves remaining == 49. The loop then raises len from 49 to 251, so
memcpy(bt_buf_extend(buf, len), ptr, len);
reads 202 bytes past the end of the source, and
remaining -= len;
evaluates 49 - 251 as a uint16_t, wrapping to 65334. On the next
iteration len is 65334, which is not less than le_mtu, so it survives
the cap. bt_buf_extend() carries only a DEBUGASSERT on tailroom, so
with assertions disabled it adds 65334 to buf->len and returns, and the
memcpy writes 64 KB into a pooled buffer sized for a few hundred bytes.
Only the last fragment of a multi-fragment PDU is normally shorter than
le_mtu, so the first fragmented transmission triggers it.
Signed-off-by: AlmAck <gluca86@gmail.com>
STM32_NGPIO_PORTS is (N+15)>>4. 81 (the real pin count) yields six
ports A-F, so PH0/PH1 cannot be configured. 113 matches the F40x
100-pin entries and gives A-H.
Signed-off-by: Jacob Dahl <dahl.jakejacob@gmail.com>
board_buttons() loops over the four buttons but read the GPIO of
g_buttons[BUTTON_BTN1] on every iteration, so all four bits of the
returned set reflected the state of button 1 alone.
Matches the equivalent loop in nrf52840-dk's nrf52_buttons.c.
Signed-off-by: AlmAck <gluca86@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>
NuttX-side support for the zbus message bus port (apps/system/zbus in
nuttx-apps), built on the link-time iterable sections infrastructure
added in a companion PR:
- include/nuttx/linker/common-rom.ld and common-insert.ld: register the
zbus channel, observer and channel observation iterable sections
(ITERABLE_SECTION blocks guarded by CONFIG_ZBUS, no-op otherwise) for
the include and the zero-touch INSERT modes respectively;
common-ram.ld: note that zbus needs no RAM sections.
- Documentation/applications/system/zbus: Sphinx documentation for the
zbus application, with the upstream Zephyr diagrams (Apache-2.0).
- .codespellrc: skip the reused zbus SVG diagrams (embedded base64
raster data trips the spell checker).
Assisted-by: Claude Code
Signed-off-by: Jorge Guzman <jorge.gzm@gmail.com>
set_sporadic_param() tested rtcb (the calling task) instead of tcb (the
task being modified). A cross-task sched_setparam() therefore either
skipped the sporadic parameter update entirely or, when the calling
task was itself sporadic, reset a task that had no sporadic state.
Use tcb consistently and drop the now-unused rtcb argument.
Signed-off-by: yushuailong <yyyusl@qq.com>
The policy flag bits were cleared before the switch statement, so the
checks testing whether the task was previously SCHED_SPORADIC could
never be true. As a result nxsched_stop_sporadic() was never called
when a sporadic task switched to SCHED_FIFO/SCHED_RR, leaking the
sporadic state, and a sporadic-to-sporadic reconfiguration ran
initialize instead of reset.
Clear the policy flag bits only after the previous policy has been
evaluated, right before the new policy bits are set.
Signed-off-by: yushuailong <yyyusl@qq.com>
Fixed all the issues reported by checkpatch.sh in stm32_eth_m3m4_v1.c,
stm32f7/stm32_ethernet.c, stm32h5/stm32_ethernet.c, stm32h7/stm32_ethernet.c
Signed-off-by: alexcekay <alexander@auterion.com>
The STM32 Ethernet MAC drivers hard-code a 60-second TX watchdog
timeout. While this is a reasonable general default, certain board
designs and use-cases require a shorter or longer value.
Introduce CONFIG_STM32_ETH_TXTIMEOUT via the shared Kconfig.eth
with a #ifndef fallback. The default is kept at 60 seconds
to preserve existing behavior.
Assisted-by: Claude Code:claude-sonnet-5
Signed-off-by: alexcekay <alexander@auterion.com>
nxsched_stop_sporadic() freed tcb->sporadic but left
TCB_FLAG_SCHED_SPORADIC set in tcb->flags. On thread exit,
nxtask_recover() calls nxsched_stop_sporadic() and the final context
switch in up_exit() then sees the stale SPORADIC policy flag and calls
nxsched_suspend_sporadic() on a TCB whose sporadic state is already
freed, tripping DEBUGASSERT(tcb->sporadic) and hanging the system
(reproduced by ostest sporadic_test on sim, present on master).
Clear the policy bits inside nxsched_stop_sporadic() so every caller
leaves the TCB in a consistent state.
Signed-off-by: yushuailong <yyyusl@qq.com>
Adds a dedicated page (matching the lsm6dso32 one, the closest
register-compatible driver already documented) instead of a plain list
entry: chip description, registration examples for both polling and
interrupt-driven mode -- including the single-shared-INT-pin
config_s/attach() shape this driver actually uses, unlike sensors that
need one interrupt pin per sub-sensor -- and the two custom ioctls
(SNIOC_WHO_AM_I, SNIOC_SETFULLSCALE) with their argument units.
Requested in review on this PR.
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
No driver exists for this exact chip. lsm6dsl.c is the closest
register-compatible match but is the deprecated legacy char-device
style; lsm6dso32_uorb.c is the closest uORB-style match but is for a
different chip variant. The new driver borrows lsm6dso32_uorb.c's
structure (dual sensor_lowerhalf_s, raw I2C_TRANSFER helpers) and
lsm6dsl.h's register map -- fixing a bug in the header it was ported
from along the way: LSM6DSL_FIFO_CTRL2_SHIFT is defined as 255 instead
of 0.
Delivery mode is chosen the same way mpu6050 does: kthread polling by
default, or interrupt-driven if the board supplies attach(). Unlike
the earlier lsm6dso32-style design this went through first -- one INT
pin and one activate()/interrupt path per sub-sensor -- the shipped
version uses a single shared INT pin for both, mirroring mpu6050's own
one-handler-one-worker design (#19601) instead. The two-independent-
paths version worked for accel alone but was intermittently broken for
gyro: activate() sometimes never actually turned CTRL2_G on even
though the interrupt-enable bit was written correctly, and other times
the whole console hung -- a real race, never conclusively root-caused
on a serial console with no JTAG available. The LSM6DS3TR-C supports
OR'ing both DRDY_XL and DRDY_G onto one pin via independent enable
bits in that pin's INTn_CTRL register, so there was no need for two
paths in the first place: one ISR times the burst, one HPWORK worker
reads OUT_TEMP_L..OUTZ_H_A (14 contiguous bytes covering temp, gyro
and accel in one I2C transaction) and pushes whichever topic(s) are
currently subscribed. activate() now just flips each sub-sensor's own
bit in the shared register instead of running its own attach.
On the XIAO ESP32-S3 with Seeed's IMU Breakout Board, INT1/INT2 route
to GPIO3/GPIO4 (confirmed from the breakout board's schematic, not
guessed). Only INT1/GPIO3 is wired up, since one pin is now enough;
GPIO4/INT2 is documented as available but unused.
Also: CTRL1_XL's FS_XL bits were never actually written to match the
driver's own software default (4g) -- registration set the in-memory
value but the chip stayed at its 2g reset default until a caller
issued an explicit SNIOC_SETFULLSCALE. register() now writes it.
Validated on the bench, both modes, reproduced across multiple fresh
reboots: WHO_AM_I reads 0x6a, sensor_accel0/sensor_gyro0 stream
continuously. Interrupt mode delivers ~300 samples of each per 6s
window with shared timestamps down to the microsecond between the two
topics per event, confirming both come from the same burst read.
Assisted-by: Claude <noreply@anthropic.com>
Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
Fixes several bugs in EDID parsing and consolidates syslog output in
videomode_dump to prevent broken lines.
Specific changes include:
- Corrected bitwise masking for _HACT_HI (0xf0) and _HBLK_HI (0x0f)
to properly extract the upper bits of horizontal active and blanking
timings.
- Multiplied raw EDID pixel clock by 10 to convert it into kHz, matching
the expectation of the videomode struct dotclock field.
- Combined fragmented syslog calls in videomode_dump into a single line
to prevent unwanted newlines from splitting the output across multiple logs.
Signed-off-by: Lwazi Dube <lwazeh@gmail.com>
This commit introduces EDID reading and parsing to the JZ4780 display
driver, replacing hardcoded resolution limits with dynamic mode selection
based on the connected display's capabilities.
Specific changes include:
- Implemented I2C DDC master communication for the HDMI controller to
read EDID blocks from monitors.
- Added dynamic mode selection to calculate bandwidth and pick the best
supported resolution, prioritizing the EDID preferred mode.
- Dynamically allocated framebuffer bounds (g_planeinfo and g_videoinfo)
based on parsed EDID dimensions.
- Configured GPIO pin multiplexing for HDMI power, DDC, and control pins
(POWER_EN, CEC, SCL, SDA) to enable display power and communication
on the CI20 board.
Signed-off-by: Lwazi Dube <lwazeh@gmail.com>
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>