zynq操作系统: Linux驱动开发Gpio中断篇

简介: Linux内核中有一套GPIO框架,管理和控制芯片上的GPIO管教,包括配置输入输出,配置电平高低(输出)和获取电平高低(输入),中断管理。只需要通过读取/sys/class/gpio/gpioN/value的值来获取中断。当然也不是简单的read,而是通过epoll、poll、select等这些IO复用函数来控制,对于epoll或者poll,需要监听的事件是EPOLLPRI或POLLPRI,而不是EPOLLIN或POLLIN,对于select,需要将文件描述符放在exceptfds中,而且文件描述符被触发时需要通过调用read读取数据,还要通过lseek将文件流指针置回文件开头。

简介

 Linux内核中有一套GPIO框架,管理和控制芯片上的GPIO管教,包括配置输入输出,配置电平高低(输出)和获取电平高低(输入),中断管理。只需要通过读取/sys/class/gpio/gpioN/value的值来获取中断。当然也不是简单的read,而是通过epoll、poll、select等这些IO复用函数来控制,对于epoll或者poll,需要监听的事件是EPOLLPRI或POLLPRI,而不是EPOLLIN或POLLIN,对于select,需要将文件描述符放在exceptfds中,而且文件描述符被触发时需要通过调用read读取数据,还要通过lseek将文件流指针置回文件开头。

(另,网上说实际测试,使用epoll或者poll时监听事件(POLLIN | POLLET)也是可以的。)

命令行的使用

进入 /sys/class/gpio目录

假如你想操作EMIO这个引脚,那么根据计算,比如内核启动会生成gpio906这个目录,emio的第一个就相当于906+54=960也就是gpio960会是我们用来判断的gpio引脚

执行命令:

echo 960 > export //暴露接口
cd gpio960
echo out > direction //设置方向
echo 1 > value //设置输出电平值 0低 1高

写代码就可以通过配置来暴露了

测试代码

下面给出整个bram通过gpio中断来实现数据读写的驱动以及测试demo:(好像还是有点简陋)

