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

在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.c
Author: Owen  Version: 1.0     Date:09/12/2009
Description:
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;
} 
 ...


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

other examples:

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);
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值