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

zephyr: The simple sample doesn't run on nucleo-h563zi #3252

Closed
lucasAbadFr opened this issue Mar 22, 2024 · 8 comments
Closed

zephyr: The simple sample doesn't run on nucleo-h563zi #3252

lucasAbadFr opened this issue Mar 22, 2024 · 8 comments
Labels
platform core/shared/platform

Comments

@lucasAbadFr
Copy link

Hello, I'm trying to build the product-mini/platforms/zephyr/simple example for the nucleo_h563zi board. But I'm unable to make it work. Any help is appreciated. Thanks.

I'm on Zephyr 3.6.0 even if it's currently unsupported by the WAMR, the simple example should work.

My build command is:

ZEPHYR_BASE=~/zephyrproject/zephyr west build .  -b nucleo_h563zi -p always -- -DWAMR_BUILD_TARGET=THUMBV8

I created a new board configuration for the nucleo_h563zi board. I used the nucleo_h563zi zephyr default board configuration as a reference:

# Default Zephyr config: 
# enable uart driver
CONFIG_SERIAL=y

# console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

# Enable clock
CONFIG_CLOCK_CONTROL=y

# Enable MPU
CONFIG_ARM_MPU=y

# Enable HW stack protection
CONFIG_HW_STACK_PROTECTION=y

