Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Portenta H7 LITE: SDRAM BUS FAULT / UNALIGNED ACCESS(USAGE FAULT) #74

Open
mjs513 opened this issue Feb 10, 2025 · 3 comments
Open

Portenta H7 LITE: SDRAM BUS FAULT / UNALIGNED ACCESS(USAGE FAULT) #74

mjs513 opened this issue Feb 10, 2025 · 3 comments

Comments

@mjs513
Copy link

mjs513 commented Feb 10, 2025

@KurtE - @facchinm
While testing SDRAM on the Portenta H7 Lite found that depending on sketch you will get one of the 2 faults mentioned in the tile depending on the sketch used.

If I run a simple sketch:

#include "SDRAM.h"
SDRAMClass ram;

void setup() {
    Serial.begin(115200);
    while (!Serial);
uint8_t *b;

  ram.begin();
  b = (uint8_t *)ram.malloc(320 * 240 * sizeof(uint8_t));
}


void loop() {
    
}

you will get the error message:


*** Booting Zephyr OS build v3.7.0-8126-g33bc8a018ecc ***
[00:00:03.158,000] <err> os: ***** BUS FAULT *****
[00:00:03.165,000] <err> os:   Imprecise data bus error
[00:00:03.173,000] <err> os: r0/a1:  0xc0000000  r1/a2:  0x240256a0  r2/a3:  0x007ffff4
[00:00:03.184,000] <err> os: r3/a4:  0xc0000000 r12/ip:  0x00000008 r14/lr:  0x2402828d
[00:00:03.195,000] <err> os:  xpsr:  0x21000000
[00:00:03.203,000] <err> os: s[ 0]:  0x00800000  s[ 1]:  0xc0000000  s[ 2]:  0x00000008  s[ 3]:  0xc0000000
[00:00:03.215,000] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x240282fb  s[ 6]:  0x240282e9  s[ 7]:  0x240282c3
[00:00:03.228,000] <err> os: s[ 8]:  0x240288a9  s[ 9]:  0x24028299  s[10]:  0x00000000  s[11]:  0x24028479
[00:00:03.240,000] <err> os: s[12]:  0x00000000  s[13]:  0x2402554c  s[14]:  0x2402845d  s[15]:  0x0804ab79
[00:00:03.253,000] <err> os: fpscr:  0x2402554c
[00:00:03.260,000] <err> os: Faulting instruction address (r15/pc): 0x24028030
[00:00:03.270,000] <err> os: >>> ZEPHYR FATAL ERROR 26: Unknown error on CPU 0
[00:00:03.280,000] <err> os: Current thread: 0x24003200 (main)
[00:00:03.289,000] <err> os: Halting system

This also occurs with the portenta H7 example sketch used for Mbed.

If I run the current example that tests memory in current zephy_sdram library you get the usuage fault:


*** Booting Zephyr OS build v3.7.0-8126-g33bc8a018ecc ***
[00:00:04.695,000] <err> os: ***** USAGE FAULT *****
[00:00:04.703,000] <err> os:   Unaligned memory access
[00:00:04.711,000] <err> os: r0/a1:  0xd9c519ba  r1/a2:  0x00000017  r2/a3:  0x0                    006f71f
[00:00:04.722,000] <err> os: r3/a4:  0x2402d88c r12/ip:  0x00000008 r14/lr:  0x2                    40283a7
[00:00:04.733,000] <err> os:  xpsr:  0x01000200
[00:00:04.740,000] <err> os: s[ 0]:  0x24029a20  s[ 1]:  0x24029a05  s[ 2]:  0x2                    402f010  s[ 3]:  0x00000000
[00:00:04.753,000] <err> os: s[ 4]:  0x24028391  s[ 5]:  0x2402a041  s[ 6]:  0x2                    4028361  s[ 7]:  0x24029b3d
[00:00:04.765,000] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x2402554c  s[10]:  0x2                    4029b21  s[11]:  0x0804ab79
[00:00:04.778,000] <err> os: s[12]:  0x2402554c  s[13]:  0x24029b21  s[14]:  0x0                    0000000  s[15]:  0x00000000
[00:00:04.791,000] <err> os: fpscr:  0x00000000
[00:00:04.798,000] <err> os: Faulting instruction address (r15/pc): 0x24029c24
[00:00:04.808,000] <err> os: >>> ZEPHYR FATAL ERROR 31: Unknown error on CPU 0
[00:00:04.818,000] <err> os: Current thread: 0x24003200 (main)
[00:00:04.827,000] <err> os: Halting system

