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");  
} 
相关文章
|
2天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
22 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
14天前
|
监控 Unix Linux
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
Linux操作系统调优相关工具(四)查看Network运行状态 和系统整体运行状态
29 0
|
15天前
|
Linux 编译器 开发者
Linux设备树解析:桥接硬件与操作系统的关键架构
在探索Linux的庞大和复杂世界时🌌,我们经常会遇到许多关键概念和工具🛠️,它们使得Linux成为了一个强大和灵活的操作系统💪。其中,"设备树"(Device Tree)是一个不可或缺的部分🌲,尤其是在嵌入式系统🖥️和多平台硬件支持方面🔌。让我们深入了解Linux设备树是什么,它的起源,以及为什么Linux需要它🌳。
Linux设备树解析:桥接硬件与操作系统的关键架构
|
1月前
|
Linux 数据安全/隐私保护 虚拟化
Linux技术基础(1)——操作系统的安装
本文是龙蜥操作系统(Anolis OS) 8.4 的安装指南,用户可以从[龙蜥社区下载页面](https://openanolis.cn/download)获取ISO镜像。安装方法包括物理机的光驱和USB闪存方式,以及虚拟机中的VMware Workstation Pro设置。安装过程涉及选择语言、配置安装目标、选择软件集合和内核,设置Root密码及创建新用户。安装完成后,可通过文本模式或图形化界面验证系统版本,如Anolis OS 8.4,标志着安装成功。
|
14天前
|
Linux
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
21 0
|
1天前
|
Linux Shell Android开发
自动化脚本之GPIO/LED相关适用于Android/Linux
自动化脚本之GPIO/LED相关适用于Android/Linux
10 0
|
8天前
|
Linux 内存技术 Perl
【ZYNQ】制作从 QSPI Flash 启动 Linux 的启动文件
【ZYNQ】制作从 QSPI Flash 启动 Linux 的启动文件
|
8天前
|
Ubuntu Linux 测试技术
【ZYNQ】简单几步,教你使用 Petalinux 定制 Linux
【ZYNQ】简单几步,教你使用 Petalinux 定制 Linux
|
19天前
|
Linux API C语言
FFmpeg开发笔记(一)搭建Linux系统的开发环境
本文指导初学者如何在Linux上搭建FFmpeg开发环境。首先,由于FFmpeg依赖第三方库,可以免去编译源码的复杂过程,直接安装预编译的FFmpeg动态库。推荐网站<https://github.com/BtbN/FFmpeg-Builds/releases>提供适用于不同系统的FFmpeg包。但在安装前,需确保系统有不低于2.22版本的glibc库。详细步骤包括下载glibc-2.23源码,配置、编译和安装。接着,下载Linux版FFmpeg安装包,解压至/usr/local/ffmpeg,并设置环境变量。最后编写和编译简单的C或C++测试程序验证FFmpeg环境是否正确配置。
37 8
FFmpeg开发笔记(一)搭建Linux系统的开发环境
|
1月前
|
存储 Shell Linux
【Shell 命令集合 网络通讯 】⭐Linux 显示当前系统的主机名和操作系统类型 uuname命令 使用教程
【Shell 命令集合 网络通讯 】⭐Linux 显示当前系统的主机名和操作系统类型 uuname命令 使用教程
29 0