# enable GPIO
CONFIG_GPIO=y
# enable pin controller
CONFIG_PINCTRL=y
  1. MPU error

    • Error output is:
    FAILED: #Skip long message
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c: In function 'disable_mpu_rasr_xn':
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c:28:16: error: 'MPU_Type' has no member named 'RASR'
    28 |         if (MPU->RASR & MPU_RASR_XN_Msk) {
        |                ^~
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c:28:25: error: 'MPU_RASR_XN_Msk' undeclared (first use in this function); did you mean 'MPU_RBAR_XN_Msk'?
    28 |         if (MPU->RASR & MPU_RASR_XN_Msk) {
        |                         ^~~~~~~~~~~~~~~
        |                         MPU_RBAR_XN_Msk
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c:28:25: note: each undeclared identifier is reported only once for each function it appears in
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c:29:16: error: 'MPU_Type' has no member named 'RASR'
    29 |             MPU->RASR |= ~MPU_RASR_XN_Msk;
        |                ^~
    /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c: In function 'os_icache_flush':
    • Work-around: In file core/shared/platform/zephyr/zephyr_platform.c, I temporarily changed the condition to use static void disable_mpu_rasr_xn(void).
      - #if WASM_ENABLE_AOT != 0
      + #if WASM_ENABLE_AOT != 0 && defined(CONFIG_CPU_CORTEX_M7)
  2. Linker error

    • function sys_cache_instr_flush_range:

      Error output is:

      /home/user/zephyr-sdk-0.16.5-1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(zephyr_platform.c.obj): in function `os_icache_flush':
      /home/user/wasm-micro-runtime/core/shared/platform/zephyr/zephyr_platform.c:227: undefined reference to `sys_cache_instr_flush_range'

      Work-around: In file core/shared/platform/zephyr/zephyr_platform.c, I added an include to zephyr/cache.h.

      #if KERNEL_VERSION_NUMBER >= 0x030300
      #include <zephyr/cache.h>
      #endif
    • function os_mremap:

      Error output is:

      /home/user/zephyr-sdk-0.16.5-1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(wasm_memory.c.obj): in function `wasm_mremap_linear_memory':
      /home/user/wasm-micro-runtime/core/iwasm/common/wasm_memory.c:659: undefined reference to `os_mremap'

      Work-around: In file core/shared/platform/zephyr/zephyr_platform.c, I added the implementation of os_mremap.

      void *
      os_mremap(void *old_addr, size_t old_size, size_t new_size){
          return os_mremap_slow(old_addr, old_size, new_size);
      }
    • function os_getpagesize

      Error output is:

      /home/user/zephyr-sdk-0.16.5-1/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: app/libapp.a(wasm_memory.c.obj): in function `wasm_allocate_linear_memory':
      /home/user/wasm-micro-runtime/core/iwasm/common/wasm_memory.c:927: undefined reference to `os_getpagesize'

      Work-around: In file core/shared/platform/zephyr/zephyr_platform.c, I added the implementation of os_getpagesize.

      // CONFIG_MMU_PAGE_SIZE: size of a memory page. Default is 4K
      unsigned 
      os_getpagesize() {
      #ifdef CONFIG_MMU
          return CONFIG_MMU_PAGE_SIZE;
      #else
          // Return a default page size if the MMU is not enabled
          return 4096; // 4KB
      #endif
      }
  3. wasm_runtime_full_init error:

    After fixing the above errors, I got the code to compile and link successfully. But when I run the code, I get the following error:

    [DEBUG]: WASM Main
    [DEBUG]: memset
    [DEBUG]: runtime init
    r:--- 159 messages dropped ---
     0x1458
    buf: 1234
    elapsed: 13

    📄 Notes: I used minicom to connect to the board and see the output. I added some prints to the code to see where it's failing. It seems to fail at the wasm_runtime_full_init function.

I'm not very familiar with the Cortex-M7 and Cortex-M33 architectures. I'm currently looking at the Cortex-M33 and Cortex-M7 documentations to see if there's anything that I'm missing. I think the issue might be related to the MPU configuration. I'll update this issue with my findings.

Any help will be appreciated. Thanks.

@mkolchurin
Copy link
Contributor

  1. I'm also tried to run the latest version and ran into the same problem with os_mremap os_mremap.
    And I tried to find workarounds, but it didn't work. But the release/1.3.x branch is working with my STM32H743
    It's happened after this

  2. if you see --- 159 messages dropped --- you can enable CONFIG_LOG_MODE_IMMEDIATE or CONFIG_LOG_MODE_MINIMAL to print the log synchronously

  3. about sys_cache_instr_flush_range. I forgot to add #if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU) in my commit .
    Something like this should solve the problem:

os_icache_flush(void *start, size_t len)
{
#if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU)
#if KERNEL_VERSION_NUMBER >= 0x030300 /* version 3.3.0 */
    sys_cache_instr_flush_range(start, len);
#endif
#endif
}

@wenyongh
Copy link
Contributor

  • Work-around: In file core/shared/platform/zephyr/zephyr_platform.c, I temporarily changed the condition to use static void disable_mpu_rasr_xn(void).
    - #if WASM_ENABLE_AOT != 0
    + #if WASM_ENABLE_AOT != 0 && defined(CONFIG_CPU_CORTEX_M7)

Is it better to use macro MPU_RASR_XN_Msk to control the code?

  1. about sys_cache_instr_flush_range. I forgot to add #if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU) in my commit .
    Something like this should solve the problem:
os_icache_flush(void *start, size_t len)
{
#if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU)
#if KERNEL_VERSION_NUMBER >= 0x030300 /* version 3.3.0 */
    sys_cache_instr_flush_range(start, len);
#endif
#endif
}

Is it better to include <zephyr/cache.h> when KERNEL_VERSION_NUMBER >= 0x030300? sys_cache_instr_flush_range is a static inline function and is always available when when KERNEL_VERSION_NUMBER >= 0x030300.

@lucasAbadFr, @mkolchurin thanks for reporting the issue and the discussion, I tried to upload the patch according to the comments, could you check whether it work?:

diff --git a/core/shared/platform/zephyr/platform_internal.h b/core/shared/platform/zephyr/platform_internal.h
index 00bb4956..3c0f5526 100644
--- a/core/shared/platform/zephyr/platform_internal.h
+++ b/core/shared/platform/zephyr/platform_internal.h
@@ -51,9 +51,7 @@
 #endif /* end of KERNEL_VERSION_NUMBER < 0x030200 */

 #if KERNEL_VERSION_NUMBER >= 0x030300 /* version 3.3.0 */
-#if defined(CONFIG_CPU_CORTEX_M7) && defined(CONFIG_ARM_MPU)
 #include <zephyr/cache.h>
-#endif
 #endif /* end of KERNEL_VERSION_NUMBER > 0x030300 */

 #ifdef CONFIG_ARM_MPU
@@ -177,4 +175,15 @@ os_get_invalid_handle()
     return -1;
 }

+static inline int
+os_getpagesize()
+{
+#ifdef CONFIG_MMU
+    return CONFIG_MMU_PAGE_SIZE;
+#else
+    /* Return a default page size if the MMU is not enabled */
+    return 4096; /* 4KB */
+#endif
+}
+
 #endif
diff --git a/core/shared/platform/zephyr/zephyr_platform.c b/core/shared/platform/zephyr/zephyr_platform.c
index 156ce537..fc54ba55 100644
--- a/core/shared/platform/zephyr/zephyr_platform.c
+++ b/core/shared/platform/zephyr/zephyr_platform.c
@@ -25,9 +25,11 @@ disable_mpu_rasr_xn(void)
        would most likely be set at index 2. */
     for (index = 0U; index < 8; index++) {
         MPU->RNR = index;
+#ifdef MPU_RASR_XN_Msk
         if (MPU->RASR & MPU_RASR_XN_Msk) {
             MPU->RASR |= ~MPU_RASR_XN_Msk;
         }
+#endif
     }
 }
 #endif /* end of CONFIG_ARM_MPU */
