• T31开发笔记:GPIO控制


    若该文为原创文章,转载请注明原文出处

    记录T31 GPIO控制过程, 此方法也适用海思等芯片。

    一、硬件和开发环境

    1、硬件:T31X+SC5235 

    2、开发环境: ubuntu16.04-64bit

    3、编译器:mips-gcc540-glibc222-32bit-r3.3.0.tar.gz

    注:板子和和WIFI模块是某淘上淘的,使用的是RTL8188,使用的是USB接口,uboot和内核是自己裁剪移植的,内核默认自带WIFI驱动,所以不用移植可以直接使用。

    二、GPIO

    GPIO具有输入输出,复用的功能。ISVP使用Linux标准的GPIOLIB接口。GPIOLIB提供了统一的GPIO申请/释放/设置/获取接口。

    如果是User  space 需要操作GPIO,有两种 方法可以选择:

    A. 通过sysfs GPIO 接口进行操作

    B. 应用程序调用相关的驱动,驱动中实现GPIO的设置

    个人使用的是A方法sysfs GPIO,只记录sysfs GPIO的操作过程。

    三、sysfs GPIO

    1、内核选项

    执行make menuconfig命令

    1. Device Drivers --->
    2. -*- GPIO Support --->
    3. [*] /sys/class/gpio/... (sysfs interface)

    一般情况下,内核默认配置。

    2、sysfs GPIO的申请与释放

    申请GPIO

    1. $ cd /sys/class/gpio
    2. $ echo [gpio_num] > export #申请 GPIO

    释放GPIO

    1. $ cd /sys/class/gpio
    2. $ echo [gpio_num] > unexport #释放 GPIO

    注:gpio_num即GPIO号,计算公式为:

    PA(n) = 0*32 + n

    PB(n) = 1*32 + n

    ...

    3、设置输入/输出方式

    申请后会在/sys/class/gpio目录下生成  gpioN目录,进入其目录,

    1. $ echo out > direction #设置 PB10 为输出模式
    2. $ echo in > direction #设置 PB10 为输入模式

    4、设置电平和读取电平

    设置电平

    在gpioN目录下有active_low节点,直接操作就可以 

    1. $ echo 0 > active_low #value0,表示低电平。value1,表示高电平
    2. $ echo 1 > active_low #value1,表示低电平。value0,表示高电平

    读取电平 

    在gpioN目录下有value节点。

    1. $ cat value #读取电平(输入模式)
    2. $ echo 0 > value #设置电平(输出模式)

    四、程序

    此程序只是一个架构,需要根据实际情况修改GPIO, 只作参考。

    1. 涉及函数:
    2. gpio_read();
    3. gpio_write();
    4. gpio_devmem();
    5. gpio_init();
    6. gpio_deInit();

    源码:

    1. #include <unistd.h>
    2. #include <fcntl.h>
    3. #include <stdio.h>
    4. #include <string.h>
    5. #include <sys/ioctl.h>
    6. #include <stdlib.h>
    7. #include <pthread.h>
    8. #include "gpio.h"
    9. static int g_gpio_state = 0;
    10. pthread_mutex_t g_gpio_mutex;
    11. /* GPIO结构体定义 */
    12. struct __gpio_t
    13. {
    14. int pins_name;
    15. int addr;
    16. int bit_mask;
    17. int value;
    18. int direction;
    19. };
    20. static struct __gpio_t gpio[1] =
    21. {
    22. {0, 0x99000050, 0x3, 0x0, GPIO_DIRECTION_OUTPUT}, // 0
    23. };
    24. int gpio_init()
    25. {
    26. qgpio_deInit();
    27. pthread_mutex_init(&g_gpio_mutex, NULL);
    28. pthread_mutex_lock(&g_gpio_mutex);
    29. g_gpio_state = 1;
    30. sprintf(cmd, "devmem 0x%x", gpio[0].addr);
    31. if (gpio_devmem(cmd, &num) != 0)
    32. {
    33. printf("i(%d) qh_gpio_devmem() error!\n", i);
    34. continue;
    35. }
    36. num &= (~(gpio[0].bit_mask));
    37. num |= gpio[0].value;
    38. sprintf(cmd, "devmem 0x%x 32 0x%x", gpio[0].addr, num);
    39. system(cmd);
    40. pin_num = 0;
    41. sprintf(cmd, "echo %d > /sys/class/gpio/export", pin_num); /* 申请GPIO */
    42. system(cmd);
    43. if (gpio[0].direction == GPIO_DIRECTION_OUTPUT) /* 设置为输出模式 */
    44. {
    45. sprintf(cmd,"echo out > /sys/class/gpio/gpio%d/direction", pin_num);
    46. system(cmd);
    47. }
    48. else if (gpio[0].direction == GPIO_DIRECTION_INPUT) /* 设置为输入模式 */
    49. {
    50. sprintf(cmd,"echo in > /sys/class/gpio/gpio%d/direction", pin_num);
    51. system(cmd);
    52. }
    53. pthread_mutex_unlock(&g_gpio_mutex);
    54. /* IO初始化 */
    55. return 0;
    56. }
    57. int qh_gpio_deInit(void)
    58. {
    59. if (g_gpio_state)
    60. {
    61. pthread_mutex_destroy(&g_gpio_mutex);
    62. g_gpio_state = 0;
    63. }
    64. return 0;
    65. }
    66. int gpio_read(int pins_name, char *value)
    67. {
    68. char open_cmd[50];
    69. memset(open_cmd, 0, sizeof(open_cmd));
    70. sprintf(open_cmd, "/sys/class/gpio/gpio%d/value", pins_name);
    71. pthread_mutex_lock(&g_gpio_mutex);
    72. FILE* fp = fopen(open_cmd, "r");
    73. if (fp == NULL)
    74. {
    75. fprintf(stderr, "open /sys/class/gpio/gpio/value error\n");
    76. pthread_mutex_unlock(&g_gpio_mutex);
    77. return -1;
    78. }
    79. char level = -1;
    80. int size = fread(&level, 1, 1, fp);
    81. if (size < 1)
    82. {
    83. fprintf(stderr, "fread error\n");
    84. fclose(fp);
    85. pthread_mutex_unlock(&g_gpio_mutex);
    86. return -1;
    87. }
    88. *value = level;
    89. fclose(fp);
    90. pthread_mutex_unlock(&g_gpio_mutex);
    91. return 0;
    92. }
    93. int gpio_write(int pins_name,char value)
    94. {
    95. char open_cmd[50];
    96. char buf[8];
    97. memset(buf, 0, sizeof(buf));
    98. sprintf(buf, "%d", value);
    99. memset(open_cmd, 0, sizeof(open_cmd));
    100. sprintf(open_cmd, "/sys/class/gpio/gpio%d/value", pins_name);
    101. pthread_mutex_lock(&g_gpio_mutex);
    102. int fd = open(open_cmd, O_RDWR);
    103. if (fd < 0)
    104. {
    105. fprintf(stderr, "open /sys/class/gpio/gpio/value error\n");
    106. pthread_mutex_unlock(&g_gpio_mutex);
    107. return -1;
    108. }
    109. int size = write(fd, buf, 1);
    110. if (size < 1)
    111. {
    112. fprintf(stderr, "write error\n");
    113. close(fd);
    114. pthread_mutex_unlock(&g_gpio_mutex);
    115. return -1;
    116. }
    117. close(fd);
    118. pthread_mutex_unlock(&g_gpio_mutex);
    119. return 0;
    120. }
    121. int gpio_devmem(char* str_cmd, int* value)
    122. {
    123. FILE* p_file = NULL;
    124. char buf[12] = {0};
    125. int tmp = 0;
    126. if (str_cmd == NULL)
    127. {
    128. fprintf(stderr, "str_cmd is NULL\n");
    129. return -1;
    130. }
    131. if((p_file = popen(str_cmd, "r")) == NULL)
    132. {
    133. printf("popen() error!\n");
    134. pclose(p_file);
    135. return -1;
    136. }
    137. if (fgets(buf, 12, p_file) == NULL)
    138. {
    139. printf("fgets() error!\n");
    140. pclose(p_file);
    141. return -1;
    142. }
    143. tmp = strtol(buf, NULL, 16);
    144. *value = tmp;
    145. pclose(p_file);
    146. return 0;
    147. }

    程序只是一个思路,并未测试。代码有在T31X测试过,需要修改GPIO的相关参数,个人原因不公布,使时时需要把初始化相关的参数修改成所使用的GPIO相关参数。

    五、总结

    1、system函数使用,在嵌入式中很常用到。

    2、pthread_mutex_t的使用。

    如有侵权,请及时联系博主删除,VX:18750903063

  • 相关阅读:
    5G消息发展的前景与挑战
    哈工大2022机器学习实验一:曲线拟合
    两个妙招教你怎么拍照识别植物,增长见识
    https
    python 迭代器
    Vue中前端导出word文件
    作为项目经理必须具备的能力
    卖股票的最佳时机[哨兵机制 || 动态规划]
    2022.11.15 英语背诵
    Python - Python练习题:回文数 “对称“数(整除//、模运算%、计算倍数和取位数)
  • 原文地址:https://blog.csdn.net/weixin_38807927/article/details/127899522