Comparing the config files for the giga and the h7 the only real difference that would apply is:

CONFIG_MPU=y 

Note in the prj.conf it is set as:

CONFIG_MPU=n

If I comment it out it in the H7 it fails to rebuild:

warning: NOCACHE_MEMORY (defined at arch/Kconfig:408) has direct dependencies ARCH_HAS_NOCACHE_MEMORY_SUPPORT with value n, but is currently being y-selected by the following symbols:
 - ETH_STM32_HAL (defined at drivers/ethernet/Kconfig.stm32_hal:7), with value y, direct dependencies DT_HAS_ST_STM32_ETHERNET_ENABLED && ETH_DRIVER (value: y), and select condition SOC_SERIES_STM32H7X && CPU_CORTEX_M7 && DT_HAS_ST_STM32_ETHERNET_ENABLED && ETH_DRIVER (value: y)
Parsing /home/my_new_zephyr_folder/zephyr/Kconfig
Loaded configuration '/home/my_new_zephyr_folder/zephyr/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_defconfig'
Merged configuration '/home/my_new_zephyr_folder/ArduinoCore-zephyr/loader/prj.conf'
Merged configuration '/home/my_new_zephyr_folder/ArduinoCore-zephyr/loader/boards/arduino_portenta_h7_m7.conf'

error: Aborting due to Kconfig warnings

CMake Error at /home/my_new_zephyr_folder/zephyr/cmake/modules/kconfig.cmake:396 (message):
  command failed with return code: 1
Call Stack (most recent call first):
  /home/my_new_zephyr_folder/zephyr/cmake/modules/zephyr_default.cmake:133 (include)
  /home/my_new_zephyr_folder/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
  /home/my_new_zephyr_folder/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
  CMakeLists.txt:7 (find_package)


-- Configuring incomplete, errors occurred!
FATAL ERROR: command exited with status 1: /usr/bin/cmake -DWEST_PYTHON=/home/my_new_zephyr_folder/ArduinoCore-zephyr/venv/bin/python3.12 -B/home/my_new_zephyr_folder/ArduinoCore-zephyr/build -GNinja -DBOARD=arduino_portenta_h7//m7 -S/home/my_new_zephyr_folder/ArduinoCore-zephyr/loader

In the Portenta H7 SDRAM library it configures the MPU to address unaligned region:

int SDRAMClass::begin(uint32_t start_address) {

	if (FMC_SDRAM_DEVICE->SDCMR == 0x00000000U) {
		bool ret = sdram_init();
		if (ret == false) {
			return 0;
		}
		/*  Enable MPU for the SDRAM Memory Region to allow non-aligned
			accesses (hard-fault otherwise)
			Initially disable all access for the entire SDRAM memory space,
			then enable access/caching for the size used
		*/

        if (SDRAM_START_ADDRESS == 0x60000000) {
            HAL_SetFMCMemorySwappingConfig(FMC_SWAPBMAP_SDRAM_SRAM);
        }

        #ifdef CORE_CM4
        MPU_Config();
        #endif
	}

	if (start_address) {
		malloc_addblock((void*)start_address, SDRAM_END_ADDRESS - start_address);
	}

	return 1;
}

so do not know how to handle this under Zephyr. PS there is more they do to configure the region.

Under zephyr did see the config option to

CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT

not sure enabling this will cause other issues

Probably have to address via:
https://docs.zephyrproject.org/apidoc/latest/arm__mpu__v8_8h.html
actually probably
https://docs.zephyrproject.org/apidoc/latest/arm__mpu__v7m_8h.html

or maybe address it through memory regions:
https://docs.zephyrproject.org/latest/services/mem_mgmt/index.html
https://docs.zephyrproject.org/apidoc/latest/group__mm__drv__apis.html

@KurtE
Copy link

KurtE commented Feb 11, 2025

@mjs513 I verified your sketch gives the same results on my H7.
I also tried updating your sketch to see if anything would print out:

#include "SDRAM.h"
SDRAMClass ram;

void setup() {
    Serial.begin(115200);
    while (!Serial);
uint8_t *b;
  Serial.println("Before Ram begin"); Serial.flush();
  ram.begin();
  Serial.println("After Ram begin"); Serial.flush();
  b = (uint8_t *)ram.malloc(320 * 240 * sizeof(uint8_t));
  Serial.println("After malloc begin"); Serial.flush();
}


void loop() {
    
}

No output in the Serial monitor;
Same fault:

