找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 406|回复: 1

LoongOS的gpio操作

[复制链接]

22

主题

58

回帖

343

积分

超级版主

积分
343
发表于 2024-7-11 09:03:10 | 显示全部楼层 |阅读模式
本帖最后由 杜比 于 2024-7-11 15:14 编辑

LoongOS的gpio操作

LoongOS是龙芯嵌入式操作系统,遵循Linux系统原理,它的GPIO(通用输入输出)的操作可以通过多种方法实现,包括

  • 使用Sysfs接口GPIO库
  • 设备树
  • 直接访问寄存器等方法。

在了解GPIO操作之前,有必要了解下龙芯的2K0300这个SOC处理器GPIO的一些背景支持:

  • 2K0300有一百多个GPIO端口,每个端口对应一个引脚
  • GPIO的功能是可以自定义的,也就是复用机制,有主功能(默认配置),复用1,复用2和软件可操作的GPIO
  • 定义GPIO功能,主要是通过设备树来完成,比如久久派max的双网口,第二个网口是通过复用进行配置的
  • GPIO口可做为输入,也可以做为输出,有些GPIO口也可以定义为中断输入,甚至可以做一些进一步的配置
  • 当定义为GPIO时,可以通过读写这个GPIO口,实现输入和输出等功能

关于设备树的定义,可以参看内核代码如下文件:
  1. src/arch/loongarch/boot/dts/loongson目录下

  2. loongson_2k0300_pai_99.dts
  3. loongson_2k0300.dtsi     
  4. 2k0300-pinctrl.dtsi     //GPIO引脚控制

复制代码



使用Sysfs接口:Sysfs是Linux内核提供的一种文件系统接口,用于与设备驱动程序进行交互。通过/sys/class/gpio目录下的文件,可以访问和控制GPIO引脚。你可以使用Shell命令或编程语言来读取或写入这些文件,以控制GPIO的状态。

GPIO库:有一些开源的GPIO库可以简化GPIO的控制,例如WiringPi,RPi.GPIO和libgpiod等库提供了函数和接口,使得在Linux系统上编程控制GPIO更加方便。你可以根据自己的需求选择适合的库,并按照其文档进行安装和使用。

设备树(Device Tree):对于一些嵌入式系统,GPIO的映射和配置信息通常存储在设备树中。你可以编辑设备树文件,定义GPIO的属性和功能,并在系统启动时加载设备树,使得GPIO能够被正确地初始化和使用。

直接访问寄存器:在一些特定的嵌入式平台上,你可以直接访问GPIO相关的物理寄存器(用户手册里面有描述)来进行控制。这需要对硬件和底层系统有更深入的了解,因此需要谨慎操作。

在linux环境下,可以通过命令来简单的了解GPIO的测试步骤:

    1、导出GPIO引脚:通过向/sys/class/gpio/export文件写入引脚编号来导出引脚。
    2、设置方向:通过写入direction文件来设置引脚的方向为输入或输出。
    3、读写值:通过读取或写入value文件来读取或设置引脚的值。

