2016-09-19 2 views
0

레지스터 설정을 통해 MT7620n의 GPIO에 액세스하려고합니다. 지금까지 나는/sys/class/gpio /를 사용하여 그것들에 접근 할 수 있었다. 그러나 그것은 나를 위해 충분히 빠르지 않다.devmemon에 mmap을 사용하는 방법 MT7620n

MT7620 페이지 84의 프로그래밍 안내서에서 GPIO 기본 주소가 0x10000600이고 단일 레지스터의 오프셋이 4 바이트임을 알 수 있습니다. 같은

MT7620 Programming Guide

뭔가 : 쉘에서 devmem 0x10000600 절대적으로 잘 작동하지만 난 C의 programm에 내부에서 액세스 할 수 없습니다.

#define GPIOCHIP_0_ADDDRESS 0x10000600 // base address 
#define GPIO_BLOCK 4 

volatile unsigned long *gpiochip_0_Address; 
int gpioSetup() 
{ 
int m_mfd; 
if ((m_mfd = open("/dev/mem", O_RDWR)) < 0) 
{ 
    printf("ERROR open\n"); 
    return -1; 
} 
gpiochip_0_Address = (unsigned long*)mmap(NULL, GPIO_BLOCK, PROT_READ|PROT_WRITE, MAP_SHARED, m_mfd, GPIOCHIP_0_ADDDRESS); 

close(m_mfd); 

if(gpiochip_0_Address == MAP_FAILED) 
{ 
    printf("mmap() failed at phsical address:%d %s\n", GPIOCHIP_0_ADDDRESS, strerror(errno)); 
    return -2; 
} 

return 0; 
} 

내가 얻는 출력은 다음과 같습니다 :

mmap() failed at phsical address:268436992 Invalid argument 

은 내가 알아서해야합니까 여기

내 코드? 전에 메모리에 액세스 할 수있게해야합니까? 나는 루트 권한으로 실행 중이다.

감사

편집

피터 코르 맞아, 정말 감사합니다.

#define GPIOCHIP_0_ADDDRESS 0x10000600 // base address 

volatile unsigned long *gpiochip_0_Address; 
int gpioSetup() 
{ 
const size_t pagesize = sysconf(_SC_PAGE_SIZE); 
unsigned long gpiochip_pageAddress = GPIOCHIP_0_ADDDRESS & ~(pagesize-1); //get the closest page-sized-address 
const unsigned long gpiochip_0_offset = GPIOCHIP_0_ADDDRESS - gpiochip_pageAddress; //calculate the offset between the physical address and the page-sized-address 

int m_mfd; 
if ((m_mfd = open("/dev/mem", O_RDWR)) < 0) 
{ 
    printf("ERROR open\n"); 
    return -1; 
} 
page_virtual_start_Address = (unsigned long*)mmap(NULL, pagesize, PROT_READ|PROT_WRITE, MAP_SHARED, m_mfd, gpiochip_pageAddress); 


close(m_mfd); 

if(page_virtual_start_Address == MAP_FAILED) 
{ 
    printf("ERROR mmap\n"); 
    printf("mmap() failed at phsical address:%d %d\n", GPIOCHIP_0_ADDDRESS, strerror(errno)); 
    return -2; 
} 

gpiochip_0_Address = page_virtual_start_Address + (gpiochip_0_offset/sizeof(long)); 


return 0; 
} 

답변

1

mmap의 파일 오프셋 인수가 페이지 정렬되어야한다), 그리고 그 EINVAL와 함께 실패 할 mmap에 대한 one of the documented reasons이다, 누군가가 버그를 발견하면 여기

내 최종 솔루션은, 제발 말해있다 .

0x10000600은 4k 또는 1k의 배수가 아니기 때문에 거의 확실하게 문제가됩니다. 어떤 시스템에도 512B만큼 작은 페이지는 없다고 생각합니다.

mmap 원하는 주소가 포함 된 전체 페이지를 매핑하고 해당 페이지 내의 오프셋으로 MMIO 레지스터에 액세스하십시오.

주소를 페이지 정렬 경계로 반올림하기 위해 하드 코드하거나 GPIOCHIP_0_ADDDRESS & ~(page_size-1)과 같은 작업을 수행하십시오. 페이지 크기를 컴파일 타임 상수로 가져 와서 효율적으로 컴파일 할 수 있어야합니다.

+0

니스;) 감사합니다. – user3000289

관련 문제