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

ipc: icmsg & icbmsg: Add support for the nrf5340bsim #78390

Merged
merged 8 commits into from
Sep 26, 2024

Conversation

aescolar
Copy link
Member

@aescolar aescolar commented Sep 13, 2024

Add support in these IPC backends for the nrf5340bsim.
And enable these backends samples/tests for this board so they are also runtime tested in CI.

Fixes #78099

The driver of this PR is that these IPC backends are configured from Device Tree at build time, with whatever hardcoded address is given on it.
But in the "native" (POSIX arch) targets (when we built for workstation testing) we cannot write to some hardcoded address. All addresses are determined at link time.
In this PR, we ifdef calls during the backend init to replace the hardcoded address with something which can be used in workstation testing. (And together with it, we need to conditionally remove the const in the structures which hold those pointers we modify at runtime).
The change does not have any effect for embedded targets.

This PR supersedes #78109. Unlike that PR, this replaces the pointers during init. As trying to replace them in the macros was not really possible in a generic way.

The PR contains:

  • 1 commit with a minor fix for a type that needs to be exposed always in icmsg_me.c a906eb7
  • A minor improvement in the pbuf interface, so icbmsg does not need to know the details on how to initialize the Rx pbuf by hand: 5ec172b
  • An update to the nRF HW models version
  • A commit, that for native (POSIX arch based) targets, adds a function to remap a hardcoded real device memory address into a corresponding address in the host simulated memory space.
  • The main change itself d6c8a5f , in which, during init we replace the hard pointer addresses which otherwise would come from DT, with whatever address is known to be good to be used for this simulated targets. (Just by calling the function from the previous commit). Note this change is conditional only for the POSIX arch targets.
  • And 3 commits enabling these IPC sample/test (multi_endpoint, icmsg, static_vrings) in the nrf5340bsim simulated target, so we have them runtime tested in CI also.

@zephyrbot zephyrbot added area: native port Host native arch port (native_sim) area: IPC Inter-Process Communication area: Samples Samples platform: nRF BSIM Nordic Semiconductors, nRF BabbleSim labels Sep 13, 2024
@zephyrbot
Copy link
Collaborator

zephyrbot commented Sep 13, 2024

The following west manifest projects have been modified in this Pull Request:

Name Old Revision New Revision Diff
nrf_hw_models zephyrproject-rtos/nrf_hw_models@d2a119a zephyrproject-rtos/nrf_hw_models@85944c6 zephyrproject-rtos/[email protected]

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@aescolar
Copy link
Member Author

CC @dchat-nordic @ilhanates

@aescolar aescolar force-pushed the 78099_fix_init branch 3 times, most recently from d266165 to 878a2a1 Compare September 14, 2024 06:38
@aescolar aescolar changed the title pc: icmsg & icbmsg: Add support for the nrf5340bsim ipc: icmsg & icbmsg: Add support for the nrf5340bsim Sep 17, 2024
@pdunaj
Copy link
Collaborator

pdunaj commented Sep 17, 2024

@maje-emb , please have a look.

Copy link
Collaborator

@pdunaj pdunaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am against doing it the way proposed. This is quite intrusive into ipc service with next to no value in itself. We will now need to track if the new posix related macros don't break compatibility and security of the ipc.

@aescolar, isn't it enough to remap buffers defined on dts level (i.e., entire memory passed to ipc service)? I expect you already tried this but I wonder why every pointer needs to be mapped separately.

blocking until we understand the impact

@pdunaj
Copy link
Collaborator

pdunaj commented Sep 17, 2024

If I understand correctly the problem comes from the fact that addresses passed in dts are from HW world and do not exist in virtual space mapping. If this is a problem then fixing address on configuration of buffers should be enough as all addresses used in ipc are calculated from it (offset from start).

I wonder if you could not simply mmap some memory into this specific range for the process running the simulation. If it is not used it should work. You could try to mmap a (ram based) file there. This could be done at this fake sim board initialization time and so nothing in the system would be aware that any mapping actually took place.

@pdunaj
Copy link
Collaborator

pdunaj commented Sep 17, 2024

something like that

#include <sys/mman.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>

int main(int argc, char *argv[])
{
        void *inaddr = (void*)(intptr_t)0x20000000;
        void *addr = mmap(inaddr, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

        printf("errno: %d, inaddr: %p, addr: %p\n", errno, inaddr, addr);

        return 0;
}
pdunaj@mystuff:~/work/tests/mmap$ gcc mmapme.c && ./a.out
errno: 0, inaddr: 0x20000000, addr: 0x20000000

@aescolar
Copy link
Member Author

If I understand correctly the problem comes from the fact that addresses passed in dts are from HW world

Yes, the problem is that addresses are indeed the HW addresses which come from DT.

I wonder if you could not simply mmap some memory into this specific range for the process..

A proof of concept of this can be seen here #78295. But unfortunately this direction is not tenable. It became immediately evident that ASan breaks with this approach. And it is likely that other libraries or tooling may also, if not now, some time in the future.

Another option which was tried was to change (at preprocessor time) the addresses when building for these simulated targets. So instead of using the DT provided address, we'd refer to a constant pointer known at link time. This is how it is done today for static vrings. Unfortunately given the amount of macrology around the initialization of icbmsg, this proved much worse than one could hope. Specially as the Tx and Rx buffers are crossed in each side of the channel. A quick trial can be seen here: #78109. Generalizing this to N MCUs with the current design would lead to way too many macros too difficult to maintain. (If instead of defining 2 buffers in DT, we'd define just one buffer, and a direction (so the buffer is used as two halves by the code at init), it would be easier).

