Problems passing arguments to lib bcm2835

36 views
Skip to first unread message

Nigel Johnson

unread,
Jun 18, 2024, 1:13:04 PM6/18/24
to bcm2835
I hate to bug people with my problems, but I have wracked my brains around this for several days. I'm sure I am missing something that somebody else will pick up easily! Any help appreciated.

I have successfully used lib bcm2835 before to turn on a relay, which opens a garage door, and the code I am using is a copy of that code, which I needed to modify for ten GPIO outputs rather than just one. Naturally I have done apt-get update and apt-get upgrade.

I am using a Pi model B V2.0, same as the one I was using on the system that is working with one relay. Pinout gives:

Revision : 000e SoC : BCM2835 RAM : 512MB Storage : SD USB ports : 2 (of which 0 USB3) Ethernet ports : 1 (100Mbps max. speed) Wi-fi : False Bluetooth : False Camera ports (CSI) : 1 Display ports (DSI): 1

#include <bcm2835.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h> #define _POSIX_SOURCE 1 /* POSIX compliant source */ //#define PN RPI_V2_GPIO_P1_19 void pulse (void); char debug =0; char Assigns[10][70]; void init(void); char Pins[10][18]; char* PinsPtr=Pins[0]; char PN; int main(int argc, char* argv[]) { init(); bcm2835_init(); for (int i=0;i<10;i++) { strncpy(&PN,&PinsPtr[i*18],17); printf("Pin = %s\n\r",&PN); bcm2835_gpio_fsel(PN,BCM2835_GPIO_FSEL_OUTP); // bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19,BCM2835_GPIO_FSEL_OUTP); } pulse(); } void pulse(void) { for (int i=0;i<10;i++) { strncpy(&PN,&PinsPtr[i*18],17); printf("PN=%s\n\r",&PN); bcm2835_gpio_write(PN, LOW); // bcm2835_gpio_write(RPI_V2_GPIO_P1_19,LOW); sleep(1); bcm2835_gpio_write(PN, HIGH); sleep(1); // bcm2835_gpio_write(RPI_V2_GPIO_P1_19,HIGH); } } void init(void) { strcpy(Assigns[0],"GPIO02 on P1-3 using RLA1-1 driving CAT5A-BLU for Pi-Star"); strcpy(Assigns[1],"GPIO03 on P1-5 using RLA1-2 driving CAT5A-ORG for Pi-Quisk"); strcpy(Assigns[2],"GPIO04 on P1-7 using RLA1-3 driving CAT5A-GRN for Pi-Marine"); strcpy(Assigns[3],"GPIO17 on P1-11 using RLA1-4 driving CAT5A-BRN for Pi-APRS"); strcpy(Assigns[4],"GPIO27 on P1-13 using RLA2-1 driving CAT5A-BLU for Pi-LiveATC"); strcpy(Assigns[5],"GPIO22 on P1-16 using RLA2-2 driving CAT5A-ORG for Spare"); strcpy(Assigns[6],"GPIO10 on P1-19 using RLA2-3 driving CAT5A-GRN for Pi-Boil-Mon"); strcpy(Assigns[7],"GPIO09 on P1-21 using RLA2-4 driving CAT5A-BRN for Pi-Aware"); strcpy(Assigns[8],"GPIO11 on P1-8 using SSR-1 driving GRN-BLK for IC900"); strcpy(Assigns[9],"GPIO14 on P1-23 using SSR-2 driving WHI-BLK for TK981"); strcpy(Pins[0],"RPI_V2_GPIO_P1_03"); strcpy(Pins[1],"RPI_V2_GPIO_P1_05"); strcpy(Pins[2],"RPI_V2_GPIO_P1_07"); strcpy(Pins[3],"RPI_V2_GPIO_P1_11"); strcpy(Pins[4],"RPI_V2_GPIO_P1_13"); strcpy(Pins[5],"RPI_V2_GPIO_P1_16"); strcpy(Pins[6],"RPI_V2_GPIO_P1_19"); strcpy(Pins[7],"RPI_V2_GPIO_P1_21"); strcpy(Pins[8],"RPI_V2_GPIO_P1_08"); strcpy(Pins[9],"RPI_V2_GPIO_P1_23"); }


If I embed the full name of the I/O pin, e.g.

bcm2835_gpio_fsel(RPI_V2_GPIO_P1_19,BCM2835_GPIO_FSEL_OUTP);
then
bcm2835_gpio_write(RPI_V2_GPIO_P1_19,LOW);
sleep(1);
bcm2835_gpio_write(PN, HIGH);
bcm2835_gpio_write(RPI_V2_GPIO_P1_19,HIGH);


For the init and actual I/O, it works fine. Relay on the pin clicks. But if I load it using a variable from a table (one of the ten pins, un-commented in code) it gives me a diagnostic from lib BCM2835 with an address which is outside the published range:

PN=RPI_V2_GPIO_P1_03
bcm2835_peri_write paddr 0xb5040030, value 00040000
bcm2835_peri_write paddr 0xb5040024, value 00040000
bcm2835_peri_write paddr 0xb504001c, value 00000400

I put in the printf to show what the value is being passed.

NOW, if I use the full name of the pin, but leave the printf uncommented, it fails again, even though I can't see how the printf could change the access to the peripheral!

So my thoughts are that I am messing up memory somewhere!

I tried running it through gdb, but after 3 single-steps I am getting 'file not found' under /proc/device-tree/soc/ranges, which I understand may be that gdb doesn't know how to handle the dynamic location there, so maybe not an error.

Any help really appreciated! I'd hate to duplicate code for each relay individually, but it is looking like that may be my only hope!

cheers,
Nigel Johnson

mike james

unread,
Jun 18, 2024, 1:31:39 PM6/18/24
to bcm2835
The names are not strings and not variables - they are symbols resolved by the macro processor.
They resolve to an integer - you are passing a string to 
void bcm2835_gpio_fsel (uint8_t pin, uint8_t mode)
as the pin parameter - its a unsigned byte. Work out what the integer pin numbers are and store them in an array.
mikej
Reply all
Reply to author
Forward
0 new messages