您尚未登录。

楼主 #1 2018-08-01 11:25:39

小白菜
会员
注册时间: 2017-09-27
已发帖子: 88
积分: 88

在NUC97x上控制gpio,测试shell,mmap和fwrite

最近在97X上要做高频的数据采集,用的是qt,由于刚开始太清楚linux内核的任务调度机制,
也是本着偷懒的原则就在qt程序里直接用system执行shell命令,
结果用示波器测试发现,单单是gpio的一次拉高置低的时间就耗去了10ms,
龟龟,对于后面用到的ad那结果可想,这个懒还是偷不得的啊。
于是就用了mmap和fwrite测了一下,mmap操作一个io拉高拉低,是200纳秒,fwrite是400纳秒,
测试代码如下,虽然网上很多例子,但还是贴出来,以方便自己以后查阅,同时也是想linux小白进军的一步
mapp_gpio.c:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#define GPIO_BASE (0xB8003000)
#define MAP_SIZE 0x32
static int dev_fd;
int main(void){
        char dev_name[] = "/dev/mem";
        dev_fd = open(dev_name,O_RDWR);
        if(dev_fd < 0){
        printf("open %s is error\n",dev_name);
        return -1;
        }
        printf("1\n");
        unsigned char *gpio_map_base = (unsigned char *)mmap(NULL,MAP_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,dev_fd,GPIO_BASE);
        printf("2\n");
        *(volatile unsigned int *)(gpio_map_base + 0x0100) |= (0x00000008);
    while(1){
        *(volatile unsigned int *)(gpio_map_base + 0x0104) |= (0x00000008);
    *(volatile unsigned int *)(gpio_map_base + 0x0104) &= (~0x00000008);
    }
        printf("3\n");
        if (dev_fd)
                close(dev_fd);
        munmap(gpio_map_base,MAP_SIZE);
        return 0;
}

对于实时进程,Linux采用了两种调度策略,即FIFO(先来先服务调度)和RR(时间片轮转调度)。
因为实时进程具有一定程度的紧迫性,所以衡量一个 实时进程是否应该运行,Linux采用了一个比较固定的标准。
实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标 准。
实时进程的counter只是用来表示该进程的剩余时间片,并不作为衡量它是否值得运行的标准,
这和普通进程是有区别的。上面已经看到,每个进程有两 个优先级(动态优先级和实时优先级),
实时优先级就是用来衡量实时进程是否值得运行的。(本段摘抄与百度)
fopen_gpio.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

FILE *fp;
char str[256];
int set_io_hight(void){
    char buffer[10];
    sprintf(str,"/sys/class/gpio/gpio%d/value",131);
        strcpy(buffer,"1");
        if ((fp = fopen(str, "rb+")) == NULL) {
        printf("Cannot open value file.\n");
    }
    fwrite(buffer,sizeof(char),sizeof(buffer)-1,fp);
    fclose(fp);
    return 1;
}
int set_io_low(void){
        char buffer[10];
        sprintf(str,"/sys/class/gpio/gpio%d/value",131);
        if ((fp = fopen(str, "rb+")) == NULL) {
                printf("Cannot open value file.\n");
        }
        strcpy(buffer,"0");
        fwrite(buffer,sizeof(char),sizeof(buffer)-1,fp);
        fclose(fp);
        return 1;
}

int main(void)
{
        int num=0x47;
        if ((fp = fopen("/sys/class/gpio/export", "w")) == NULL) {
                printf("Cannot open export file.\n");
                exit(1);
        }
        num = 131;
        fprintf(fp, "%d", num);
        printf("num = %d\n",num);
        fclose(fp);
        //  linux equivalent code "echo out > direction" to set the port as an input 
        sprintf(str,"/sys/class/gpio/gpio%d/direction",num);
        if ((fp = fopen(str, "rb+")) == NULL) {
                printf("Cannot open direction file.\n");
                exit(1);
        }
        fprintf(fp, "out");
        fclose(fp);
    while(1){
    set_io_hight();
    set_io_low();
    }
        return 0;
}

以上程序是本菜鸟参照网上例程,以及新塘的数据手册编码而来

离线

楼主 #3 2018-08-01 12:12:42

小白菜
会员
注册时间: 2017-09-27
已发帖子: 88
积分: 88

Re: 在NUC97x上控制gpio,测试shell,mmap和fwrite

达克罗德 说:

Linux不是实时系统,那拉高拉低之间不会被别的进程打断吗?

linux操作系统的是多任务操作系统,通过任务的调度可以实现并发执行,不知道你这个打断是内部打断还是什么的?

离线

楼主 #5 2018-08-02 09:35:03

小白菜
会员
注册时间: 2017-09-27
已发帖子: 88
积分: 88

Re: 在NUC97x上控制gpio,测试shell,mmap和fwrite

目前正在挖坑,挖完再上贴

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn