这是在mini6410上测试成功的,在没有驱动的情况下用程序直接控制了led灯test_mmap.c:
/* Example how to access the value of the on-board DIP switches on
* HiCO.SH7760. You can compile the program with command:
*
* sh4-linux-gcc -Wall dip_switch.c -o dip_switch
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
int main(void) {
int fd;
void *map_base, *virt_addr;
/* Physical address of the DIP switch GPIO register on HiCO.SH7760 (See
* the HiCO.SH7760 hardware manual
*
* _NOTE_: the dipswitches also define how the system boots (i.e. the value
* is used by the bootloader at startup), so oafter testting, leave the
* switches in the same position as they were */
off_t target = 0x7F008800; //GPKCON0 0x7F008800
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
printf("/dev/mem could not be opened.\n");
perror("open");
exit(1);
} else {
printf("/dev/mem opened.\n");
}
/* Map one page */
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
if(map_base == (void *) -1) {
printf("Memory map failed.\n");
perror("mmap");
} else {
printf("Memory mapped at address %p.\n", map_base);
}
virt_addr = map_base + (target & MAP_MASK);
/* acess remapped region here */
printf("Now try to change the value of the on-board DIP switche\n");
*(unsigned int *)virt_addr=0x11110000;//0x1111<<16;//设定为输出状态
int ab=*(unsigned int *)virt_addr;
//*(unsigned int *)(virt_addr+8)=0xffffffff;
printf("ab=%x\n",ab);
#if 1
while(1){
*(volatile unsigned int *)(virt_addr+8)=0x00; //一定要是virt_addr不能是map_base//置0亮
printf("1value is 0x%x\n",*(unsigned int *)(virt_addr+8));
printf("2value is 0x%x\n",*(unsigned int *)virt_addr);
sleep(1); //一定要有要不很快,人眼发现不了
*(volatile unsigned int *)(virt_addr+8)=0xf0; //置1灭
printf("3value is 0x%x\n",*(unsigned int *)(virt_addr+8));
printf("4value is 0x%x\n",*(unsigned int *)virt_addr);
sleep(1); //一定要有要不很快,人眼发现不了
}
#endif
/* we'll never get here in this example, but here's how the region is
* unmapped. */
if(munmap(map_base, MAP_SIZE) == -1) {
printf("Memory unmap failed.\n");
}
close(fd);
}
以上程序证明了在linux下用mmap函数可以在没有驱动的情况下也可以直接控制底层。
网上说只能控制gpio设备,我还可以直接控制其它设备,有待验证。