具体的操作演示:

  1. // 先看下gpio的使用状况
  2. root@LoongOS:gpio# pwd
  3. /sys/class/gpio

  4. root@LoongOS:gpio# ls -la
  5. total 0
  6. drwxr-xr-x  2 root root     0 Jun  9 10:06 .
  7. drwxr-xr-x 51 root root     0 Jun  9 10:06 ..
  8. --w-------  1 root root 16384 Jun  9 10:17 export
  9. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip0 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip0
  10. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip16 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip16
  11. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip32 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip32
  12. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip48 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip48
  13. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip64 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip64
  14. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip80 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip80
  15. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip96 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip96
  16. --w-------  1 root root 16384 Jun  9 10:20 unexport

  17. // 导出GPIO88

  18. root@LoongOS:gpio# pwd
  19. /sys/class/gpio

  20. root@LoongOS:gpio# echo 88 > export         
  21. // 这其实是个重定向写入到export文件,export文件是内核gpio驱动的一个映射,gpio驱动会根据写入的值调用相应的功能
  22. // 目录下还有个unexport文件,重定向写入这个文件,会释放对应gpio口

  23. root@LoongOS:gpio# ls -la
  24. total 0
  25. drwxr-xr-x  2 root root     0 Jun  9 10:06 .
  26. drwxr-xr-x 51 root root     0 Jun  9 10:06 ..
  27. --w-------  1 root root 16384 Jun  9 10:30 export
  28. lrwxrwxrwx  1 root root     0 Jun  9 10:30 gpio88 -> ../../devices/platform/soc/16000490.pinctrl/gpiochip5/gpio/gpio88
  29. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip0 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip0
  30. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip16 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip16
  31. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip32 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip32
  32. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip48 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip48
  33. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip64 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip64
  34. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip80 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip80
  35. lrwxrwxrwx  1 root root     0 Jun  9 10:06 gpiochip96 -> ../../devices/platform/soc/16000490.pinctrl/gpio/gpiochip96
  36. --w-------  1 root root 16384 Jun  9 10:20 unexport

  37. 可以看出,新增了一个gpio88目录,说明导出成功
  38. gpio88目录的软连接信息里,加粗的信息对应着设备树的结构
  39. gpiochip5 的信息和gpio分组配置有关,16个gpio为一组,每个gpio占2位,对应4种复用关系,一组占32个位,也就是一个word
  40. 所以GPIO88的组是  88/16 = 5 余 8,除数就是组号
  41. 如果导出GPIO66,看看会发生什么!

  42. root@LoongOS:gpio# echo 66 > export
  43. [  230.707910] loongson_gpio_request: GPA64  used_pins_bitmap: 0X0000FF6F      
  44. [  230.719545] current gpio request pin: chip->name gpa4, gpio: 0X00000004        // 第4组
  45. [  230.731529] CPU: 0 PID: 1609 Comm: sh Tainted: G           O      4.19.190 #22
  46. [  230.744027] Stack : 900000000113afd8 9000000000d7afa8 900000009da0c000 900000009da0fb50
  47. [  230.757584]         0000000000000000 900000009da0fb50 900000000148eac8 ffffffffffffffff
  48. [  230.771166]         0000000000000000 ffffffffffffffff 0000000000000007 0000000000000000
  49. [  230.784799]         9000000000d7afa8 0000000000000007 0000000000000006 0000000000000007
  50. [  230.798441]         9000000005500848 0000000000aaaaaa 00000000000002a1 0000000000000001
  51. [  230.811978]         0000000000000001 0000000004110000 0000007ffba733e4 ffffff8000000000
  52. [  230.825423]         90000000012c9bc8 0000000000000004 0000000000000000 900000000108caf8
  53. [  230.838905]         900000009c2eb720 0000005555a66418 0000000000000000 0000007ffba733e0
  54. [  230.852432]         900000000020a074 0000005555aafc50 00000000000000b0 0000000000000004
  55. [  230.865959]         0000000000000000 0000000000071fff 0000000000000800 90000000012c9bc8
  56. [  230.879494]         ...
  57. [  230.886287] Call Trace:
  58. [  230.893146] [<900000000020a074>] show_stack+0x34/0x140
  59. [  230.903377] [<9000000000d7afa8>] dump_stack+0xa8/0xdc
  60. [  230.913470] [<9000000000759d48>] loongson_gpio_request+0x78/0xc0
  61. [  230.924737] [<900000000075cf7c>] gpiod_request_commit+0x10c/0x2d0
  62. [  230.936178] [<9000000000760138>] gpiod_request+0x58/0xc0
  63. [  230.946655] [<9000000000764b0c>] export_store+0x7c/0x150
  64. [  230.957123] [<9000000000469c08>] kernfs_fop_write+0xc8/0x1e0
  65. [  230.968048] [<90000000003db9b8>] __vfs_write+0x28/0x170
  66. [  230.978460] [<90000000003dbce4>] vfs_write+0xc4/0x1d0
  67. [  230.988638] [<90000000003dbfa4>] ksys_write+0x64/0x100
  68. [  230.998944] [<90000000002116f8>] syscall_common+0x24/0x34
  69. [  231.009888] <b>drivers/pinctrl/pinctrl-ls2k300.c:gpio functions has redefinition


复制代码

接下来看一个更好玩的

  1. // 输出系统当前的gpio复用表格,可以通过这种方式查看系统当前的GPIO口复用情况

  2. root@LoongOS:device# cat    /sys/class/gpio/gpiochip0/device/dump_gpio
  3. PA0-00:main     PA1-00:main     PA2-00:main     PA3-00:main     PA4-00:main     PA5-00:main     PA6-00:main
  4. PA0-01:main     PA1-01:main     PA2-01:main     PA3-01:main     PA4-01:main     PA5-01:gpio     PA6-01:main
  5. PA0-02:main     PA1-02:main     PA2-02:main     PA3-02:main     PA4-02:main     PA5-02:gpio     PA6-02:main
  6. PA0-03:main     PA1-03:main     PA2-03:main     PA3-03:main     PA4-03:main     PA5-03:gpio     PA6-03:main
  7. PA0-04:main     PA1-04:main     PA2-04:main     PA3-04:gpio     PA4-04:gpio     PA5-04:gpio     PA6-04:main
  8. PA0-05:main     PA1-05:main     PA2-05:main     PA3-05:gpio     PA4-05:func1    PA5-05:gpio     PA6-05:main
  9. PA0-06:main     PA1-06:main     PA2-06:main     PA3-06:gpio     PA4-06:func1    PA5-06:func2    PA6-06:main
  10. PA0-07:main     PA1-07:main     PA2-07:main     PA3-07:gpio     PA4-07:gpio     PA5-07:gpio     PA6-07:main
  11. PA0-08:main     PA1-08:main     PA2-08:main     PA3-08:main     PA4-08:main     PA5-08:gpio     PA6-08:main
  12. PA0-09:main     PA1-09:main     PA2-09:main     PA3-09:main     PA4-09:main     PA5-09:gpio     PA6-09:main
  13. PA0-10:main     PA1-10:main     PA2-10:main     PA3-10:main     PA4-10:main     PA5-10:main     PA6-10:gpio
  14. PA0-11:main     PA1-11:main     PA2-11:main     PA3-11:main     PA4-11:main     PA5-11:main     PA6-11:gpio
  15. PA0-12:main     PA1-12:main     PA2-12:main     PA3-12:main     PA4-12:main     PA5-12:main     PA6-12:gpio
  16. PA0-13:main     PA1-13:main     PA2-13:main     PA3-13:main     PA4-13:main     PA5-13:main     PA6-13:gpio
  17. PA0-14:main     PA1-14:main     PA2-14:main     PA3-14:main     PA4-14:main     PA5-14:main     PA6-14:gpio
  18. PA0-15:main     PA1-15:main     PA2-15:main     PA3-15:main     PA4-15:main     PA5-15:main     PA6-15:gpio
  19. root@LoongOS:device#
