Hi,

I have a few questions about the PRU usage of Bela.

I understand that the Bela program (the code that you write using the IDE) is executed on the PRU. I guess it is executed directly in the context of the interrupt handler for the audio codec. Is that correct?

How many of the two PRUs are used by Bela? Both? Is it possible (or practical) to restrict Bela to one of the PRUs to run custom code on the other one?

Is it practical at all to run custom code on the PRUs while Bela is running?

Tasks created by Bela_createAuxiliaryTask -- where are they run? They must be on the PRUs, but are they on any single one in particular? Or are all PRU tasks (including audio) scheduled on both PRUs somehow?

Where can I find more information about these things?

A separate, but related question: I'd like to drive a WS2812B string with a moderate amount of RGB LEDs (around 150) using Bela. Is there a good way to do this without external hardware? Has anybody done it? I know SPI can be abused to "emulate" the WS2812B protocol, but the SPI pin seems to be allocated for other things.

    The code you write in the IDE is not run on the PRUs.

    whatever312 I understand that the Bela program (the code that you write using the IDE) is executed on the PRU. I guess it is executed directly in the context of the interrupt handler for the audio codec. Is that correct?

    No. The PRU performs only the I/O from and to the audio ADC and DAC (over I2S), the analog ADC and DAC (over SPI), the digital I/O (these are just GPIOs of the SoC). All the I/O operations on the PRU are timed by the audio clock. The data are transmitted from ARM to PRU and from PRU to ARM by using a shared memory buffer. The PRU signals an RTDM driver (Real-time device model, a Xenomai-compliant real-time driver) that runs on ARM, when a buffer is ready. The C++ code you write in the IDE runs in user-space on the ARM CPU within a Xenomai thread. This thread blocks on a read() to the RTDM driver, and after the read() returns (with 0 bytes being copied), it copies the memory from the PRU RAM to the ARM RAM, processes the data, and copies the results back from the ARM RAM to the PRU RAM, and blocks again on a read() call, and the loop continues.

    whatever312 How many of the two PRUs are used by Bela? Both? Is it possible (or practical) to restrict Bela to one of the PRUs to run custom code on the other one?

    Bela runs only on one PRU. This can be either PRU 0 or PRU 1. It defaults to PRU1, and if you want to use the multiplexer capelet, you have to use PRU1.

    whatever312 Is it practical at all to run custom code on the PRUs while Bela is running?

    It is. We actually ship an example that runs a second PRU alongside the one running Bela.
    In another application, I bitbang an SPI protocol on the PRU in order to get an extra SPI bus. Someone very recently wrote a firmware for the second PRU in order to bitbang the I2S protocol.

    whatever312 Tasks created by Bela_createAuxiliaryTask -- where are they run? They must be on the PRUs, but are they on any single one in particular? Or are all PRU tasks (including audio) scheduled on both PRUs somehow?

    They run on ARM, just like all the C++ code (or PureData, or Supercollider, or CSound: everything except the PRU firmware used or Bela I/Os and any PRU-specific code you may want to write to run on the other PRU). These are Xenomai threads, that therefore can run with a similar level of real-time guarantees as the audio thread: they can run at higher priority than the rest of the operating system, but - given how there is only one CPU - they will have to compete for CPU time with the audio thread. You could in principle set them at higher priority than the audio, but for most application they are set to be lower priority than the audio thread.

    The PRU is a 200MHz RISC microcontroller, that can only do basic integer arithmetic operations. It does not have a hardware multiplier and it does not have floating point operations. It is really not suitable for doing any DSP, so it wouldn't be able to run the user code, even if we wanted to. We program the PRU in PRU assembly. I know there are some other tools out there that allow you to use higher-level languages (including C) to write your PRU code, but I am not familiar with those.

    whatever312 A separate, but related question: I'd like to drive a WS2812B string with a moderate amount of RGB LEDs (around 150) using Bela. Is there a good way to do this without external hardware? Has anybody done it? I know SPI can be abused to "emulate" the WS2812B protocol, but the SPI pin seems to be allocated for other things.

    On Bela, one SPI bus is used by the analog ADC and DAC, and some other pins that could provide access to the other SPI bus are used by the I2S (audio) bus. There is no other hardware SPI bus available there. Linux soft-SPI is available for low-bandwidth signals (e.g.: ~100kHz), or the link provide above allows soft-SPI in the 8MHz range (however that code is currently application-specific and would require some rework to work as a generic SPI driver).
    On BelaMini, there is one hardware SPI bus available, that you could use (up to speeds of 48MHz, I believe).

    I am not familiar with the WS2812B protocol, and I don't find the illustration on the datasheet very informative. However, i see that they are transmitting 800kbps, so it should be well within reach of the capabilities of the PRU.

      giuliomoro Thanks for that very detailed explanation! That was exactly the information I was looking for, it clears a lot of things up for me.