FireBrain 发表于 2020-4-7 08:46:44

go语言开发f1c100s之oled驱动mmap版

上次是用文件方式操作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(longtarget,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);
}

FireBrain 发表于 2020-4-7 08:48:52

还用了纯c语言的mmap方式,速度稍微有点提升,但还是有扫描感。难道linux上操作gpio真么慢

youkebing 发表于 2020-4-7 09:28:55

FireBrain 发表于 2020-4-7 08:48
还用了纯c语言的mmap方式,速度稍微有点提升,但还是有扫描感。难道linux上操作gpio真么慢 ...

我认为是应用进行系统调用的效率问题,如果要提高效率还是需要写驱动,当然,linux其实我也不是很懂!以上是我猜的.

FireBrain 发表于 2020-4-7 09:40:54

youkebing 发表于 2020-4-7 09:28
我认为是应用进行系统调用的效率问题,如果要提高效率还是需要写驱动,当然,linux其实我也不是很懂!以 ...

谢谢回复,从大佬确认,你猜对了,内核态和用户态交互是毫秒级的延迟。
下一步的玩法是:
1:f1c100s硬件spi的4线方式
2. spi软件模式做成驱动集成到内核
3. 最终做成spi软硬件兼容的驱动集成到内核

通过这个小demo系统的学习一下linux的驱动开发

youkebing 发表于 2020-4-7 09:44:15

FireBrain 发表于 2020-4-7 09:40
谢谢回复,从大佬确认,你猜对了,内核态和用户态交互是毫秒级的延迟。
下一步的玩法是:
1:f1c100s硬件 ...

期待你分享最新成果!

armstrong 发表于 2020-4-15 19:12:45

本帖最后由 armstrong 于 2020-4-15 19:17 编辑

技术总是在无尽的折腾中进步,这个我深有体会。
之前玩过几次linux,总是拿裸机开发做对比;感觉裸机很直接暴力的做法,在linux总是要拐弯抹角才能实现。
我很不愿意用拐弯抹角的方法实现本来直接能解决的问题,所以我永远学不会linux;也就是我没有不怕折腾的精神。

redworlf007 发表于 2020-4-25 09:14:01

armstrong 发表于 2020-4-15 19:12
技术总是在无尽的折腾中进步,这个我深有体会。
之前玩过几次linux,总是拿裸机开发做对比;感觉裸机很直接 ...

linux也不是拐弯抹角,那是一层层的封装,裸机的话一层层封装后会变成rtos,也会有驱动框架。上了操作系统,能实现更强大的软件功能。
在linux上搞开发,思维方式和知识都不同。如果只会裸机开发,开发思维和知识面,只能停留在一个很狭窄的区域。

armstrong 发表于 2020-4-25 12:17:31

redworlf007 发表于 2020-4-25 09:14
linux也不是拐弯抹角,那是一层层的封装,裸机的话一层层封装后会变成rtos,也会有驱动框架。上了操作系 ...

对的,是这么回事。所以新开发者建议从linux入手嵌入式开发,尽早培养完整的嵌入式思维方式。
我是感觉自己老了,思维方式顽固不化{:dizzy:}

redworlf007 发表于 2020-4-25 20:24:45

armstrong 发表于 2020-4-25 12:17
对的,是这么回事。所以新开发者建议从linux入手嵌入式开发,尽早培养完整的嵌入式思维方式。
我是感觉自 ...

你玩玩新塘这种nuc972的片子,搞几天你会发现,和玩ucos差不多,写应用程序和裸机上差不多,都是瞎搞,哈哈。

at90s 发表于 2020-4-25 21:57:23

我觉得是你的代码问题,每操作一个bit都要调用一堆系统调用。其实应该分成3个函数:初始化,writebit,关闭。初始化在整个程序启动时调用一次,包括打开文件,mmap等,最终得到一个虚拟基地址。writebi函数多加一个参数,就是前面得到的虚基地址,writebit里面只有指针操作,不会再有任何系统调用。关闭函数ummap和close,在程序退出前执行一次。

FireBrain 发表于 2020-4-25 22:20:46

at90s 发表于 2020-4-25 21:57
我觉得是你的代码问题,每操作一个bit都要调用一堆系统调用。其实应该分成3个函数:初始化,writebit,关闭 ...

感谢回复,想到过这个问题。由于改动比较多,人比较懒,当时没有改。有时间我会试一下。不知道这样操作虚拟地址,和在裸奔中直接操作寄存器速度差多少
页: [1]
查看完整版本: go语言开发f1c100s之oled驱动mmap版