This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit ff1c03f68c493e89f1aef960d16d263a09d1c2a4
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Nov 11 11:42:46 2026 +0100

    arch/arm/rp23xx: Allow only a separate PSRAM heap with SMP.
    
    The atomic operations of the RP2350 work across the two cores only in
    the internal SRAM (datasheet, section 2.1.6).  rp23xx_mpu_share_sram()
    maps the SRAM Shareable, so there an exclusive access goes to the global
    exclusive monitor.  The PSRAM keeps the default memory map, Non-
    shareable, so an exclusive access to it uses only the local monitor of
    the core.  On one core this works.  With SMP a lock or an atomic
    variable in the PSRAM does not exclude the other core: on a Pimoroni
    Pico Plus 2 two cores that add 1 to an atomic counter in the PSRAM a
    million times each lose one update in three, without an error.
    
    With RP23XX_PSRAM_HEAP_SINGLE (the default) or RP23XX_PSRAM_HEAP_USER,
    malloc() can return PSRAM for any object, a mutex or a semaphore among
    them.  So with SMP allow only RP23XX_PSRAM_HEAP_SEPARATE, and make it
    the default there.  RP23XX_PSRAM_HEAP_SINGLE also needs MM_REGIONS
    greater than 1: with 1 the PSRAM was silently not added to the heap.
    And define arm_addregion() for every heap mode when MM_REGIONS is
    greater than 1: up_initialize() calls it, and with the separate or the
    user heap the link failed.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/arm/src/rp23xx/Kconfig        | 12 ++++++++++--
 arch/arm/src/rp23xx/rp23xx_heaps.c | 16 +++++++++++-----
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm/src/rp23xx/Kconfig b/arch/arm/src/rp23xx/Kconfig
index 32ce2d7afab..23665b34814 100644
--- a/arch/arm/src/rp23xx/Kconfig
+++ b/arch/arm/src/rp23xx/Kconfig
@@ -24,13 +24,20 @@ if RP23XX_PSRAM
 
 choice
        prompt "PSRAM heap usage"
+       default RP23XX_PSRAM_HEAP_SEPARATE if SMP
        default RP23XX_PSRAM_HEAP_SINGLE
        ---help---
                How the detected PSRAM is exposed to the memory manager.
 
+               The atomic operations of the RP2350 work across the two cores
+               only in the internal SRAM (datasheet, section 2.1.6).  In the
+               PSRAM they exclude only the local core, so with SMP a lock or
+               an atomic variable in the PSRAM does not exclude the other core.
+               With SMP the PSRAM can only be a separate heap.
+
 config RP23XX_PSRAM_HEAP_SINGLE
        bool "Add PSRAM to the main heap"
-       depends on !MM_KERNEL_HEAP
+       depends on !MM_KERNEL_HEAP && !SMP && MM_REGIONS > 1
        ---help---
                Add the PSRAM region to the main heap.  Requires
                CONFIG_MM_REGIONS greater than 1 so the extra region can be
@@ -38,7 +45,7 @@ config RP23XX_PSRAM_HEAP_SINGLE
 
 config RP23XX_PSRAM_HEAP_USER
        bool "PSRAM as the user heap"
-       depends on MM_KERNEL_HEAP
+       depends on MM_KERNEL_HEAP && !SMP
        ---help---
                Use the PSRAM as the (user) heap and the internal SRAM as the
                kernel heap.
@@ -49,6 +56,7 @@ config RP23XX_PSRAM_HEAP_SEPARATE
        ---help---
                Expose the PSRAM as a separate named heap ("psram") rather than
                adding it to the main heap.
+               With SMP, do not allocate a lock or an atomic variable from it.
 
 endchoice
 
diff --git a/arch/arm/src/rp23xx/rp23xx_heaps.c 
b/arch/arm/src/rp23xx/rp23xx_heaps.c
index a2b57df4f10..56422614f31 100644
--- a/arch/arm/src/rp23xx/rp23xx_heaps.c
+++ b/arch/arm/src/rp23xx/rp23xx_heaps.c
@@ -53,15 +53,14 @@
 static struct mm_heap_s *g_psramheap;
 #endif
 
-#if defined(CONFIG_RP23XX_PSRAM_HEAP_SINGLE)
-
-#if defined(CONFIG_MM_KERNEL_HEAP)
-#error cannot use CONFIG_MM_KERNEL_HEAP with single heap
-#endif
+/* up_initialize() calls arm_addregion() whenever CONFIG_MM_REGIONS > 1.
+ * Only the single heap has a region to add: the PSRAM.
+ */
 
 #if CONFIG_MM_REGIONS > 1
 void arm_addregion(void)
 {
+#ifdef CONFIG_RP23XX_PSRAM_HEAP_SINGLE
   size_t psram_size = rp23xx_psram_size();
 
   /* Add the detected PSRAM region to the main heap */
@@ -70,9 +69,16 @@ void arm_addregion(void)
     {
       kumm_addregion(PSRAM_START, psram_size);
     }
+#endif
 }
 #endif
 
+#if defined(CONFIG_RP23XX_PSRAM_HEAP_SINGLE)
+
+#if defined(CONFIG_MM_KERNEL_HEAP)
+#error cannot use CONFIG_MM_KERNEL_HEAP with single heap
+#endif
+
 #elif defined (CONFIG_RP23XX_PSRAM_HEAP_USER)
 
 #if !defined(CONFIG_MM_KERNEL_HEAP)

Reply via email to