上次是用文件方式操作io,这次换成了设备地址映射到虚拟地址,操作虚拟地址来操作io。但是这两种方式驱动oled都非常慢,有很明显的扫描感。不知道大家用什么方式操作f1c100s的io,理论上不应该这么慢的。
https://github.com/kekemuyu/f1c100s/tree/master/oled_spi
mmap部分代码:
#include"devmem.h"
int tempfd;
void Openfile(){
if((tempfd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
}
void Closefile(){
close(tempfd);
}
void Writebit(long target,int bitsize ,char value){
void *map_base, *virt_addr;
unsigned long read_result, writeval;
int fd;
fd = fcntl(tempfd, F_DUPFD, 0);
if(fd<0){
FATAL;
}
// if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) FATAL;
// printf("/dev/mem opened.\n");
// fflush(stdout);
/* Map one page */
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target & ~MAP_MASK);
if(map_base == (void *) -1) FATAL;
// printf("Memory mapped at address %p.\n", map_base);
// fflush(stdout);
virt_addr = map_base + (target & MAP_MASK);
read_result = *((unsigned long *) virt_addr);
// printf("Value at address 0x%X (%p): 0x%X\n", target, virt_addr, read_result);
// fflush(stdout);
// printf("bitsize:%d;value:%d\n",bitsize,value);
if(value==0){
read_result&=~(1<<bitsize);
}else{
read_result|=1<<bitsize;
}
writeval=read_result;
*((unsigned long *) virt_addr)=writeval;
read_result=*((unsigned long *) virt_addr);
// printf("Written 0x%X; readback 0x%X\n", writeval, read_result);
// fflush(stdout);
if(munmap(map_base, MAP_SIZE) == -1) FATAL;
close(fd);
}
最近编辑记录 kekemuyu (2020-04-06 22:16:16)
离线
这个相当于 devmem 命令吧?
对,我就是拿devmem代码改的,其实就是用了两个函数mmap和munmap
最近编辑记录 kekemuyu (2020-04-06 22:18:38)
离线
还用了纯c语言的mmap方式,速度稍微有点提升,但还是有扫描感。难道linux上操作gpio真么慢
离线
刚刚咨询一位大佬:
这个速度本来就慢,
几十kHz,
内核与用户的数据同步毫秒级。
就是说linux不适合干用gpio直接驱动的事情,即使用mmap也一样。
哦,原来是这样。下一步的玩法是:
1:f1c100s硬件spi的4线方式
2. spi软件模式做成驱动集成到内核
3. 最终做成spi软硬件兼容的驱动集成到内核
通过这个小demo系统的学习一下linux的驱动开发
最近编辑记录 kekemuyu (2020-04-07 09:39:01)
离线