xref: /aosp_15_r20/external/pigweed/pw_stream_shmem_mcuxpresso/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_stream_shmem_mcuxpresso:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker==========================
4*61c4878aSAndroid Build Coastguard Workerpw_stream_shmem_mcuxpresso
5*61c4878aSAndroid Build Coastguard Worker==========================
6*61c4878aSAndroid Build Coastguard Worker``pw_stream_shmem_mcuxpresso`` implements the ``pw_stream`` interface for
7*61c4878aSAndroid Build Coastguard Workerreading and writing between two different processor cores via shared memory
8*61c4878aSAndroid Build Coastguard Workerusing the NXP MCUXpresso SDK. It uses the messaging unit module (MU) to signal
9*61c4878aSAndroid Build Coastguard Workerdata readiness between cores.
10*61c4878aSAndroid Build Coastguard Worker
11*61c4878aSAndroid Build Coastguard WorkerSetup
12*61c4878aSAndroid Build Coastguard Worker=====
13*61c4878aSAndroid Build Coastguard WorkerThis module requires a little setup:
14*61c4878aSAndroid Build Coastguard Worker
15*61c4878aSAndroid Build Coastguard Worker1. Use ``pw_build_mcuxpresso`` to create a ``pw_source_set`` for an
16*61c4878aSAndroid Build Coastguard Worker   MCUXpresso SDK.
17*61c4878aSAndroid Build Coastguard Worker2. Include the debug console component in this SDK definition.
18*61c4878aSAndroid Build Coastguard Worker3. Specify the ``pw_third_party_mcuxpresso_SDK`` GN global variable to specify
19*61c4878aSAndroid Build Coastguard Worker   the name of this source set.
20*61c4878aSAndroid Build Coastguard Worker
21*61c4878aSAndroid Build Coastguard WorkerThe name of the SDK source set must be set in the
22*61c4878aSAndroid Build Coastguard Worker"pw_third_party_mcuxpresso_SDK" GN arg
23*61c4878aSAndroid Build Coastguard Worker
24*61c4878aSAndroid Build Coastguard WorkerUsage
25*61c4878aSAndroid Build Coastguard Worker=====
26*61c4878aSAndroid Build Coastguard Worker``ShmemMcuxpressoStream`` blocks on both reads and writes, as only one
27*61c4878aSAndroid Build Coastguard Workeroutstanding buffer can be transferred at a time in each direction. This means a
28*61c4878aSAndroid Build Coastguard Workerdedicated thread should be used for both reading and writing. A typical use case
29*61c4878aSAndroid Build Coastguard Workerfor this class would be as the underlying transport for a pw_rpc network between
30*61c4878aSAndroid Build Coastguard Workercores. Use with the ``pw::rpc::StreamRpcFrameSender`` and
31*61c4878aSAndroid Build Coastguard Worker``pw::rpc::StreamRpcDispatcher`` classes.
32*61c4878aSAndroid Build Coastguard Worker
33*61c4878aSAndroid Build Coastguard WorkerInterrupt handlers and shared buffers on both cores must be setup before using
34*61c4878aSAndroid Build Coastguard Workerthis stream. The shared buffer must be mapped as uncacheable on both sides.
35*61c4878aSAndroid Build Coastguard Worker
36*61c4878aSAndroid Build Coastguard WorkerAs an example on the RT595, we connect the M33 core to the FusionF1 DSP. On the
37*61c4878aSAndroid Build Coastguard WorkerFusionF1 side, the MU interrupt must be explicitly routed.
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard WorkerInitialization for the M33 Core:
40*61c4878aSAndroid Build Coastguard Worker
41*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard Worker   // `kSharedBuffer` is a pointer to memory that is shared between the M33 and
44*61c4878aSAndroid Build Coastguard Worker   // F1 cores, and it is at least `2 * kSharedBufferSize` in size.
45*61c4878aSAndroid Build Coastguard Worker   ByteSpan read_buffer = ByteSpan{kSharedBuffer, kSharedBufferSize};
46*61c4878aSAndroid Build Coastguard Worker   ByteSpan write_buffer = ByteSpan{kSharedBuffer + kSharedBufferSize, kSharedBufferSize};
47*61c4878aSAndroid Build Coastguard Worker   ShmemMcuxpressoStream stream{MUA, read_buffer, write_buffer};
48*61c4878aSAndroid Build Coastguard Worker
49*61c4878aSAndroid Build Coastguard Worker   PW_EXTERN_C void MU_A_DriverIRQHandler() {
50*61c4878aSAndroid Build Coastguard Worker     stream.HandleInterrupt();
51*61c4878aSAndroid Build Coastguard Worker   }
52*61c4878aSAndroid Build Coastguard Worker
53*61c4878aSAndroid Build Coastguard Worker   void Init() {
54*61c4878aSAndroid Build Coastguard Worker     return stream.Enable();
55*61c4878aSAndroid Build Coastguard Worker   }
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard WorkerInitialization for the FusionF1 Core:
58*61c4878aSAndroid Build Coastguard Worker
59*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
60*61c4878aSAndroid Build Coastguard Worker
61*61c4878aSAndroid Build Coastguard Worker   ByteSpan write_buffer = ByteSpan{kSharedBuffer, kSharedBufferSize};
62*61c4878aSAndroid Build Coastguard Worker   ByteSpan read_buffer = ByteSpan{kSharedBuffer + kSharedBufferSize, kSharedBufferSize};
63*61c4878aSAndroid Build Coastguard Worker   ShmemMcuxpressoStream stream{MUB, read_buffer, write_buffer};
64*61c4878aSAndroid Build Coastguard Worker
65*61c4878aSAndroid Build Coastguard Worker   PW_EXTERN_C void MU_B_IrqHandler(void*) {
66*61c4878aSAndroid Build Coastguard Worker     stream.HandleInterrupt();
67*61c4878aSAndroid Build Coastguard Worker   }
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker   void Init() {
70*61c4878aSAndroid Build Coastguard Worker    // Enables the clock for the Input Mux
71*61c4878aSAndroid Build Coastguard Worker    INPUTMUX_Init(INPUTMUX);
72*61c4878aSAndroid Build Coastguard Worker    // MUB interrupt signal is selected for DSP interrupt input 1
73*61c4878aSAndroid Build Coastguard Worker    INPUTMUX_AttachSignal(INPUTMUX, 1U, kINPUTMUX_MuBToDspInterrupt);
74*61c4878aSAndroid Build Coastguard Worker    // Disables the clock for the Input Mux to save power
75*61c4878aSAndroid Build Coastguard Worker    INPUTMUX_Deinit(INPUTMUX);
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Worker    xt_set_interrupt_handler(kMuBIrqNum, MU_B_IrqHandler, NULL);
78*61c4878aSAndroid Build Coastguard Worker    xt_interrupt_enable(kMuBIrqNum);
79*61c4878aSAndroid Build Coastguard Worker    stream.Enable();
80*61c4878aSAndroid Build Coastguard Worker   }
81*61c4878aSAndroid Build Coastguard Worker
82*61c4878aSAndroid Build Coastguard WorkerRead/Write example where each core has threads for reading and writing.
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard WorkerCore 0:
85*61c4878aSAndroid Build Coastguard Worker
86*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
87*61c4878aSAndroid Build Coastguard Worker
88*61c4878aSAndroid Build Coastguard Worker   constexpr std::byte kCore0Value = std::byte{0xab};
89*61c4878aSAndroid Build Coastguard Worker   constexpr std::byte kCore1Value = std::byte{0xcd};
90*61c4878aSAndroid Build Coastguard Worker
91*61c4878aSAndroid Build Coastguard Worker   void ReadThread() {
92*61c4878aSAndroid Build Coastguard Worker     while(true) {
93*61c4878aSAndroid Build Coastguard Worker       std::array<std::byte, 1> read = {};
94*61c4878aSAndroid Build Coastguard Worker       auto status = stream.Read(read);
95*61c4878aSAndroid Build Coastguard Worker       if (!status.ok() || status.size() != 1 || read[0] != kCore1Value) {
96*61c4878aSAndroid Build Coastguard Worker         PW_LOG_WARN("Incorrect value read from core1");
97*61c4878aSAndroid Build Coastguard Worker       }
98*61c4878aSAndroid Build Coastguard Worker     }
99*61c4878aSAndroid Build Coastguard Worker   }
100*61c4878aSAndroid Build Coastguard Worker
101*61c4878aSAndroid Build Coastguard Worker
102*61c4878aSAndroid Build Coastguard Worker   void WriteThread() {
103*61c4878aSAndroid Build Coastguard Worker     std::array<std::byte, 1> write = {kCore0Value};
104*61c4878aSAndroid Build Coastguard Worker     while(true) {
105*61c4878aSAndroid Build Coastguard Worker       stream.Write(write);
106*61c4878aSAndroid Build Coastguard Worker     }
107*61c4878aSAndroid Build Coastguard Worker   }
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard WorkerCore 1:
110*61c4878aSAndroid Build Coastguard Worker
111*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
112*61c4878aSAndroid Build Coastguard Worker
113*61c4878aSAndroid Build Coastguard Worker   void ReadThread() {
114*61c4878aSAndroid Build Coastguard Worker    while(true) {
115*61c4878aSAndroid Build Coastguard Worker      std::array<std::byte, 1> read = {};
116*61c4878aSAndroid Build Coastguard Worker      auto status = stream.Read(read);
117*61c4878aSAndroid Build Coastguard Worker      if (!status.ok() || status.size() != 1 || read[0] != kCore0Value) {
118*61c4878aSAndroid Build Coastguard Worker        PW_LOG_WARN("Incorrect value read from core0");
119*61c4878aSAndroid Build Coastguard Worker      }
120*61c4878aSAndroid Build Coastguard Worker    }
121*61c4878aSAndroid Build Coastguard Worker
122*61c4878aSAndroid Build Coastguard Worker  }
123*61c4878aSAndroid Build Coastguard Worker
124*61c4878aSAndroid Build Coastguard Worker  void WriteThread() {
125*61c4878aSAndroid Build Coastguard Worker    std::array<std::byte, 1> write = {kCore1Value};
126*61c4878aSAndroid Build Coastguard Worker    while(true) {
127*61c4878aSAndroid Build Coastguard Worker      stream.Write(write);
128*61c4878aSAndroid Build Coastguard Worker    }
129*61c4878aSAndroid Build Coastguard Worker  }
130