starter 发表于 2012-12-3 14:49:17

下面是从网上找的mmap方式驱动LED代码,

本帖最后由 starter 于 2012-12-3 15:39 编辑

其中地址+24是我改的,原文+8
#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;
    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;//éè???aê?3?×?ì?
      int ab=*(unsigned int *)virt_addr;
      //*(unsigned int *)(virt_addr+8)=0xffffffff;
      printf("ab=%x\n",ab);
    while(1){
      *(volatile unsigned int *)(virt_addr+0x24)=0x00;      
//printf("1value is 0x%x\n",*(unsigned int *)(virt_addr+0x24));
      //printf("2value is 0x%x\n",*(unsigned int *)virt_addr);
      //sleep(1);      
      *(volatile unsigned int *)(virt_addr+0x24)=0xff;
      //printf("3value is 0x%x\n",*(unsigned int *)(virt_addr+0x24));
      //printf("4value is 0x%x\n",*(unsigned int *)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);
}
这个代码用4.3.2编译可以动作的,但是我把它mmap 以及驱动LED部分插到QtCreator程序中,编译也应当是4.3.2,运行就退出GUI,为何?

starter 发表于 2012-12-3 15:00:35

下面把重点地方抽出来,几乎一样的
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
    off_t target = 0x7F008800;        //GPKCON0 0x7F008800
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {

    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
    virt_addr = map_base + (target & MAP_MASK);
        *(unsigned int *)virt_addr=0x11110000;//0x1111<<16;//éè???aê?3?×?ì?
    while(1){
        *(volatile unsigned int *)(virt_addr+0x24)=0x00;       

        *(volatile unsigned int *)(virt_addr+0x24)=0xff;

    }
    close(fd);

}

          target= 0x7F008800;
                #define MAP_SIZE 4096UL
                #define MAP_MASK (MAP_SIZE - 1)
    fbb=open("/dev/mem",O_RDWR | O_SYNC);
    map_base =(long *)mmap(NULL,MAP_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fbb,target & ~MAP_MASK);
    virt_addr = map_base + (target & MAP_MASK);
    s1=QString::number((unsigned int)virt_addr);
    //s1=QString::number(errno);
    //s1=QString::number(fbb);
    ui->lineEdit_3->setText( s1 );
                while(1)
        {
    *(volatile unsigned int *)(virt_addr+0x24)=0x00;
    *(volatile unsigned int *)(virt_addr+0x24)=0xff;

        }

starter 发表于 2012-12-4 16:21:30

搞定了,char *指针和long *指针搞错了,地址错了.另外搞定了mmap控制SPI,效率真是高,本来write方式控制SPI,代码后有个IO翻转,44us后SPI才出数据,mmap映射后直接操作1us后SPI数据就出来了
页: [1]
查看完整版本: 下面是从网上找的mmap方式驱动LED代码,