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