uart:~$
*** Booting Zephyr OS build v3.7.0-8126-g33bc8a018ecc ***
[00:00:30.728,000] <err> os: ***** BUS FAULT *****
[00:00:30.736,000] <err> os:   Imprecise data bus error
[00:00:30.744,000] <err> os: r0/a1:  0xc0000000  r1/a2:  0x24030ea0  r2/a3:  0x007ffff4
[00:00:30.755,000] <err> os: r3/a4:  0xc0000000 r12/ip:  0x00000002 r14/lr:  0x2403328d
[00:00:30.766,000] <err> os:  xpsr:  0x21000000
[00:00:30.773,000] <err> os: s[ 0]:  0x00000002  s[ 1]:  0x240337c1  s[ 2]:  0x08068298  s[ 3]:  0x61000000
[00:00:30.786,000] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x00000000  s[ 6]:  0x00000000  s[ 7]:  0x00000000
[00:00:30.798,000] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x00000000  s[11]:  0x00000000
[00:00:30.811,000] <err> os: s[12]:  0x00000000  s[13]:  0x00000000  s[14]:  0x00000000  s[15]:  0x00000000
[00:00:30.823,000] <err> os: fpscr:  0x4bbebc20
[00:00:30.831,000] <err> os: Faulting instruction address (r15/pc): 0x24033030
[00:00:30.841,000] <err> os: >>> ZEPHYR FATAL ERROR 26: Unknown error on CPU 0
[00:00:30.851,000] <err> os: Current thread: 0x240031f8 (main)
[00:00:30.860,000] <err> os: Halting system

If I add printk calls like:

#include "SDRAM.h"
SDRAMClass ram;

void setup() {
  printk("Setup called\n");
    Serial.begin(115200);
  while (!Serial)
    ;
  uint8_t *b;
  Serial.println("Before Ram begin");
  Serial.flush();
  printk("before Ram begin\n");
  ram.begin();
  printk("after Ram begin\n");
  Serial.println("After Ram begin");
  Serial.flush();
  b = (uint8_t *)ram.malloc(320 * 240 * sizeof(uint8_t));
  Serial.println("After malloc begin");
  Serial.flush();
}

I see...

uart:~$
*** Booting Zephyr OS build v3.7.0-8126-g33bc8a018ecc ***
Setup called
before Ram begin
[00:00:04.747,000] <err> os: ***** BUS FAULT *****
and the Ram begin also prints in the USB port...

@KurtE
Copy link

KurtE commented Feb 12, 2025

Quick update: I was curious if the IO pins associated with SDRam were updated to the proper Altenate Function mode.
S I added some code to dump out some of the GPIO states just before we called the SDRam:
Whole sketch again:

#include "SDRAM.h"
SDRAMClass ram;

void print_gpio_regs(const char *name, GPIO_TypeDef* port) {
  printk("GPIO%s(%p) %08X %08X %08x\n", name, port, port->MODER, port->AFR[0], port->AFR[1]);
  Serial.print("GPIO"); Serial.print(name);
  Serial.print(" "); Serial.print(port->MODER, HEX); 
  Serial.print(" "); Serial.print(port->AFR[0], HEX); 
  Serial.print(" "); Serial.println(port->AFR[1], HEX); 
} 

void setup() {
  printk("Setup called\n");
    Serial.begin(115200);
  while (!Serial)
    ;
  uint8_t *b;
  Serial.println("Before Ram begin");
  Serial.flush();
  printk("before Ram begin\n");
  print_gpio_regs("A", GPIOA);
  print_gpio_regs("B", GPIOB);
  print_gpio_regs("C", GPIOC);
  print_gpio_regs("D", GPIOD);
  print_gpio_regs("E", GPIOE);
  print_gpio_regs("F", GPIOF);
  print_gpio_regs("G", GPIOG);
  print_gpio_regs("H", GPIOH);
  print_gpio_regs("I", GPIOI);
  print_gpio_regs("J", GPIOJ);
  print_gpio_regs("K", GPIOK);

  ram.begin();
  printk("after Ram begin\n");
  Serial.println("After Ram begin");
  Serial.flush();
  b = (uint8_t *)ram.malloc(320 * 240 * sizeof(uint8_t));
  Serial.println("After malloc begin");
  Serial.flush();
}

void loop() {

}

On the Portenta H7: that crashes with this sketh I see:

