mmap直接操作底层,相当于驱动

来源:互联网 发布:淘宝店铺怎样上传视频 编辑:程序博客网 时间:2024/04/29 12:58

在2.6的内核中,上面个程序测试出错,下面个测试可用


1、http://www.codeforge.cn/read/99759/pxa270_gpio_led.c__html

pxa270_gpio_led.c in pxa270_gpio_led.rar

/*********************************************************copyright (C), 1999-2009, YILIDA Tech. Co., Ltd.File name: gpio.cAuthor: Owen  Version: 1.0     Date:09/12/2009Description:Others:Function List:1.2.History:1. Date:   Author:   Modification:*********************************************************/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/file.h>#define UINT unsigned int #define GPIO_BASE 0x40E00000#define GPIO  *(volatile UINT *)#define GPDR1_DIR 0x0010#define GPSR1_OUT 0x001C#define GPCR1_ZERO 0x0028 int main(int argc,char *argv[]){     int i;    int fd;    char *start;//open /dev/mem with read and write mode    fd = open ("/dev/mem", O_RDWR);    if (fd < 0)    {        printf("cannot open /dev/mem.");        return -1;    }    //map physical memory 0-10 bytes     start = (char *)mmap(0, 10, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);    GPIO(start + GPDR1_DIR) = (1 << 21);    while(1)    {        GPIO(start + GPSR1_OUT) = (1 << 21);        sleep(2);        GPIO(start + GPCR1_ZERO) = (1 << 21);        sleep(2);    }    munmap(start, 10); //destroy map memory    close(fd); //close file    return 0;}  ...


2、http://www.support.emtrion.de/doku.php?id=linux:how-to-access-gpio
how_to_access_gpio_ports_and_physical_memory_from_user-space

Normally all hardware access is done by a kernel driver. There are, however cases where you just need to change a value in some register without worrying buffering, interrupts etc. For example if you just need to access some GPIO ports to change a value of a led.

GPIO ports and physical memory need to be mapped into the user-space before they can be accessed. Following document discusses this and provides an example program devmem2

  • http://www.simtec.co.uk/appnotes/AN0014/

other examples:

  • http://wiki.gp2x.org/wiki/GPIO_Programming_Example

Here is an example how to read the on-board DIP switch value on HiCO.SH7760

/* 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 = 0xA40000A0;     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");    while(1){printf("value is 0x%02x\n",*(unsigned char *)virt_addr);sleep(1);    }     /* 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);}