Peterpion has asked for the wisdom of the Perl Monks concerning the following question:
Greetings monks.
I am trying to use peri_read and its associated peri functions in the module Device::BCM2835 and failing miserably. I hit seg faults with every slight use of the peri functions and I can't work out what I am doing wrong, to the point of suspecting a fault with the module or its installation.
First, briefly - why am I trying to use low level access? I need to toggle groups of bits on a raspberry pi GPIO interface at high audio frequencies and setting individual bits one by one in perl is proving too slow. I believe that if I write a whole byte to the register at once I will probably hit my speed requirements. I have got it all working fine in C, but I am doing something which needs rapid code modifications (as I modify the hardware) which perl suits far better hence my attempts here.
But the documentation for the Device::BCM2835 module is quite sparse regarding the 3 peri functions and there are no examples, which is probably why I can't 'get it'. Although there are no examples of people using these functions on the searchable web, and so I doubt anyone here will have played with them personally, I wonder if more experienced eyes cast over the docs will detect my mistake.
Essentially I am doing this:
$|=1; use Device::BCM2835; Device::BCM2835::init()|| die "Could not init library"; my @pins = (&Device::BCM2835::RPI_GPIO_P1_07, &Device::BCM2835::RPI_GPIO_P1_11,&Device::BCM2835::RPI_GPIO_P1_12, &Device::BCM2835::RPI_V2_GPIO_P1_13,&Device::BCM2835::RPI_GPIO_P1_15, &Device::BCM2835::RPI_GPIO_P1_16,&Device::BCM2835::RPI_GPIO_P1_18, &Device::BCM2835::RPI_GPIO_P1_22); Device::BCM2835::gpio_fsel($_, &Device::BCM2835::BCM2835_GPIO_FSEL_OUT +P) for @pins; Device::BCM2835::peri_write(&Device::BCM2835::BCM2835_PERI_BASE + 0x2 +00000, 0x1C); print "No seg fault!!\n";
I have tried various permutations (many) of the peri_write arguments but all have the same effect, which is immediate seg fault.
Perhaps I am mixing access methods, but it seems to me I need to set the hardware pin modes one way or another and using the higher level methods would seem to be fine, after all the regisers will remain in the state I set them to (using fsel).
The code works fine if I use Device::BCM2835::gpio_write instead of peri_write but that only sets a single bit at a time.
I suspect my address arguments to peri_write are wrong, but I have tried several different ones, using the constants as well as the actual physical addresses which the function apparently takes. I can't find the actual perl in the module which the various functions are defined in so I have not been able to really see what the function peri_write looks like. I suspect the peri_write function is just a wrapper round the C, but looking at the C function it seems it should take the physical numerical addresses I have tried. So I am at that unhappy point of not knowing what to try next, and hoping that a wise monk could point me in the right direction.
TIA, Pete
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Device::BCM2835, hardware access on a pi, SIGSEGV
by Anonymous Monk on Aug 25, 2014 at 12:02 UTC | |
by Peterpion (Acolyte) on Aug 25, 2014 at 13:00 UTC | |
Re: Device::BCM2835, hardware access on a pi, SIGSEGV
by hardburn (Abbot) on Aug 25, 2014 at 18:02 UTC | |
by Peterpion (Acolyte) on Aug 26, 2014 at 13:27 UTC | |
by hardburn (Abbot) on Aug 26, 2014 at 17:29 UTC | |
by Peterpion (Acolyte) on Aug 27, 2014 at 10:19 UTC | |
by afoken (Chancellor) on Aug 27, 2014 at 19:22 UTC | |
by hardburn (Abbot) on Aug 27, 2014 at 13:11 UTC | |
by hardburn (Abbot) on Aug 27, 2014 at 18:57 UTC |