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

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


The following commit(s) were added to refs/heads/master by this push:
     new ef469bac7f samv7: ensure the correct location of message RAM
ef469bac7f is described below

commit ef469bac7fc1b9c423f03a436cafbca1649e3182
Author: Michal Lenc <[email protected]>
AuthorDate: Sun Feb 9 15:08:49 2025 +0100

    samv7: ensure the correct location of message RAM
    
    The message RAM does not behave correctly if lower 16 bits of
    buffer address overflow (upper 16 bits are set once in matrix driver
    for the entire CAN driver). For example message RAM starting at
    0x2040fc20 would not work for buffers that go beyond 0x20410000 and
    MCAN would sent data located at 0x20400000 to the network. The same
    issue would occur even if TX buffers would start directly at 0x20410000.
    The upper 16 bits would still have 0x2040 value because of RX buffers
    located in 0x2040ffff range.
    
    This commit ensures the RAM is always located at the beginning of
    the data section and thus the overflow mentioned above should never occur.
    The alternative would be to use larger alignment, but the message RAM
    can have up to 4352 words and this would cause a significant padding.
    
    The RAM is also initialized to zero to ensure valid parity/ECC checksums.
    The address issue is not described anywhere in the manual, so it is
    possible this is caused by some incorrect configuration, but the context
    of the registers looks valid.
    
    This commit also fixes the compilation errors when the driver is run
    without data cache.
    
    Signed-off-by: Michal Lenc <[email protected]>
---
 arch/arm/src/samv7/sam_mcan.c                     | 51 +++++++++++++++++++----
 boards/arm/samv7/common/scripts/flash.ld.template |  1 +
 boards/arm/samv7/common/scripts/kernel-space.ld   |  1 +
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/arch/arm/src/samv7/sam_mcan.c b/arch/arm/src/samv7/sam_mcan.c
index 5f6b2014d2..bbf63022a7 100644
--- a/arch/arm/src/samv7/sam_mcan.c
+++ b/arch/arm/src/samv7/sam_mcan.c
@@ -108,6 +108,8 @@
 #  ifndef CONFIG_ARMV7M_DCACHE_WRITETHROUGH
 #    warning !!! This driver will not work without 
CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y!!!
 #  endif
+#else
+#  define MCAN_ALIGN_UP(n)  (n)
 #endif
 
 /* General Configuration ****************************************************/
@@ -989,14 +991,30 @@ static const struct can_ops_s g_mcanops =
 
 #ifdef CONFIG_SAMV7_MCAN0
 
-/* MCAN0 message RAM allocation */
+/* MCAN0 message RAM allocation. The RAM is initalized to zeroes to ensure
+ * valid parity/ECC checksums. This should avoid possible BEC or BEU
+ * interrupts according to MCAN manual.
+ *
+ * The message RAM is also located in .mcan section that should be placed
+ * at the begining of .data section in linker script. The CAN controller
+ * seems to incorrectly handle lower 16 bits address overflow. For example
+ * message RAM starting at 0x2040fc20 would not work for buffers that
+ * go beyond 0x20410000. The same issue would occur even if TX buffers
+ * would start directly at 0x20410000. The upper 16 bits would still have
+ * 0x2040 value because of RX buffers located in 0x2040ffff range. The
+ * section ensures the RAM starts at the begining of the data section and
+ * thus overflow should not occur.
+ */
 
 static uint32_t g_mcan0_msgram[MCAN0_MSGRAM_WORDS]
+  locate_data(".mcan")
 #ifdef CONFIG_ARCH_DCACHE
-  __attribute__((aligned(MCAN_ALIGN)));
-#else
-  ;
+  __attribute__((aligned(MCAN_ALIGN)))
 #endif
+  =
+    {
+      0
+    };
 
 /* Constant configuration */
 
@@ -1088,14 +1106,30 @@ static struct can_dev_s g_mcan0dev =
 
 #ifdef CONFIG_SAMV7_MCAN1
 
-/* MCAN1 message RAM allocation */
+/* MCAN1 message RAM allocation. The RAM is initalized to zeroes to ensure
+ * valid parity/ECC checksums. This should avoid possible BEC or BEU
+ * interrupts according to MCAN manual.
+ *
+ * The message RAM is also located in .mcan section that should be placed
+ * at the begining of .data section in linker script. The CAN controller
+ * seems to incorrectly handle lower 16 bits address overflow. For example
+ * message RAM starting at 0x2040fc20 would not work for buffers that
+ * go beyond 0x20410000. The same issue would occur even if TX buffers
+ * would start directly at 0x20410000. The upper 16 bits would still have
+ * 0x2040 value because of RX buffers located in 0x2040ffff range. The
+ * section ensures the RAM starts at the begining of the data section and
+ * thus overflow should not occur.
+ */
 
 static uint32_t g_mcan1_msgram[MCAN1_MSGRAM_WORDS]
+  locate_data(".mcan")
 #ifdef CONFIG_ARCH_DCACHE
-  __attribute__((aligned(MCAN_ALIGN)));
-#else
-  ;
+  __attribute__((aligned(MCAN_ALIGN)))
 #endif
+  =
+    {
+      0
+    };
 
 /* MCAN1 constant configuration */
 
@@ -3519,6 +3553,7 @@ static void mcan_receive(struct can_dev_s *dev, uint32_t 
*rxbuffer,
 
   nbytes = (nwords << 2);
   up_invalidate_dcache((uintptr_t)rxbuffer, (uintptr_t)rxbuffer + nbytes);
+  UNUSED(nbytes);
 
   /* Format the CAN header */
 
diff --git a/boards/arm/samv7/common/scripts/flash.ld.template 
b/boards/arm/samv7/common/scripts/flash.ld.template
index b374277043..30c868f0a2 100644
--- a/boards/arm/samv7/common/scripts/flash.ld.template
+++ b/boards/arm/samv7/common/scripts/flash.ld.template
@@ -99,6 +99,7 @@ SECTIONS
 
     .data : {
         _sdata = ABSOLUTE(.);
+        *(.mcan)
         *(.data .data.*)
         *(.gnu.linkonce.d.*)
         CONSTRUCTORS
diff --git a/boards/arm/samv7/common/scripts/kernel-space.ld 
b/boards/arm/samv7/common/scripts/kernel-space.ld
index 5e53db7dfe..4c341a59a7 100644
--- a/boards/arm/samv7/common/scripts/kernel-space.ld
+++ b/boards/arm/samv7/common/scripts/kernel-space.ld
@@ -74,6 +74,7 @@ SECTIONS
 
     .data : {
         _sdata = ABSOLUTE(.);
+        *(.mcan)
         *(.data .data.*)
         *(.gnu.linkonce.d.*)
         CONSTRUCTORS

Reply via email to