Opérations gpio de l’espace utilisateur Linux sous ARM utilisant l’approche mmap / dev / mem (capable d’écrire dans les registres GPIO, mais sans pouvoir les lire)

Version du kernel 3.12.30-AM335x-PD15.1.1 de PHYTEC.

Si j’utilise la méthode / sys / class / gpio, je peux voir que la valeur de la broche d’entrée du bouton (gpio103 de AM3359) passe de 0 à 1.

À la suite de cet exercice http://elinux.org/EBC_Exercise_11b_gpio_via_mmap et en exécutant la commande ci-dessous pour lire l’approche usp / dev / mem des gpio:

`devmem2 0x481ae13c` 

(base de la banque gpio 3 qui est 0x481ae000 + 0x13c offset de données)

Je reçois la sortie ci-dessous quelle que soit la position du bouton.

 /dev/mem opened Memory mapped at address 0xb6fd1000. Read at address 0x481AE13C (0xb6fd113c): 0x00000000 

Également avec le programme c donné ci-dessous, j’ai réussi à basculer gpios en utilisant / dev / mem; Cependant, je ne pouvais pas les lire avec succès.

dans le fichier d’en-tête:

 #define GPIO0_START_ADDRESS (0x44E07000) #define GPIO1_START_ADDRESS (0x4804C000) #define GPIO2_START_ADDRESS (0x481AC000) #define GPIO3_START_ADDRESS (0x481AE000) #define GPIO0_END_ADDRESS (0x44e09000) #define GPIO1_END_ADDRESS (0x4804E000) #define GPIO2_END_ADDRESS (0x481AE000) #define GPIO3_END_ADDRESS (0x481B0000) #define GPIO0_SIZE (GPIO0_END_ADDRESS - GPIO0_START_ADDRESS) #define GPIO1_SIZE (GPIO1_END_ADDRESS - GPIO1_START_ADDRESS) #define GPIO2_SIZE (GPIO2_END_ADDRESS - GPIO2_START_ADDRESS) #define GPIO3_SIZE (GPIO3_END_ADDRESS - GPIO3_START_ADDRESS) #define GPIO_SETDATAOUT (0x194) #define GPIO_CLEARDATAOUT (0x190) #define GPIO_DATAOUT (0x13c) 

quelque part dans le programme:

  int fd = open("/dev/mem", O_RDWR); //int fd = open("/dev/mem", O_RDWR|O_SYNC); gpio0_address = mmap(0, GPIO0_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO0_START_ADDRESS); gpio1_address = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_START_ADDRESS); gpio2_address = mmap(0, GPIO2_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO2_START_ADDRESS); gpio3_address = mmap(0, GPIO3_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO3_START_ADDRESS); if(gpio0_address == MAP_FAILED){ printf("unable to map GPIO0 bank.\n"); } if(gpio1_address == MAP_FAILED){ printf("unable to map GPIO1 bank.\n"); } if(gpio2_address == MAP_FAILED){ printf("unable to map GPIO2 bank.\n"); } if(gpio3_address == MAP_FAILED){ printf("unable to map GPIO3 bank.\n"); } gpio0_dataout_address = gpio0_address + GPIO_DATAOUT; gpio0_setdataout_address = gpio0_address + GPIO_SETDATAOUT; gpio0_cleardataout_address = gpio0_address + GPIO_CLEARDATAOUT; gpio1_dataout_address = gpio1_address + GPIO_DATAOUT; gpio1_setdataout_address = gpio1_address + GPIO_SETDATAOUT; gpio1_cleardataout_address = gpio1_address + GPIO_CLEARDATAOUT; gpio2_dataout_address = gpio2_address + GPIO_DATAOUT; gpio2_setdataout_address = gpio2_address + GPIO_SETDATAOUT; gpio2_cleardataout_address = gpio2_address + GPIO_CLEARDATAOUT; gpio3_dataout_address = gpio3_address + GPIO_DATAOUT; gpio3_setdataout_address = gpio3_address + GPIO_SETDATAOUT; gpio3_cleardataout_address = gpio3_address + GPIO_CLEARDATAOUT; read_GPIO_bank_memory(3, &GPIO3_bank_memory); 

fonction de lecture:

  void read_GPIO_bank_memory(int bank, four_bytes* gpio_bank_dataout) { switch(bank) { case 0: gpio_bank_dataout->ALL = *gpio0_dataout_address; break; case 1: gpio_bank_dataout->ALL = *gpio1_dataout_address; break; case 2: gpio_bank_dataout->ALL = *gpio2_dataout_address; break; case 3: gpio_bank_dataout->ALL = *gpio3_dataout_address; break; } } 

Vous devez utiliser GPIO_DATAIN Register (offset = 138h) pour lire l’épingle GPIO, pas GPIO_DATAOUT.