驱动c文件 gpioapp.c
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include "gpioapp.h"
#define XPAR_BRAM_0_BASEADDR 0x40000000
#define XPAR_BRAM_1_BASEADDR 0x42000000
#define XPAR_BRAM_2_BASEADDR 0x44000000
#define XPAR_BRAM_3_BASEADDR 0x46000000
#define XPAR_BRAM_4_BASEADDR 0x48000000
#define XPAR_BRAM_5_BASEADDR 0x4A000000
#define XPAR_BRAM_6_BASEADDR 0x4C000000
#define XPAR_BRAM_7_BASEADDR 0x4E000000
#define XPAR_BRAM_8_BASEADDR 0x50000000
#define DATA_LEN    1024
volatile unsigned int *map_base0;
volatile unsigned int *map_base1;
volatile unsigned int *map_base2;
volatile unsigned int *map_base3;
volatile unsigned int *map_base4;
volatile unsigned int *map_base5;
volatile unsigned int *map_base6;
volatile unsigned int *map_base7;
volatile unsigned int *map_base8;
int gpio_fd;
int gpio_fd1;
int gpio_fd2;
int gpio_fd3;
int gpio_fd4;
int gpio_fd5;
int gpio_fd6;
int gpio_fd7;
static int gpio_export(int pin);
static int gpio_unexport(int pin);
static int gpio_direction(int pin, int dir);
static int gpio_write(int pin, int value);
static int gpio_read(int pin);
static int gpio_edge(int pin, int edge);
void XBram_Out32(unsigned int * Addr, unsigned int Value)
{
  volatile unsigned int *LocalAddr = (volatile unsigned int *)Addr;
  *LocalAddr = Value;
}
 unsigned int * XBram_In32(unsigned int * Addr)
{
  return *(volatile unsigned int *) Addr;
}
static int gpio_export(int pin)  
{  
    char buffer[64];  
    int len;  
    int fd;  
    fd = open("/sys/class/gpio/export", O_WRONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open export for writing!\n");  
        return(-1);  
    }  
    len = snprintf(buffer, sizeof(buffer), "%d", pin);  
    printf("%s,%d,%d\n",buffer,sizeof(buffer),len);
    if (write(fd, buffer, len) < 0) 
    {  
        MSG("Failed to export gpio!");  
        return -1;  
    }  
    close(fd);  
    return 0;  
}  
static int gpio_unexport(int pin)  
{  
    char buffer[64];  
    int len;  
    int fd;  
    fd = open("/sys/class/gpio/unexport", O_WRONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open unexport for writing!\n");  
        return -1;  
    }  
    len = snprintf(buffer, sizeof(buffer), "%d", pin);  
    if (write(fd, buffer, len) < 0) 
    {  
        MSG("Failed to unexport gpio!");  
        return -1;  
    }  
    close(fd);  
    return 0;  
} 
//dir: 0输入, 1输出
static int gpio_direction(int pin, int dir)  
{  
    static const char dir_str[] = "in\0out";  
    char path[64];  
    int fd;  
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/direction", pin);  
    fd = open(path, O_WRONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open gpio direction for writing!\n");  
        return -1;  
    }  
    if (write(fd, &dir_str[dir == 0 ? 0 : 3], dir == 0 ? 2 : 3) < 0) 
    {  
        MSG("Failed to set direction!\n");  
        return -1;  
    }  
    close(fd);  
    return 0;  
}  
//value: 0-->LOW, 1-->HIGH
static int gpio_write(int pin, int value)  
{  
    static const char values_str[] = "01";  
    char path[64];  
    int fd;  
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);  
    fd = open(path, O_WRONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open gpio value for writing!\n");  
        return -1;  
    }  
    if (write(fd, &values_str[value == 0 ? 0 : 1], 1) < 0) 
    {  
        MSG("Failed to write value!\n");  
        return -1;  
    }  
    close(fd);  
    return 0;  
}
static int gpio_read(int pin)  
{  
    char path[64];  
    char value_str[3];  
    int fd;  
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", pin);  
    fd = open(path, O_RDONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open gpio value for reading!\n");  
        return -1;  
    }  
    if (read(fd, value_str, 3) < 0)
    {  
        MSG("Failed to read value!\n");  
        return -1;  
    }  
    close(fd);  
    return (atoi(value_str));
}  
// none表示引脚为输入,不是中断引脚
// rising表示引脚为中断输入,上升沿触发
// falling表示引脚为中断输入,下降沿触发
// both表示引脚为中断输入,边沿触发
// 0-->none, 1-->rising, 2-->falling, 3-->both
static int gpio_edge(int pin, int edge)
{
const char dir_str[] = "none\0rising\0falling\0both"; 
char ptr;
char path[64];  
    int fd; 
switch(edge)
{
    case 0:
        ptr = 0;
        break;
    case 1:
        ptr = 5;
        break;
    case 2:
        ptr = 12;
        break;
    case 3:
        ptr = 20;
        break;
    default:
        ptr = 0;
} 
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/edge", pin);  
    fd = open(path, O_WRONLY);  
    if (fd < 0) 
    {  
        MSG("Failed to open gpio edge for writing!\n");  
        return -1;  
    }  
    if (write(fd, &dir_str[ptr], strlen(&dir_str[ptr])) < 0) 
    {  
        MSG("Failed to set edge!\n");  
        return -1;  
    }  
    close(fd);  
    return 0;  
}
int GpioInit()
{
    gpio_unexport(958);
    gpio_unexport(959);
    gpio_unexport(960);
    gpio_unexport(961);
    gpio_unexport(962);
    gpio_unexport(963);
    gpio_unexport(964);
    gpio_unexport(965);
    /*********************rx handle**************/ 
    gpio_export(958);
    gpio_direction(958, 0);//
    gpio_edge(958,1);
    gpio_fd = open("/sys/class/gpio/gpio958/value",O_RDONLY);
    if(gpio_fd < 0)
    {
        MSG("Failed to open value!\n");  
        return -1;  
    }
    else
    printf("success open958\r\n");
    gpio_export(959);
    gpio_direction(959, 0);//
    gpio_edge(959,1);
    gpio_fd1 = open("/sys/class/gpio/gpio959/value",O_RDONLY);
    if(gpio_fd1 < 0)
    {
        MSG("Failed to open value1!\n");  
        return -1;  
    }
    else
    printf("success open959\r\n");
    gpio_export(960);
    gpio_direction(960, 0);//
    gpio_edge(960,1);
    gpio_fd2 = open("/sys/class/gpio/gpio960/value",O_RDONLY);
    if(gpio_fd2 < 0)
    {
        MSG("Failed to open value2!\n");  
        return -1;  
    }
    else
    printf("success open960\r\n");
    gpio_export(961);
    gpio_direction(961, 0);//
    gpio_edge(961,1);
    gpio_fd3 = open("/sys/class/gpio/gpio961/value",O_RDONLY);
    if(gpio_fd3 < 0)
    {
        MSG("Failed to open value3!\n");  
        return -1;  
    }
    else
    printf("success open961\r\n");
    gpio_export(962);
    gpio_direction(962, 0);//
    gpio_edge(962,1);
    gpio_fd4 = open("/sys/class/gpio/gpio962/value",O_RDONLY);
    if(gpio_fd4 < 0)
    {
        MSG("Failed to open value4!\n");  
        return -1;  
    }
    else
    printf("success open962\r\n");
    gpio_export(963);
    gpio_direction(963, 0);//
    gpio_edge(963,1);
    gpio_fd5 = open("/sys/class/gpio/gpio963/value",O_RDONLY);
    if(gpio_fd5 < 0)
    {
        MSG("Failed to open value5!\n");  
        return -1;  
    }
    else
    printf("success open963\r\n");
    gpio_export(964);
    gpio_direction(964, 0);//
    gpio_edge(964,1);
    gpio_fd6 = open("/sys/class/gpio/gpio964/value",O_RDONLY);
    if(gpio_fd6 < 0)
    {
        MSG("Failed to open value6!\n");  
        return -1;  
    }
    else
    printf("success open964\r\n");
    gpio_export(965);
    gpio_direction(965, 0);//
    gpio_edge(965,1);
    gpio_fd7 = open("/sys/class/gpio/gpio965/value",O_RDONLY);
    if(gpio_fd7 < 0)
    {
        MSG("Failed to open value7!\n");  
        return -1;  
    }
    else
    printf("success open965\r\n");
}
int BramInit()
{
/********************BRAMinit****************************************************/
    GpioInit();
    int fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd < 0) {
        printf("can not open /dev/mem \n");
        return (-1);
    }   
    printf("/dev/mem is open \n");
    /*
    mmap(阿巴阿巴阿巴)
    第二个参数表示内存映射的大小、
    第三个参数是一个 flag标志, PROT_READ | PROT_WRITE 的组合表示映射的内存空间是可读可写的、
    第四个参数MAP_SHARED、
    第五个参数表示文件描述符 fd。
     mmap 函数的返回值就等于映射之后得到的实际地址
    */
    map_base0 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_0_BASEADDR);
    map_base1 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_1_BASEADDR);
    map_base2 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_2_BASEADDR);
    map_base3 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_3_BASEADDR);
    map_base4 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_4_BASEADDR);
    map_base5 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_5_BASEADDR);
    map_base6 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_6_BASEADDR);
    map_base7 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_7_BASEADDR);
    map_base8 = mmap(NULL, BRAM_MAX_SIZE * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, XPAR_BRAM_8_BASEADDR);
    if (map_base0 == 0 || map_base1 == 0|| map_base2 == 0|| map_base3 == 0|| map_base4 == 0||
                          map_base5 == 0|| map_base6 == 0|| map_base7 == 0|| map_base8 == 0 ) { 
        printf("NULL pointer\n");
    }   
    else {
        printf("mmap successful\n");
    }   
     close(fd);
     return 0;
}
 int BramExit()
{
  munmap(map_base0, DATA_LEN);
  munmap(map_base1, DATA_LEN);
  munmap(map_base2, DATA_LEN);
  munmap(map_base3, DATA_LEN);
  munmap(map_base4, DATA_LEN);
  munmap(map_base5, DATA_LEN);
  munmap(map_base6, DATA_LEN);
  munmap(map_base7, DATA_LEN);
}
/*******************************************************
 * 
 * 
 * 
 * 
 * 
 * *****************************************************/
 int SendBram0(unsigned char *sbuffer,unsigned int length)
{
    int m,n;
    int Status;
    int i;
    unsigned int addr;
    unsigned int content;
  unsigned char *bufferrptr;
    bufferrptr = (unsigned char *)map_base2;
    if(sbuffer == NULL)
    {
        return -1;
    }
    m = length/BRAM_MAX_SIZE;
    n = length%BRAM_MAX_SIZE;
    for(i = 0;i < m;i++)
    {
        memcpy(bufferrptr,&sbuffer[i*BRAM_MAX_SIZE],BRAM_MAX_SIZE);
        XBram_Out32(map_base0+1,BRAM_MAX_SIZE);
        XBram_Out32(map_base0+2,0x1);
        usleep(15);
        XBram_Out32(map_base0+2,0);//清除发送中断,实际地址加8
    }
    memcpy(bufferrptr,&sbuffer[m*BRAM_MAX_SIZE],n);
    XBram_Out32(map_base0+1,n);
    XBram_Out32(map_base0+2,0x1);
    usleep(15);
    XBram_Out32(map_base0+2,0);//清除发送中断,实际地址加8
    return 0;
}
int SendBram1(unsigned char *sbuffer,unsigned int length)
{
    int m,n;
    int Status;
    int i;
    unsigned int addr;
    unsigned int content;
  unsigned char *bufferrptr;
    bufferrptr = (unsigned char *)map_base3;
    if(sbuffer == NULL)
    {
        return -1;
    }
    m = length/BRAM_MAX_SIZE;
    n = length%BRAM_MAX_SIZE;
    for(i = 0;i < m;i++)
    {
        memcpy(bufferrptr,&sbuffer[i*BRAM_MAX_SIZE],BRAM_MAX_SIZE);
        XBram_Out32(map_base0+5,BRAM_MAX_SIZE);
        XBram_Out32(map_base0+6,0x1);
        usleep(15);
        XBram_Out32(map_base0+6,0);//清除发送中断,实际地址加24
    }
    memcpy(bufferrptr,&sbuffer[m*BRAM_MAX_SIZE],n);
    XBram_Out32(map_base0+5,n);
    XBram_Out32(map_base0+6,0x1);
    usleep(15);
    XBram_Out32(map_base0+6,0);//清除发送中断,实际地址加24
    return 0;
}
int SendBram2(unsigned char *sbuffer,unsigned int length)
{
    int m,n;
    int Status;
    int i;
    unsigned int addr;
    unsigned int content;
  unsigned char *bufferrptr;
    bufferrptr = (unsigned char *)map_base5;
    if(sbuffer == NULL)
    {
        return -1;
    }
    m = length/BRAM_MAX_SIZE;
    n = length%BRAM_MAX_SIZE;
    for(i = 0;i < m;i++)
    {
        memcpy(bufferrptr,&sbuffer[i*BRAM_MAX_SIZE],BRAM_MAX_SIZE);
        XBram_Out32(map_base0+9,BRAM_MAX_SIZE);
        XBram_Out32(map_base0+10,0x1);
        usleep(15);
        XBram_Out32(map_base0+10,0);//清除发送中断,实际地址加40
    }
    memcpy(bufferrptr,&sbuffer[m*BRAM_MAX_SIZE],n);
    XBram_Out32(map_base0+9,n);
    XBram_Out32(map_base0+10,0x1);
    usleep(15);
    XBram_Out32(map_base0+10,0);//清除发送中断,实际地址加40
    return 0;
}
int SendBram3(unsigned char *sbuffer,unsigned int length)
{
    int m,n;
    int Status;
    int i;
    unsigned int addr;
    unsigned int content;
  unsigned char *bufferrptr;
    bufferrptr = (unsigned char *)map_base7;
    if(sbuffer == NULL)
    {
        return -1;
    }
    m = length/BRAM_MAX_SIZE;
    n = length%BRAM_MAX_SIZE;
    for(i = 0;i < m;i++)
    {
        memcpy(bufferrptr,&sbuffer[i*BRAM_MAX_SIZE],BRAM_MAX_SIZE);
        XBram_Out32(map_base0+13,BRAM_MAX_SIZE);
        XBram_Out32(map_base0+14,0x1);
        usleep(15);
        XBram_Out32(map_base0+14,0);
    }
    memcpy(bufferrptr,&sbuffer[m*BRAM_MAX_SIZE],n);
    XBram_Out32(map_base0+13,n);
    XBram_Out32(map_base0+14,0x1);
    usleep(30);
    XBram_Out32(map_base0+14,0);
    return 0;
}
 int ReadBram0(unsigned char *rbuffer)
{
    int i;
    int Length;
    int Status;
    unsigned int addr;
    unsigned int content;
    Length = XBram_In32(map_base0+2);
    memcpy(rbuffer,(unsigned char*)map_base1,Length);
    XBram_Out32(map_base0,0x1);
    XBram_Out32(map_base0,0);//清除接收中断
    // XBram_Out32(map_base0+2,0);//清除发送中断,实际地址加8
    return Length;
}
int ReadBram1(unsigned char *rbuffer)
{
    int i;
    int Length;
    int Status;
    unsigned int addr;
    unsigned int content;
    Length = XBram_In32(map_base0+2+1);
    memcpy(rbuffer,(unsigned char*)map_base4,Length);
    XBram_Out32(map_base0+4,0x1);
    XBram_Out32(map_base0+4,0);//清除接收中断
    // XBram_Out32(map_base0+2+4,0);//清除发送中断,实际地址加8
    return Length;
}
int ReadBram2(unsigned char *rbuffer)
{
    int i;
    int Length;
    int Status;
    unsigned int addr;
    unsigned int content;
    Length = XBram_In32(map_base0+2+1+1);
    memcpy(rbuffer,(unsigned char*)map_base6,Length);
    XBram_Out32(map_base0+4+4,0x1);
    XBram_Out32(map_base0+4+4,0);//清除接收中断
    // XBram_Out32(map_base0+2+4+4,0);//清除发送中断,实际地址加8
    return Length;
}
int ReadBram3(unsigned char *rbuffer)
{
    int i;
    int Length;
    int Status;
    unsigned int addr;
    unsigned int content;
    Length = XBram_In32(map_base0+2+1+1+1);
    if(Length == 0)
    {
        XBram_Out32(map_base0+4+4+4,0x1);
        XBram_Out32(map_base0+4+4+4,0);//清除接收中断
      return 0;
    }
    memcpy(rbuffer,(unsigned char*)map_base8,Length);
    XBram_Out32(map_base0+4+4+4,0x1);
    XBram_Out32(map_base0+4+4+4,0);//清除接收中断
    // XBram_Out32(map_base0+2+4+4+4,0);//清除发送中断,实际地址加8
    return Length;
}
驱动头文件gpioapp.h
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#define MSG(args...) printf(args) 
#define BRAM_MAX_SIZE    2048
#define DATA_LEN    1024
int GpioInit();
int BramInit();
int BramExit();
int SendBram0(unsigned char *sbuffer,unsigned int length);
int ReadBram0(unsigned char *rbuffer);
int SendBram1(unsigned char *sbuffer,unsigned int length);
int ReadBram1(unsigned char *rbuffer);
int SendBram2(unsigned char *sbuffer,unsigned int length);
int ReadBram2(unsigned char *rbuffer);
int SendBram3(unsigned char *sbuffer,unsigned int length);
int ReadBram3(unsigned char *rbuffer);
测试demo
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <poll.h>
#include <pthread.h>
#include "gpioapp.h"
extern gpio_fd;
extern gpio_fd2;
extern gpio_fd4;
extern gpio_fd6;
static unsigned char rbuffer[BRAM_MAX_SIZE] = {0};
static unsigned char tbuffer[BRAM_MAX_SIZE] = {0};
// void *rapidio_taks_rec(void *arg)
// {
//     int ret = 0,i;
//     unsigned int rec_len = 0;
//     struct pollfd fds[1];
//     char buff[10];
//     static cnt = 0;
//     fds[0].fd = gpio_fd;
//     fds[0].events  = POLLPRI;
//     ret = read(gpio_fd,buff,10);
//     if( ret == -1 )
//         MSG("read\n");
//     while(1)
//     {
//       ret = poll(fds,1,-1);
//       if( ret == -1 )
//           MSG("poll\n");
//       if( fds[0].revents & POLLPRI)
//       {
//         ret = lseek(gpio_fd,0,SEEK_SET);
//         if( ret == -1 )
//             MSG("lseek\n");
//         ret = read(gpio_fd,buff,10);
//         if( ret == -1 )
//             MSG("read\n");
//         memset(rbuffer,0,BRAM_MAX_SIZE);
//         rec_len = ReadBram0(rbuffer);
//         cnt ++;
//         printf("\nrec_len = 0x%x,cnt = %d\n",rec_len,cnt);
//         printf("bram0 rx\n");
//          if(cnt == 3)
//          {
//              for(i = 0;i<256;i++)
//              {
//                  if(i%16 == 0)
//                  {
//                      printf("\n");
//                  }         
//                  printf("0x%02x ",rbuffer[i]);
//              }
//              printf("\n");
//          }
//          if(rec_len != BRAM_MAX_SIZE)
//          {
//              for(i = 0;i<rec_len;i++)
//              {
//                  if(i%16 == 0)
//                  {
//                      printf("\n");
//                  }   
//                  printf("0x%02x ",rbuffer[i]);
//              }
//              printf("\n");
//          }
//  SendBram0(rbuffer,rec_len);
//       }
//     else
//     printf("poll nothing--------------------------\n");
//    }
//    pthread_exit(0);
// }
// void *rapidio_taks_rec1(void *arg)
// {
//     int ret = 0,i;
//     unsigned int rec_len = 0;
//     struct pollfd fds[1];
//     char buff[10];
//     static cnt = 0;
//     fds[0].fd = gpio_fd2;
//     fds[0].events  = POLLPRI;
//     ret = read(gpio_fd2,buff,10);
//     if( ret == -1 )
//         MSG("read\n");
//     while(1)
//     {
//       ret = poll(fds,1,-1);
//       if( ret == -1 )
//           MSG("poll\n");
//       if( fds[0].revents & POLLPRI)
//       {
//         ret = lseek(gpio_fd2,0,SEEK_SET);
//         if( ret == -1 )
//             MSG("lseek\n");
//         ret = read(gpio_fd2,buff,10);
//         if( ret == -1 )
//             MSG("read\n");
//         memset(rbuffer,0,256);
//         rec_len = ReadBram1(rbuffer);
//         cnt ++;
//         printf("\nrec_len = 0x%x,cnt = %d\n",rec_len,cnt);
//         printf("bram1 rx\n");
//          for(i = 0;i<rec_len;i++)
//          {
//              if(i%16 == 0)
//              {
//                  printf("\n");
//              }
//              printf("0x%02x ",rbuffer[i]);
//          }
//          printf("\n");
//  SendBram1(rbuffer,rec_len);
//       }
//     else
//     printf("poll nothing--------------------------\n");
//    }
//    pthread_exit(0);
// }
// void *rapidio_taks_rec2(void *arg)
// {
//     int ret = 0,i;
//     unsigned int rec_len = 0;
//     struct pollfd fds[1];
//     char buff[10];
//     static cnt = 0;
//     fds[0].fd = gpio_fd4;
//     fds[0].events  = POLLPRI;
//     ret = read(gpio_fd4,buff,10);
//     if( ret == -1 )
//         MSG("read\n");
//     while(1)
//     {
//       ret = poll(fds,1,-1);
//       if( ret == -1 )
//           MSG("poll\n");
//       if( fds[0].revents & POLLPRI)
//       {
//         ret = lseek(gpio_fd4,0,SEEK_SET);
//         if( ret == -1 )
//             MSG("lseek\n");
//         ret = read(gpio_fd4,buff,10);
//         if( ret == -1 )
//             MSG("read\n");
//         memset(rbuffer,0,256);
//         rec_len = ReadBram2(rbuffer);
//         cnt ++;
//         printf("\nrec_len = 0x%x,cnt = %d\n",rec_len,cnt);
//         printf("bram2 rx\n");
//          for(i = 0;i<rec_len;i++)
//          {
//              if(i%16 == 0)
//              {
//                  printf("\n");
//              }
//              printf("0x%02x ",rbuffer[i]);
//          }
//          printf("\n");
//  SendBram2(rbuffer,rec_len);
//       }
//     else
//     printf("poll nothing--------------------------\n");
//    }
//    pthread_exit(0);
// }
void *rapidio_taks_rec3(void *arg)
{
    int ret = 0,i;
    unsigned int rec_len = 0;
    struct pollfd fds[1];
    char buff[10];
    static cnt = 0;
    unsigned int err_num = 0;
    unsigned int cou = 0;
    fds[0].fd = gpio_fd6;
    fds[0].events  = POLLPRI;
    ret = read(gpio_fd6,buff,10);
    if( ret == -1 )
        MSG("read\n");
    while(1)
    {
      ret = poll(fds,1,-1);
      if( ret == -1 )
          MSG("poll\n");
      if( fds[0].revents & POLLPRI)
      {
        ret = lseek(gpio_fd6,0,SEEK_SET);
        if( ret == -1 )
            MSG("lseek\n");
        ret = read(gpio_fd6,buff,10);
        if( ret == -1 )
            MSG("read\n");
        memset(rbuffer,0,2048);
        rec_len = ReadBram3(rbuffer);
        cnt ++;
        if(rec_len == 0)
     {
      printf("gkhy_debug : recv len error \n");
      continue;
     }
        if(rec_len > 1500)
     {
      printf("gkhy_debug : recv len error1500 \n");
      continue;
     }
        for(i=0;i<rec_len;i++)
  {
  if(rbuffer[i] != tbuffer[i])
  {
    // printf("khy_debug :tbuffer[%d] : 0x%x, rbuffer[%d] : 0x%x\n",i,tbuffer[i],i,rbuffer[i]);
    err_num++;
  }
  }   
        if(err_num != 0)
        {
            printf("gkhy_debug:err_num = %d\n",err_num);
            err_num = 0;
        }
  //if(cnt%50 == 0)
  //{
   //printf("\nrec_len = 0x%x,cnt = %d\n",rec_len,cnt);
  //}
        //printf("\nrec_len = 0x%x,cnt = %d\n",rec_len,cnt);
        // printf("bram3 rx\n");
        // for(i = 0;i<(rec_len);i++)
        // {
        //     if(i%16 == 0)
        //     {
        //         printf("\n");
        //     }
        //    printf("0x%02x ",rbuffer[i]);//注意大小端转换
        // }
        // printf("\n");
        // SendBram3(rbuffer,rec_len); 
      }
    else
    printf("poll nothing--------------------------\n");
   }
   pthread_exit(0);
}
// void *rapidio_taks_send(void *arg)
// {
//     int i;
//     unsigned char sbuffer[256] = {0};
//     for(i = 0;i < 256;i++)
//     {
//         sbuffer[i]=i+1;
//     }
//     while(1)
//     {
//         sleep(10);
//         //SendBram0(sbuffer,0x500); 
//     }
//    pthread_exit(0);
// }
// void *rapidio_taks_send1(void *arg)
// {
//     int i;
//     unsigned char sbuffer[256] = {0};
//     for(i = 0;i < 256;i++)
//     {
//         sbuffer[i]=i+1;
//     }
//     while(1)
//     {
//         sleep(10);
//         //SendBram1(sbuffer,0x100); 
//     }
//    pthread_exit(0);
// }
// void *rapidio_taks_send2(void *arg)
// {
//     int i;
//     unsigned char sbuffer[256] = {0};
//     for(i = 0;i < 256;i++)
//     {
//         sbuffer[i]=i+2;
//     }
//     while(1)
//     {
//         sleep(10);
//         //SendBram2(sbuffer,0x200); 
//     }
//    pthread_exit(0);
// }
void *rapidio_taks_send3(void *arg)
{
    while(1)
    {
        usleep(20000);
        SendBram3(tbuffer,375); 
    }
   pthread_exit(0);
}
int main(int argc, char **argv)
{
    int error;
    int ret;
    int i;
    pthread_t rapidio_sid;
    pthread_t rapidio_rid;
    pthread_t rapidio_sid1;
    pthread_t rapidio_rid1;
    pthread_t rapidio_sid2;
    pthread_t rapidio_rid2;
    pthread_t rapidio_sid3;
    pthread_t rapidio_rid3;
    printf("enter app --------\n");
    BramInit();
    for(i = 0;i < 1500;i++)
    {
        tbuffer[i]=i;
    }
    // error=pthread_create(&rapidio_rid, NULL, &rapidio_taks_rec,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadrx_create fail\n");
    //     return -1;
    // }
    // error=pthread_create(&rapidio_sid, NULL, &rapidio_taks_send,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadtx_create fail\n");
    //     return -1;
    // }
    // error=pthread_create(&rapidio_rid1, NULL, &rapidio_taks_rec1,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadrx1_create fail\n");
    //     return -1;
    // }
    // error=pthread_create(&rapidio_sid1, NULL, &rapidio_taks_send1,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadtx1_create fail\n");
    //     return -1;
    // }
    // error=pthread_create(&rapidio_rid2, NULL, &rapidio_taks_rec2,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadrx2_create fail\n");
    //     return -1;
    // }
    // error=pthread_create(&rapidio_sid2, NULL, &rapidio_taks_send2,NULL);
    // if(error != 0)
    // {
    //     printf("pthreadtx2_create fail\n");
    //     return -1;
    // }
    error=pthread_create(&rapidio_rid3, NULL, &rapidio_taks_rec3,NULL);
    if(error != 0)
    {
        printf("pthreadrx3_create fail\n");
        return -1;
    }
    error=pthread_create(&rapidio_sid3, NULL, &rapidio_taks_send3,NULL);
    if(error != 0)
    {
        printf("pthreadtx3_create fail\n");
        return -1;
    }
    // pthread_detach(rapidio_rid);
    // pthread_detach(rapidio_sid);
    // pthread_detach(rapidio_rid1);
    // pthread_detach(rapidio_sid1);
    // pthread_detach(rapidio_rid2);
    // pthread_detach(rapidio_sid2);
    pthread_detach(rapidio_rid3);
    pthread_detach(rapidio_sid3);
    while(1)
    {
        sleep(10);
    }
    //BramExit();
    return 0;
}