I also considered offsetting the DT address (also at preprocessor time), offsetting 0x2000_0000 to a buffer whose address is known at link time, where that buffer represent the whole global memory. That solution would be ok for the nrf5340, but would easily became quite cumbersome if we have different processors using different common memories.

That's why I leaned for a solution which changes the configured addresses at runtime for simulated targets. Note there is no penalty for the embedded targets. Neither in executed code or memory layout (what is const remains const).

isn't it enough to remap buffers defined on dts level (i.e., entire memory passed to ipc service)? I expect you already tried this but I wonder why every pointer needs to be mapped separately.

We are just remapping the pointers set from DT macros. The macros that initialize the config structure are already pre-initializing all those pointers. Unfortunately there is not just 1 pointer set from DT, there is all of those to which the DT address propagates thru several layers of macros.

* Remap the pbuf memory pointers into something which can be used in the native simulated
* targets
*/
void pbuf_native_addr_remap(struct pbuf *pb);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe make this function more consistent, because right now calling it depends on few conditions. It is automatically called in init function, but if you not calling init then you have to call it directly. If CONFIG_ARCH_POSIX is enabled, you have to call it. Otherwise, you don't.

I suggest calling this function always before using pb. Even before pbuf_init. if CONFIG_ARCH_POSIX it can be empty static inline function. This will make it clearer when to use it and we avoid additional #ifs when calling it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please update the comment to be doxygen-compatible and add statement when it must be called.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for the review. I updated the PR content with what we just discussed on the phone.

ssize_t is not part of the C library ISO standard subset, and as such
one cannot expect a C library to expose the type by default.
Some libraries like glibc do not expose this type in general, and
trying to build using them results in build errors.

There is 3 possible options:
1. Continue using ssize_t and:
1.a define _POSIX_C_SOURCE before including any header
1.b include sys/types.h directly (A bit uglier)
3. Not use ssize_t, and instead rely on ISO standard types

Let's just go with 1.a assuming we want to keep using this type,
as that is the correct way of getting this type defined.

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Update the HW models module to:
85944c64f224406e4d781aa382c5f1f71ed307fd

Including the following:
* 5340: Allocate a buffer for the APP core RAM (2nd version)
* 82ca90c Add NCS test-spec.yml to trigger downstream CI job
* a05d7a6 docs: top README: Mention nrf54l15 support and minor fixes
* cd64524 54 ECB/CCM tests: Remove comment which does not apply

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Add a function which can be used to remap embedded device address,
into addresses which can be used in the simulated native boards.

For the nrf_bsim boards we provide an actual implementation.
For other boards, we provide an optional dummy version which does
nothing.
It is up to each board implementation to decide if they want to
provide one or use the dummy.

Signed-off-by: Alberto Escolar Piedras <[email protected]>
@aescolar aescolar force-pushed the 78099_fix_init branch 3 times, most recently from 326a3fa to 30208ca Compare September 18, 2024 10:19
Provide a new function for initializing the Rx side,
so users do not need to initialize the pointers by hand
if they did not use PBUF_DEFINE().

Let's also rename pbuf_init() to pbuf_tx_init() to clearly
signify the previous function was only meant to be used
by the Tx side.

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Add support in this IPC backends for POSIX arch targets in general,
and ensure the nrf5340bsim defines the buffer which will be used.

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Enable this sample for the nrf5340bsim

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Enable this sample for the nrf5340bsim

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Enable this sample for the nrf5340bsim

Signed-off-by: Alberto Escolar Piedras <[email protected]>
Copy link
Collaborator

@pdunaj pdunaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering the situation I see we will have to accept this changes. I think it would be best to find a long term solution hiding the simulator quirks into some porting layer. I understand however this cannot be done at this point and we need to go on.
Since Dominik is ok, I don't see a reason to nack it.

Copy link
Collaborator

@arnopo arnopo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a minor comment else LGTM

/* Initialize local copies of rx_pb. */
dev_data->rx_pb->data.wr_idx = 0;
dev_data->rx_pb->data.rd_idx = 0;
(void)pbuf_rx_init(dev_data->rx_pb);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you don't treat the error returned would be nice to have a comment explaining why

@nashif nashif merged commit 13efb39 into zephyrproject-rtos:main Sep 26, 2024
32 checks passed
@aescolar aescolar deleted the 78099_fix_init branch September 26, 2024 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: IPC Inter-Process Communication area: native port Host native arch port (native_sim) area: Samples Samples manifest manifest-nrf_hw_models platform: nRF BSIM Nordic Semiconductors, nRF BabbleSim
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Crash/segfault on all nrf5340 bsim simulations during IPC init
10 participants