1. 程式人生 > >【EmbeddedDev】通過mmap方法訪問ADC/GPIO

【EmbeddedDev】通過mmap方法訪問ADC/GPIO

正常通過檔案系統訪問AIN串列埠的值, 可以使用fread等檔案IO方式讀取/sys/bus/iio/devices/iio:device0/in_voltage*_raw的內容。

但是這樣在需要高頻獲取ADC值得情況就顯得效率很低下, 資料需要從磁碟拷貝到核心程序空間, 然後再拷貝到使用者程序空間, 消耗無謂的資源。

可以通過記憶體影射的方式來解決這個問題, mmap可以實現磁碟資料到使用者主存的一次資料拷貝, 從而達到使用者空間驅動的高效率。

在linux下可以檢視到/dev/mem這個檔案, 可以認為是實體記憶體的映象, 能用來訪問實體記憶體。

而在Beaglebone Black下可以通過訪問/dev/mem來訪問GPIO,ADC這些資料。mmap建立對映關係示例:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <sys/mman.h>
#include <fcntl.h>


#define MMAP_OFFSET (0x44C00000)
#define MMAP_SIZE   (0x481AEFFF-MMAP_OFFSET)
static volatile uint32_t *map;
static char mapped = FALSE;


int init_mmap()
{
    if(!mapped)
    {
        int fd;
        fd = open("/dev/mem", O_RDWR);
        if(fd == -1)
        {
            perror("Unable to open /dev/mem");
            exit(EXIT_FAILURE);
        }
        map = (uint32_t*)mmap(NULL, MMAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MMAP_OFFSET);
        if(map == MAP_FAILED)
        {
            close(fd);
            perror("Unable to map /dev/mem");
            exit(EXIT_FAILURE);
        }
        mapped = TRUE;
    }
    return mapped;
}