复制代码

此外,对于需要更高性能的应用,可以通过内存映射的方式直接操作GPIO寄存器,这通常需要管理员权限,并且需要对硬件有深入的了解。

在LoongOS中提供了一个叫 devmem2 的工具软件

  1. root@LoongOS:bin# devmem2

  2. Usage:  devmem2 { address } [ type [ data ] ]
  3.         address : memory address to act upon
  4.         type    : access operation type : [b]yte, [h]alfword, [w]ord, [l]ong
  5.         data    : data to be written

  6. 使用方法: devmem2  物理地址  类型  [数值]         数值 = 要写入的值,如果是读,不用提供数值

  7. 如:GPIO复用配置寄存器的地址是 16000490.pinctrl 中的 0x16000490,属于芯片配置寄存器,采用直接映射机制,它的地址是 0x8000000016000490

  8. root@LoongOS:bin# devmem2 0x016000490 w 0000       // 对0x16000490 写一个字,值 = 0000,相当于把 gpio0 - gpio15 都设置成 00,也就是GPIO功能
  9. /dev/mem opened.
  10. Memory mapped at address 0x7ff458c000.
  11. Read at address  0x16000490 (0x7ff458c490): 0xFFFFFFFF
  12. Write at address 0x16000490 (0x7ff458c490): 0x00000000, readback 0x00000000


  13. root@LoongOS:bin# cat    /sys/class/gpio/gpiochip0/device/dump_gpio
  14. PA0-00:gpio     PA1-00:main     PA2-00:main     PA3-00:main     PA4-00:main     PA5-00:main     PA6-00:main
  15. PA0-01:gpio     PA1-01:main     PA2-01:main     PA3-01:main     PA4-01:main     PA5-01:gpio     PA6-01:main
  16. PA0-02:gpio     PA1-02:main     PA2-02:main     PA3-02:main     PA4-02:main     PA5-02:gpio     PA6-02:main
  17. PA0-03:gpio     PA1-03:main     PA2-03:main     PA3-03:main     PA4-03:main     PA5-03:gpio     PA6-03:main
  18. PA0-04:gpio     PA1-04:main     PA2-04:main     PA3-04:gpio     PA4-04:gpio     PA5-04:gpio     PA6-04:main
  19. PA0-05:gpio     PA1-05:main     PA2-05:main     PA3-05:gpio     PA4-05:func1    PA5-05:gpio     PA6-05:main
  20. PA0-06:gpio     PA1-06:main     PA2-06:main     PA3-06:gpio     PA4-06:func1    PA5-06:func2    PA6-06:main
  21. PA0-07:gpio     PA1-07:main     PA2-07:main     PA3-07:gpio     PA4-07:gpio     PA5-07:gpio     PA6-07:main
  22. PA0-08:gpio     PA1-08:main     PA2-08:main     PA3-08:main     PA4-08:main     PA5-08:gpio     PA6-08:main
  23. PA0-09:gpio     PA1-09:main     PA2-09:main     PA3-09:main     PA4-09:main     PA5-09:gpio     PA6-09:main
  24. PA0-10:gpio     PA1-10:main     PA2-10:main     PA3-10:main     PA4-10:main     PA5-10:main     PA6-10:gpio
  25. PA0-11:gpio     PA1-11:main     PA2-11:main     PA3-11:main     PA4-11:main     PA5-11:main     PA6-11:gpio
  26. PA0-12:gpio     PA1-12:main     PA2-12:main     PA3-12:main     PA4-12:main     PA5-12:main     PA6-12:gpio
  27. PA0-13:gpio     PA1-13:main     PA2-13:main     PA3-13:main     PA4-13:main     PA5-13:main     PA6-13:gpio
  28. PA0-14:gpio     PA1-14:main     PA2-14:main     PA3-14:main     PA4-14:main     PA5-14:main     PA6-14:gpio
  29. PA0-15:gpio     PA1-15:main     PA2-15:main     PA3-15:main     PA4-15:main     PA5-15:main     PA6-15:gpio

  30. // 这种寄存器直接读写操作,不会有任何的提示和警告
复制代码



11

主题

63

回帖

447

积分

超级版主

积分
447
发表于 2024-7-11 09:14:10 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Discuz! X

GMT+8, 2024-11-23 16:13 , Processed in 0.083412 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表