IO控制代码

normal_mode
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>   //define O_WRONLY and O_RDONLY
void initGpio(int n)
{
    FILE * fp =fdopen("/sys/class/gpio/export","w");
    if (fp == NULL)
        perror("export open filed");
    else
        fprintf(fp,"%d",n);
    fclose(fp);
}   //create gpio file
void setGpioDirection(int n,char *direction)
{
    char path[100] = {0};
    sprintf(path,"/sys/class/gpio/gpio%d/direction",n);
    FILE * fp =fdopen(path,"w");
    if (fp == NULL)
        perror("direction open filed");
    else
        fprintf(fp,"%s",direction);
    fclose(fp);
}   //set gpio "in" or "out"
int getGpioValue(int n)
{
    char path[64];
    char value_str[3];
    int fd;
    snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", n);
    fd = open(path, O_RDONLY);
    if (fd < 0) {
        perror("Failed to open gpio value for reading!");
        return -1;
    }
    if (read(fd, value_str, 3) < 0) {
        perror("Failed to read value!");
        return -1;
    }
    close(fd);
    return (atoi(value_str));
}   //get gpio(n)'s value
int main()
{
    initGpio(970);
    setGpioDirection(970,"in");
    while(1)
    {
        printf("%d\n",getGpioValue(18));<span style="white-space:pre">  </span>//每隔1s输出一次gpio18的值
        sleep(1);
    }
    return 0;
}
system_mode
void set_gpio64_low(void)  
{     
    system("echo 970> /sys/class/gpio/export");  
    system("echo out > /sys/class/gpio/gpio970/direction");  
    system("echo 0 > /sys/class/gpio/gpio970/value");  
} 
相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
4天前
|
边缘计算 人工智能 运维
Linux操作系统:开源力量的崛起与影响###
一场技术革命的回顾 回溯至1991年,当Linus Torvalds宣布Linux操作系统的诞生时,世界或许并未意识到这一举措将如何深刻地改变技术领域的面貌。本文旨在探讨Linux操作系统的发展历程、核心特性、以及它如何引领了一场开源运动,重塑了软件行业的生态。从最初的个人爱好项目成长为全球最广泛采用的服务器操作系统之一,Linux的故事是技术创新与社区精神共同推动下的辉煌篇章。 ###
|
3天前
|
人工智能 安全 Linux
|
6天前
|
物联网 Linux 5G
Linux操作系统的演变与未来趋势####
本文深入探讨了Linux操作系统的发展历程,从最初的一个学生项目到如今全球最流行的开源操作系统之一。文章将分析Linux的核心优势、关键特性以及它在云计算、物联网和嵌入式系统中的应用前景。通过具体案例展示Linux如何推动技术创新,并预测其在未来技术生态中的角色。本文旨在为读者提供一个全面而深入的理解,帮助他们认识到Linux在现代计算环境中的重要性及其未来的潜力。 ####
|
6天前
|
人工智能 安全 物联网
Linux操作系统的演变与未来:从开源精神到万物互联的基石###
本文是关于Linux操作系统的演变、现状与未来的深度探索。Linux,这一基于Unix的开源操作系统,自1991年由林纳斯·托瓦兹(Linus Torvalds)学生时代创造以来,已经彻底改变了我们的数字世界。文章首先追溯了Linux的起源,解析其作为开源项目的独特之处;随后,详细阐述了Linux如何从一个小众项目成长为全球最广泛采用的操作系统之一,特别是在服务器、云计算及嵌入式系统领域的主导地位。此外,文章还探讨了Linux在推动技术创新、促进协作开发模式以及保障信息安全方面的作用,最后展望了Linux在未来技术趋势中的角色,包括物联网、人工智能和量子计算等前沿领域的潜在影响。 ###
|
8天前
|
前端开发 测试技术 调度
移动应用与系统:探索开发与操作系统的奥秘####
【10月更文挑战第22天】 本文深入剖析了移动应用的开发流程与移动操作系统的核心原理,揭示了两者如何相互依存、共同推动移动互联网的发展。从应用架构设计到操作系统性能优化,全方位解读移动生态的技术细节,为开发者和用户提供有价值的参考。 ####
19 5
|
6天前
|
搜索推荐 前端开发 测试技术
移动应用与系统:探索开发之道与操作系统的演进#### 一、
【10月更文挑战第24天】 本文将带你深入探索移动应用开发的全过程,从构思到上架的每一个细节。同时,我们还将回顾移动操作系统的发展历程,分析当前主流系统的技术特点和未来趋势。无论你是开发者还是普通用户,都能在这里找到感兴趣的内容。 #### 二、
13 1
|
9天前
|
运维 物联网 Linux
Linux操作系统的演变与未来趋势####
本文通过探讨Linux操作系统的历史沿革、当前主流版本的特点,以及其在服务器、云计算和物联网等新兴领域的应用,旨在揭示Linux在现代计算环境中的重要性。此外,文章还将分析Linux面临的挑战与机遇,预测其未来的发展趋势。希望通过这篇文章,读者能够更好地理解Linux的价值,并对其未来充满期待。 ####
|
9天前
|
存储 Linux Shell
深入理解Linux操作系统的启动过程
【10月更文挑战第21天】本文将深入浅出地介绍Linux操作系统的启动过程,包括BIOS、引导加载程序、内核初始化和系统服务启动等环节。通过阅读本文,您将了解到Linux启动过程中的关键步骤和相关概念,以及如何优化启动速度。
|
4天前
|
人工智能 前端开发 物联网
移动应用与系统:探索开发与操作系统的协同进化####
【10月更文挑战第26天】 本文探讨了移动应用开发和移动操作系统之间的紧密关系,揭示了它们是如何相互影响和促进彼此发展的。从早期的功能手机到现今的智能手机,移动操作系统经历了巨大的变革,而移动应用作为其生态系统中的重要组成部分,也随着技术的演进不断创新。文章将深入分析这一过程中的关键节点和技术突破,以及未来的发展趋势。 ####
8 0
|
12天前
|
运维 安全 Linux
Linux中传输文件文件夹的10个scp命令
【10月更文挑战第18天】本文详细介绍了10种利用scp命令在Linux系统中进行文件传输的方法,涵盖基础文件传输、使用密钥认证、复制整个目录、从远程主机复制文件、同时传输多个文件和目录、保持文件权限、跨多台远程主机传输、指定端口及显示传输进度等场景,旨在帮助用户在不同情况下高效安全地完成文件传输任务。
104 5