2016-09-19 49 views
0

我試圖通過寄存器設置訪問MT7620n的GPIO。到目前爲止,我可以通過使用/ sys/class/gpio/...來訪問它們,但這對我來說還不夠快。如何將mmap用於devmemon 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 

我有什麼照顧?我必須先讓內存訪問嗎?我以root身份運行。

感謝

編輯

彼得·科德斯是正確的,非常感謝你。

這是我最終的解決方案,如果有人發現了錯誤,請告訴我;)

#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的文件偏移參數必須是頁對齊的,並且對於mmap將失敗,並EINVAL的one of the documented reasons

0x10000600不是4k,甚至1k的倍數,所以這幾乎肯定是你的問題。我不認爲任何系統的頁面都小於512B。

mmap包含所需地址的整個頁面,並訪問該頁面內偏移處的MMIO寄存器。

要麼對它進行硬編碼,要麼可以做一些類似於GPIOCHIP_0_ADDDRESS & ~(page_size-1)的操作來將地址舍入到頁面對齊的邊界。你應該可以做一些將頁面大小作爲編譯時常量的東西,這樣它仍然可以高效編譯。

+0

不錯;)非常感謝 – user3000289