【EmbeddedDev】通過mmap方法訪問ADC/GPIO
阿新 • • 發佈:2019-02-09
正常通過檔案系統訪問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; }