0

AtmelのArm99g20のGPIOピンにアクセスしようとしています。以下の私のコードは

、gpio = mmap(0、getpagesize()、PROT_READ | PROT_WRITE、MAP_SHARED、fd、0xFFFFF400);で失敗し続けます。//GPIOAの開始

誰かが私のコードを手伝ってくれて、このこぶを乗り越えるためのI / Oサンプルコードを少し提供してもらえますか?ありがとう。

// gpio.c
// compile arm-linux-gcc -o button button.c
//

#include<unistd.h>
#include<sys/types.h>
#include<sys/mman.h>
#include<stdio.h>
#include<fcntl.h>
#include<string.h>

// GPIO Registers
//http://www.atmel.com/dyn/resources/prod_documents/doc6384.pdf  - page 374
#define PIO_PER 0x0000 // PIO Enable Register  Write-only –
#define PIO_PDR 0x0004 // PIO Disable Register  Write-only –
#define PIO_PSR 0x0008 // PIO Status Register  Read-only
#define PIO_OER 0x0010 // Output Enable Register  Write-only –
#define PIO_ODR 0x0014 // Output Disable Register  Write-only –
#define PIO_OSR 0x0018 // Output Status Register  Read-only. reset 0x0000 0000
//0x001C Reserved
#define PIO_IFER 0x0020 // Glitch Input Filter Enable Register  Write-only –
#define PIO_IFDR 0x0024 // Glitch Input Filter Disable Register  Write-only –
#define PIO_IFSR 0x0028 // Glitch Input Filter Status Register  Read-only. Reset 0x0000 0000
//0x002C Reserved
#define PIO_SODR 0x0030 // Set Output Data Register  Write-only –
#define PIO_CODR 0x0034 // Clear Output Data Register  Write-only
#define PIO_ODSR 0x0038 // Output Data Status Register  Read-only or Read-write
#define PIO_PDSR 0x003C // Pin Data Status Register  Read-only
#define PIO_IER  0x0040 // Interrupt Enable Register  Write-only –
#define PIO_IDR 0x0044 // Interrupt Disable Register  Write-only –
#define PIO_IMR 0x0048 // Interrupt Mask Register Read-only. Reset 0x00000000
#define PIO_ISR 0x004C // Interrupt Status Register Read-only. Reset 0x00000000
#define PIO_MDER 0x0050 // Multi-driver Enable Register  Write-only –
#define PIO_MDDR 0x0054 // Multi-driver Disable Register  Write-only –
#define PIO_MDSR 0x0058 // Multi-driver Status Register  Read-only. Reset 0x00000000
//0x005C Reserved
#define PIO_PUDR 0x0060 // Pull-up Disable Register  Write-only –
#define PIO_PUER 0x0064 // Pull-up Enable Register  Write-only –
#define PIO_PUSR 0x0068 // Pad Pull-up Status Register
#define PIO_ASR 0x0070 // Peripheral A Select Register  Write-only –
#define PIO_BSR 0x0074 // Peripheral B Select Register  Write-only –
#define PIO_ABSR 0x0078 // AB Status Register  Read-only 0x00000000
//0x007C to 0x009C Reserved
#define PIO_OWER 0x00A0 // Output Write Enable  Write-only –
#define PIO_OWDR 0x00A4 // Output Write Disable  Write-only –
#define PIO_OWSR 0x00A8 // Output Write Status Register  Read-only 0x00000000


/*******************************************************************************************************
 *                                                  MAIN
 *******************************************************************************************************/
int main(int argc, char **argv) {
  volatile unsigned int *PADR, *PADDR, *PBDR, *PBDDR, *PCDR, *PCDDR;
  unsigned long *gpio;

  int fd = open("/dev/mem", O_RDWR|O_SYNC);
  if (fd < 0){
         fprintf(stderr, "Unable to open port\n\r");
         exit(fd);
     }

  gpio = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0xFFFFF400); // start of GPIOA

  if(gpio == (void *) -1) {
      printf("Memory map failed.\n");
      exit(0);
  } else {
      printf("Memory mapped at address %p.\n", gpio);
  }

  PADR = (unsigned int *)(gpio + 0x00);     // port a
  PADDR = (unsigned int *)(gpio + PIO_OER);    // port a output enable

  *PADDR = 0xff;    // make all output
  *PADR = 0xffff;   // turn All of A Off

  close(fd);
  return 0;
}
4

1 に答える 1

0

発生している障害の種類はわかりませんが(説明されていません)、GPIOポートとコメントを使用した操作は正しくありません。まず、レジスタPIO_PERはIOイネーブルレジスタであり、ビットを設定すると出力ではなくイネーブルになります。一方、PIO_OERは実際にそれらを出力させるためのものであり、すべてをオフにするためのものではありません。したがって、次の順序に従う必要があります。

// initializing
*(unsigned int *) (gpio + PIO_PER) = 0xff; // enable
*(unsigned int *) (gpio + PIO_OER) = 0xff; // set output

// working
...
*(unsigned int *) (gpio + PIO_SODR) = 0xff; // set 1's
...
*(unsigned int *) (gpio + PIO_CODR) = 0xff; // set 0's

アップデート

マップできるのはページ全体のみなので、次の点を考慮に入れる必要があります。

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
#define GPIOA_BASE 0xFFFFF400

...    
/* Map one page */
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIOA_BASE & & ~MAP_MASK);
...    
gpio = map_base + (GPIOA_BASE & MAP_MASK);
...

よく知られているdevmemツールのソースを確認してください:ここ

于 2011-11-07T20:16:26.947 に答える