*** Booting Zephyr OS build v3.7.0-8126-g33bc8a018ecc ***
Setup called
before Ram begin
GPIOA(0x58020000) ABEBBBAA B0A0ABB8 00000770
GPIOB(0x58020400) FAAFAABA 44A000AA 00aaaa00
GPIOC(0x58020800) FFFFFAAA 00BB55BA 00000000
GPIOD(0x58020c00) FABFFFFF 00000000 00999000
GPIOE(0x58021000) FFFFFFFF 00000000 00000000
GPIOF(0x58021400) FFEFBFFF 90000000 00000900
GPIOG(0x58021800) EABBEFFF 0A000000 07bbb070
GPIOH(0x58021c00) FEBEBEF7 400A0000 00044004
GPIOI(0x58022000) FFB8FFFB 00000050 0000a080
GPIOJ(0x58022400) 7FFFFD5F 00000000 00000000
GPIOK(0x58022800) FFFF5FFC 00000000 00000000
[00:00:01.303,000] <err> os: ***** BUS FAULT *****
[00:00:01.311,000] <err> os:   Imprecise data bus error
[00:00:01.319,000] <err> os: r0/a1:  0xc0000000  r1/a2:  0x24030ea0  r2/a3:  0x007ffff4
[00:00:01.330,000] <err> os: r3/a4:  0xc0000000 r12/ip:  0x00000000 r14/lr:  0x2403328d
[00:00:01.341,000] <err> os:  xpsr:  0x21000000
[00:00:01.348,000] <err> os: s[ 0]:  0x0806b4af  s[ 1]:  0x24033885  s[ 2]:  0x240335cd  s[ 3]:  0x00000000
[00:00:01.361,000] <err> os: s[ 4]:  0x00000010  s[ 5]:  0x00000000  s[ 6]:  0x00000000  s[ 7]:  0x0806ba85
[00:00:01.373,000] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x24032200  s[11]:  0x2403057c
[00:00:01.386,000] <err> os: s[12]:  0x0806b4af  s[13]:  0x0806b4bf  s[14]:  0x24032200  s[15]:  0x2403057c
[00:00:01.398,000] <err> os: fpscr:  0x58022800
[00:00:01.406,000] <err> os: Faulting instruction address (r15/pc): 0x24033030
[00:00:01.416,000] <err> os: >>> ZEPHYR FATAL ERROR 26: Unknown error on CPU 0
[00:00:01.426,000] <err> os: Current thread: 0x240031f8 (main)
[00:00:01.435,000] <err> os: Halting system

I know that the SDRam is under the FMC, And for example I know it includes these pins:

<style> </style>
  PF_00 SDRAM_A0 PF0 - - - - I2C2_SDA - - - - - - - FMC_A0
  PF_01 SDRAM_A1 PF1 - - - - I2C2_SCL - - - - - - - FMC_A1
  PF_02 SDRAM_A2 PF2 - - - - I2C2_SMBA - - - - - - - FMC_A2
  PF_03 SDRAM_A3 PF3 - - - - - - - - - - - - FMC_A3
  PF_04 SDRAM_A4 PF4 - - - - - - - - - - - - FMC_A4
  PF_05 SDRAM_A5 PF5 - - - - - - - - - - - - FMC_A5
Where the FMC is AF12 in this case. And GPIOF we have: GPIOF(0x58021400) FFEFBFFF 90000000 00000900 Where the MODEF for pins PF0_5 are showing that these pins are still in ANALOG mode (3) with two bits per pin.

Now if I run the same sketch on GIGA I see:
Before Ram begin

GPIOA AABAAFA7 2D001100 AA07B
GPIOB FFBAAEBF 76025000 4022
GPIOC FFFFBFFF 70000000 0
GPIOD AAAAA9FA 577000CC CC299CCC
GPIOE AAAABF6A C00009CC CCCCCCCC
GPIOF AAAAAAAA 79CCCCCC CCCCC977
GPIOG AFBAEAEA ACC0CCC C700D05C
GPIOH EAAAEAAF 2C4CC00 D84DDDD
GPIOI FDFBAAFF DDDD0000 80
GPIOJ F7AAFFFF 0 1313
GPIOK FFFFFFFB 10 0
After Ram begin
After malloc begin

Again same pins used on GIGA for FMC. and if we again look at GPIOF: MODER
We have: GPIOF AAAAAAAA So The last 3 nibbles: A 1010 so these 6 pins are mode 2: which is Alternate function.
If we Look ath the print for AFR[0], bottom 6 nibbles: 79CCCCCC They are all C (12), which matches the FMC AF12

I am still trying to figure out where in the code, is something called that initializes the SDRAM FMC/SDRam hardware:
(SDRAM1).

Wondering if/where there might be an SYS_INIT(...) function that initializes it.
The one place I see a sys init that mentiones SDRAM1 is in our loader\fixups.c
But that is onlye if: CONFIG_SHARED_MULTI_HEAP