@@ -185,6 +187,12 @@ os_mmap(void *hint, size_t size, int prot, int flags, os_file_handle file)
         return BH_MALLOC(size);
 }

+void *
+os_mremap(void *old_addr, size_t old_size, size_t new_size)
+{
+    return os_mremap_slow(old_addr, old_size, new_size);
+}
+
 void
 os_munmap(void *addr, size_t size)
 {

@mkolchurin
Copy link
Contributor

mkolchurin commented Mar 25, 2024

@wenyongh it's works! Thanks
I had to rebuild wamrc, it looks like wamrc from 1.3.x is incompatible with the main branch and i got AOT module load failed: unexpect end

@wenyongh
Copy link
Contributor

@wenyongh it's works! Thanks I had to rebuild wamrc, it looks like wamrc from 1.3.x is incompatible with the main branch and i got AOT module load failed: unexpect end

The AOT ABI has changed after 1.3.x, see #3116. The aot runtime and wamrc must be consistent, please ensure both them are built from release/1.3.x, or both are built from main.

@wenyongh
Copy link
Contributor

#3255

@lucasAbadFr
Copy link
Author

Hello @wenyongh and @mkolchurin !
Thanks to both of you for the quick reply and tips.

Apologies for the oversight, I forgot to mention in my issue that I was working on the
main branch.

@wenyongh, after testing with your changes, I was able to make the simple example run without encontering any issues.

Output:

Hello world!
buf ptr: 0x1458
buf: 1234
elapsed: 29

Would it be appropriate to raise an issue on Zephyr's GitHub to seek assistance with implementing the following two functions:

  • os_getpagesize()
  • disable_mpu_rasr_xn(void)

The current functionality is effective with three or four boards (may be more), but its compatibility with all Zephyr's supported boards is uncertain. Addressing this may facilitate the implementation of WAMR as a Zephyr module, as suggested by your pull request.

I'm also quite interested in increasing zephyr plateform support, is there a guideline other than the contributing.md ?

@wenyongh
Copy link
Contributor

Hello @wenyongh and @mkolchurin ! Thanks to both of you for the quick reply and tips.

Apologies for the oversight, I forgot to mention in my issue that I was working on the main branch.

@wenyongh, after testing with your changes, I was able to make the simple example run without encontering any issues.

Output:

Hello world!
buf ptr: 0x1458
buf: 1234
elapsed: 29

OK, so let's merge the PR.

Would it be appropriate to raise an issue on Zephyr's GitHub to seek assistance with implementing the following two functions:

  • os_getpagesize()
  • disable_mpu_rasr_xn(void)

Here os_getpagesize is used in the code below:

page_size = os_getpagesize();
*memory_data_size = init_page_count * num_bytes_per_page;
bh_assert(*memory_data_size <= MAX_LINEAR_MEMORY_SIZE);
align_as_and_cast(*memory_data_size, page_size);

It is to ensure the size of memory mapped is multiple of the system page size, so mmap can allocate complete pages. I think it should not be an issue for zephyr since it uses malloc function. The last sentence should be *memory_data_size = align_as_and_cast(*memory_data_size, page_size), we will fix it soon.
I have no idea about disable_mpu_rasr_xn, maybe you can raise an issue in zephyr.

The current functionality is effective with three or four boards (may be more), but its compatibility with all Zephyr's supported boards is uncertain. Addressing this may facilitate the implementation of WAMR as a Zephyr module, as suggested by your pull request.

I'm also quite interested in increasing zephyr plateform support, is there a guideline other than the contributing.md ?

Yes, WAMR is an open community, it is highly appreciated that developer helps to contribute PRs.

wenyongh added a commit that referenced this issue Mar 26, 2024
@lucasAbadFr
Copy link
Author

I'm marking this issue as closed since the pull request has been merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
platform core/shared/platform
Projects
None yet
Development

No branches or pull requests

3 participants