I have been looking at the way the PPM RC inputs are parsed in RCInput_RPI (Copter_3.6.1). Here at my company we work on a custom board based on a Raspberry Pi 3 with a custom kernel. I have been getting a SIGSEGV here
*x = circle_buffer->get_virt_addr((ad + j)->dst) in RC_Input_RPI.cpp. I’m trying to debug it (I’m not expecting to debug in this topic but just trying to get a good understanding of the code, maybe the topic can be useful for other people using RPI). From gdb I could see that at some point
ad->dst is not valid (memory cannot be accessed at
Here is what I have understood from the way we use DMA to parse PPM (correct me if I’m wrong):
- We create an array of control block structures in a mapping between physical addresses and virtual addresses. The control blocks are linked and the last control block links to the first one, so the DMAC loops. They are setup so we read 56 times the GPIO values and then the timer value.
- The control blocks’ destination addresses (physical) are the addresses of a circular buffer which is mapped to virtual memory. That way, the values read by the DMAC are sent to the circular buffer directly.
- At each call of
_timer_tick, we get the address ad of the control block the DMAC is using. The destination
ad->dstcontained in this control block is the physical address in the
circle_bufferin which the GPIO value has been read. We then get the pointer
xto the virtual address corresponding to
ad->dst. From here, we parse the values of the
circle_bufferto decode PPM pulses.
However, I don’t really get why we are trying to get
ad-j. Are we trying different addresses in the vicinity of
ad here ? Why ?