joan2937 / pigpio

pigpio is a C library for the Raspberry which allows control of the General Purpose Input Outputs (GPIO).
The Unlicense
1.43k stars 403 forks source link

Pigpio BB Serial Read CPU Resource vs. RPI version #595

Open davthomaspilot opened 5 months ago

davthomaspilot commented 5 months ago

Not really an issue, but I don't know where to ask these questions...

I'm doing an RPI gadget Preferably with an RPI Zero W for smallest size and low power.

The gadget will be using the pigpio, bit bang, serial read function to monitor and read a serial data string. Maybe two inputs in parallel, if CPU resource is adequate.

The pigpio web page indicates that 10% CPU resource is used when the DMA sample rate is 5 microseconds.

1) Does the %CPU utilization depend on whether it's an RPI Zero, or RPI3, 4, 5? 2) Can two bit bang serial read operations (on two different inputs) be done simultaneously? 3) If answer to 2) is yes, does the CPU resource used double? 4) If an RPI Zero 2 is used, can a core be dedicated for doing the pigpio serial read? Or, is the resource "consumed" not in a CPU core? 5) What's a good source to dig deeper into how PIGPIO uses the BCM hardware to do the edge timestamping?

Thanks!

guymcswain commented 5 months ago

No problem.

  1. Does the %CPU utilization depend on whether it's an RPI Zero, or RPI3, 4, 5?

Judging from the dates these CPU measurements were taken I'd say they were all done on single core versions of the RPi. I would expect the %CPU to be about constant across the different models but the actual power consumed to be different. That is to say the power consumption on Zero will be less than on an RPI3 for example.

  1. Can two bit bang serial read operations (on two different inputs) be done simultaneously?

Yes. The DMA is timestamping all GPIO simultaneously.

  1. If answer to 2) is yes, does the CPU resource used double?

If you are reading small amounts of data, I would expect the increase in CPU utilization to be minimal. As mentioned above, the time stamping is done in DMA hardware, but the processing is done in a single CPU thread. The %CPU numbers you mention above refer to the idle overhead of this running thread. When enabled by the API there will be a call to a function that decodes the serial data and that additional %CPU will depend on the amount of data to process.

  1. If an RPI Zero 2 is used, can a core be dedicated for doing the pigpio serial read? Or, is the resource "consumed" not in a CPU core?

The library does nothing to influence the affinity of threads to CPU cores. This is all taken care of by the OS.

  1. What's a good source to dig deeper into how PIGPIO uses the BCM hardware to do the edge timestamping?

The author, who fairly regularly answers questions posted on the Raspberrypi.org forum. Oh, and the source code.

davthomaspilot commented 5 months ago

Thanks for the prompt reply!

The incoming serial data will typically have lots of edges. The serial data is provided by a radio receiver, and when the transmitter isn't sending, there's just noise.

Serial reads are done at approximately 1 second intervals. I hacked a version of the serial read function (see posts made here several years ago) to return an array of timestamps in addition to the received data. Data from the reads is ignored, until the time between edges exceeds one millisecond--that indicates the receiver is driving the serial pin with data, versus just flapping around.

So, the timestamping is running continuously, but the circular buffer only needs to be about four milliseconds to capture and entire message. (But, I don't think the circular buffer size impacts CPU utilization) .

Based on your reply, I think at least trying it on an RPI Zero W makes sense.

Thanks!

guymcswain commented 5 months ago

I hacked a version of the serial read function (see posts made here several years ago) to return an array of timestamps in addition to the received data.

Interesting. I was thinking if you had enough time during the preample that you could just use the callback api for edge events then switch to the bb serial read api. I once tried to do something similar but without serial data - just discerning code bits vs noise - and drove myself crazy trying to figure out a filter that would be somewhat general purpose. If you focus on one protocol then you should be fine. Good luck.

davthomaspilot commented 5 months ago

Well, it's strange. I'd want the callback when there is a period of no edges--again, normally there are lots of edges due to only noise being received.

The preamble is long period of marks. This isn't a standard protocol, but I have to interoperate with equipment using it that's been in the field for 20 plus years.

So, everything is ignored until there is a one millisecond period with no edges. That "preamble" (most protocols define preambles as 0101010..., not 1111111) indicates the following serial data should be read.

I'm all about figuring a better, interrupt driven way to do it. Hardware UARTs won't work, at least I can't figure out to do it. That 1 millisecond of 1's is actually 22 bit times--not even an integral number of bytes. And, the message (including the all 1's "preamble is repeated 70 times.

Anyway, it's not pretty, but it works.

Thanks!