导航

    全志在线开发者论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 在线文档
    • 社区主页
    1. 主页
    2. LilaZhou
    L
    • 资料
    • 关注 0
    • 粉丝 0
    • 我的积分 239
    • 主题 2
    • 帖子 4
    • 最佳 0
    • 群组 0

    LilaZhouLV 3

    @LilaZhou

    239
    积分
    0
    声望
    1
    资料浏览
    4
    帖子
    0
    粉丝
    0
    关注
    注册时间 最后登录

    LilaZhou 取消关注 关注

    LilaZhou 发布的最新帖子

    • 回复: D1S GPIO的速率最高能到多少?

      @whycanservice 那引脚速度有多少

      发布在 MR Series
      L
      LilaZhou
    • D1S GPIO的速率最高能到多少?

      D1S GPIO的速率最高能到多少?

      发布在 MR Series
      L
      LilaZhou
    • 回复: D1s 通过内存映射方式,直接操作GPIO寄存器,输出速度很慢,如何提高?

      @memory

      这是操作GPIO的方法, 主要就用gpio_set_value方法来设置GPIO端口值。

      #include <unistd.h>
      #include <stdint.h>
      #include <stdio.h>
      #include <fcntl.h>
      #include <sys/mman.h>
      
      // 一个端口的数据结构
      typedef struct
      {
          // 工作方式寄存器 / Configure Register
          uint32_t cfg[4];
          // 数据寄存器 / Data Register
          uint32_t dat;
          // Multi_Driving Register
          uint32_t drv[4];
          // Pull Register
          uint32_t pull[3];
      } port_t;
      
      #define GPIO_MAX_PORT_COUNT	7
      // 基地址
      #define BASE_ADDR 0x02000000
      // 要映射的内存大小
      #define MEM_AREA_SIZE (GPIO_MAX_PORT_COUNT * sizeof(port_t))
      
      // port_t数组指针
      static port_t *ports = 0;
      
      int gpio_init()
      {
          // 避免重复初始化
          if (ports != 0) {
              printf("inited already\n");
              return 1;
          }
          // 打开/dev/mem
          int fd = open("/dev/mem", O_RDWR);
          if (fd == -1) {
              perror("open '/dev/mem' failed\n");
              return 1;
          }
          // 获取页大小
          uint32_t page_size = sysconf(_SC_PAGESIZE);
          // 计算基址相对于页大小的余数,也就是mmap结果之上的偏移量
          uint32_t offset = BASE_ADDR % page_size;
          // 映射到物理地址
          void *map_addr = mmap(0, MEM_AREA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, BASE_ADDR - offset);
          // 映射失败
          if (map_addr == MAP_FAILED) {
              perror("mmap failed!\n");
              close(fd);
              return 1;
          }
          // 可以关闭/dev/mem,对映射关系没有影响
          close(fd);
          // 把数组首地址指过去,此时就指向了第一个端口的第一个寄存器
          ports = (port_t *)(map_addr + offset);
      
          return 0;
      }
      
      // 辅助函数,检查参数,如果合法就找到对应的端口
      static port_t *check_and_get_gpio(char port, int pin)
      {
          // 避免未初始化
          if (ports == 0) {
              printf("not inited yet!\n");
              return 0;
          }
          // 得到端口编号
          int port_index = port - 'A';
          // 检查端口编号
          if (port_index < 0 || port_index >= GPIO_MAX_PORT_COUNT) {
              printf("no such port '%c'!\n", port);
              return 0;
          }
          // 检查引脚编号
          if (pin < 0 || pin >= 32) {
              printf("no such pin '%d'!\n", pin);
              return 0;
          }
          // 返回对应编号的端口
          return ports + port_index;
      }
      
      void gpio_set_mode(char port, int pin, int mode)
      {
          // 获取端口
          port_t *pport = check_and_get_gpio(port, pin);
          if (pport == 0) {
              return;
          }
      
          // 指向对应的cfg寄存器;因为每个cfg寄存器可以控制8个引脚,所以是第pin/8个cfg寄存器
          uint32_t *cfg = &(pport->cfg[pin / 8]);
          // 掩码的左移位数
          int shift = (pin % 8) * 4;
          // 把cfg寄存器对应的4位清空
          *cfg &= ~(((uint32_t)0x0f) << shift);
          // 把cfg寄存器对应的4位清空设置为mode的低4位
          *cfg |= ((uint32_t)(mode & 0x0f)) << shift;
      }
      
      void gpio_set_value(char port, int pin, int value)
      {
          // 获取端口
          port_t *pport = check_and_get_gpio(port, pin);
          if (pport == 0) {
              return;
          }
      
          // 如果为1,就把那一位置位,否则清0
          if (value == 1) {
              pport->dat |= ((uint32_t)1) << pin;
          } else {
              pport->dat &= ~(((uint32_t)1) << pin);
          }
      }
      
      发布在 MR Series
      L
      LilaZhou
    • D1s 通过内存映射方式,直接操作GPIO寄存器,输出速度很慢,如何提高?

      D1s, tina linux 系统,通过内存映射方式,直接操作GPIO寄存器,循环写入多个GPIO端口,共计操作671232次,需要225秒时间,平均1秒2983次,速度较慢,有什么解决办法可提高速度?

      发布在 MR Series
      L
      LilaZhou