参考:http://www.cubieforums.com/index.php?topic=253.10;wap2
代码如下:
1 /////////////////////////////////////////////////////////////////////////////// 2 #include <ctype.h> 3 #include <string.h> 4 #include <stdlib.h> 5 #include <stdio.h> 6 #include <math.h> 7 #include <time.h> 8 #include <signal.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <sys/mman.h> 13 #include <sys/select.h> 14 #include <pthread.h> 15 #include <unistd.h> 16 #include <sched.h> 17 #include <errno.h> 18 19 20 #define SW_PORTC_IO_BASE 0x01c20800 21 22 int main() { 23 unsigned int * pc; 24 int fd, i; 25 char * ptr; 26 unsigned int addr_start, addr_offset, PageSize, PageMask, data; 27 28 PageSize = sysconf(_SC_PAGESIZE); 29 PageMask = (~(PageSize-1)); 30 addr_start = SW_PORTC_IO_BASE & PageMask; 31 addr_offset = SW_PORTC_IO_BASE & ~PageMask; 32 33 fd = open("/dev/mem", O_RDWR); 34 if(fd < 0) { 35 perror("Unable to open /dev/mem"); 36 return(-1); 37 } 38 39 pc = mmap(0, PageSize*2, PROT_READ|PROT_WRITE, MAP_SHARED, fd, addr_start); 40 41 if(pc == MAP_FAILED) { 42 perror("Unable to mmap file"); 43 printf("pc:%lx ", (unsigned long)pc); 44 return(-1); 45 } 46 printf("PageSize:%8.8x PageMask:%8.8x addr_start:%8.8x addr_offset:%8.8x ",PageSize,PageMask,addr_start,addr_offset); 47 printf("pc:%8.8x ", *(unsigned int *)pc); 48 ptr = (char *)pc + addr_offset; 49 data = *(unsigned int *)(ptr+0x10c); 50 for(i=0;i<1000;i++){ 51 data |= 1<<21; //blue led 52 *(unsigned int *)(ptr+0x10c) = data; 53 usleep(100000); 54 data &= ~(1<<21); 55 *(unsigned int *)(ptr+0x10c) = data; 56 usleep(500000); 57 } 58 59 60 61 //debug 62 //printf("cfg2=0x%8.8x pul1=0x%8.8x drv1=0x%8.8x data=0x%8.8x ", *(unsigned int *)(ptr+0x104),*(unsigned int *)(ptr+0x11c),*(unsigned int *)(ptr+0x114),*(unsigned int *)(ptr+0x10c)); 63 close(fd); 64 return 0; 65 }
分析:
参照cubieboard开发板的用户手册,我们可以知道PIO的基地址是0x01c20800,但是mmap函数映射是以页为单位进行映射的,因此要做一个转换sysconf()函数就是得到系统页大小的,然后进行一系列的转换,然后通过mmap()函数来得到对应的io映射地址,然后进行操作。