int smh_init(void)
{
    int ret = 0;
    ret = shared_multi_heap_pool_init();
    if (ret != 0) {
        return ret;
    }

    const struct memory_region_t regions[] = {
        DT_FOREACH_STATUS_OKAY(zephyr_memory_region, _BUILD_MEM_REGION)
    };

    for (size_t i=0; i<ARRAY_SIZE(regions); i++) {
        if (!strncmp("SDRAM", regions[i].dt_name, 5)) {
            struct shared_multi_heap_region smh_sdram = {
                .addr = regions[i].dt_addr,
                .size = regions[i].dt_size,
                .attr = SMH_REG_ATTR_EXTERNAL,
            };
            ret = shared_multi_heap_add(&smh_sdram, NULL);
            if (ret != 0) {
                return ret;
            }
        }
    }
	return 0;
}

SYS_INIT(smh_init, POST_KERNEL, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY);

But it looks like it excludes doing anything with the region name starts with SDRAM.

Question is, what is different here versus GIGA.

Don't know if this is related or not, think probably not, but there are Warning messages for Quadspi, as part of this
build:

-- Found BOARD.dts: /home/kurte/git/zephyr/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7.dts
-- Found devicetree overlay: /home/kurte/git/zephyr/boards/arduino/portenta_h7/arduino_portenta_h7_stm32h747xx_m7_1_0_0.overlay
-- Found devicetree overlay: /home/kurte/git/ArduinoCore-zephyr/loader/boards/arduino_portenta_h7_m7.overlay
unit address and first address in 'reg' (0xe0000) don't match for /soc/flash-controller@52002000/flash@8000000/partitions/partition@0
-- Generated zephyr.dts: /home/kurte/git/ArduinoCore-zephyr/build/zephyr/zephyr.dts
-- Generated pickled edt: /home/kurte/git/ArduinoCore-zephyr/build/zephyr/edt.pickle
-- Generated zephyr.dts: /home/kurte/git/ArduinoCore-zephyr/build/zephyr/zephyr.dts
-- Generated devicetree_generated.h: /home/kurte/git/ArduinoCore-zephyr/build/zephyr/include/generated/zephyr/devicetree_generated.h
-- Including generated dts.cmake file: /home/kurte/git/ArduinoCore-zephyr/build/zephyr/dts.cmake
CMake Warning at /home/kurte/git/zephyr/cmake/modules/dts.cmake:426 (message):
  dtc raised one or more warnings:

  /home/kurte/git/ArduinoCore-zephyr/build/zephyr/zephyr.dts:1435.29-1467.5:
  Warning (spi_bus_bridge): /soc/quadspi@52005000: node name for SPI buses
  should be 'spi'

  <stdout>: Warning (spi_bus_reg): Failed prerequisite 'spi_bus_bridge'

Call Stack (most recent call first):
  /home/kurte/git/zephyr/cmake/modules/zephyr_default.cmake:133 (include)
  /home/kurte/git/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
  /home/kurte/git/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
  CMakeLists.txt:7 (find_package)

But maybe that flash message about not matching?

KurtE added a commit to KurtE/ArduinoCore-zephyr that referenced this issue Feb 12, 2025
resolves: arduino#74

needed to add: CONFIG_MEMC=y
to have the SDRAM enabled and as such not fault if you do anything with the SDRAM library.
Also enabled CONFIG_DMA=y
As not sure if that was needed but is in the GIGA .conf file
@KurtE
Copy link

KurtE commented Feb 12, 2025

Resolved down to needing:

CONFIG_DMA=y
CONFIG_MEMC=y

In the Portenta .conf file

Pushed it up into the changes in my PR: #71

KurtE added a commit to KurtE/ArduinoCore-zephyr that referenced this issue Feb 12, 2025
resolves: arduino#74

needed to add: CONFIG_MEMC=y
to have the SDRAM enabled and as such not fault if you do anything with the SDRAM library.
Also enabled CONFIG_DMA=y
As not sure if that was needed but is in the GIGA .conf file

Update arduino_portenta_h7_m7.overlay

Add dma sections to remove the build warnings
KurtE added a commit to KurtE/ArduinoCore-zephyr that referenced this issue Mar 6, 2025
resolves: arduino#74

needed to add: CONFIG_MEMC=y
to have the SDRAM enabled and as such not fault if you do anything with the SDRAM library.
Also enabled CONFIG_DMA=y
As not sure if that was needed but is in the GIGA .conf file

Update arduino_portenta_h7_m7.overlay

Add dma sections to remove the build warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants