zynq linux下的gpio应用实践_zynq linux环境下使用pl gpio(1)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

本文参考ALINX黑金教程,并在开发板上验证通过。
https://blog.csdn.net/spark550/article/details/52043792?locationNum=8&fps=1

我们首先应该在zynq Linux环境下通过sysfs的方式确定gpio的编号,在控制成功后,才可以在应用程序中读写设备文件从而达到控制GPIO的目的。

一、sysfs方式控制GPIO
二、编写GPIO应用程序

在上一部分,我们验证发现,gpio897正是PL LED的第一个LED。因此接下来的应用程序都是读写gpio897的设备文件。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>


// The specific GPIO being used must be setup and replaced thru
// this code. The GPIO of 897 is in the path of most the sys dirs
// and in the export write.
//
// Figuring out the exact GPIO was not totally obvious when there
// were multiple GPIOs in the system. One way to do is to go into
// the gpiochips in /sys/class/gpio and view the label as it should
// reflect the address of the GPIO in the system. The name of the
// the chip appears to be the 1st GPIO of the controller.
//
// The export causes the gpio897 dir to appear in /sys/class/gpio.
// Then the direction and value can be changed by writing to them.

// The performance of this is pretty good, using a nfs mount,
// running on open source linux, 
// the GPIO can be toggled about every 1sec.
// The following commands from the console setup the GPIO to be
// exported, set the direction of it to an output and write a 1
// to the GPIO.
//
// bash> echo 897 > /sys/class/gpio/export
// bash> echo out > /sys/class/gpio/gpio897/direction
// bash> echo 1 > /sys/class/gpio/gpio897/value

// if sysfs is not mounted on your system, the you need to mount it
// bash> mount -t sysfs sysfs /sys

// the following bash script to toggle the gpio is also handy for
// testing
//
// while [ 1 ]; do
// echo 1 > /sys/class/gpio/gpio897/value
// echo 0 > /sys/class/gpio/gpio897/value
// done

// to compile this, use the following command
// gcc gpio.c -o gpio

// The kernel needs the following configuration to make this work.
//
// CONFIG\_GPIO\_SYSFS=y
// CONFIG\_SYSFS=y
// CONFIG\_EXPERIMENTAL=y
// CONFIG\_GPIO\_XILINX=y

int main()
{
    int valuefd, exportfd, directionfd;

    printf("GPIO test running...\n");

    // The GPIO has to be exported to be able to see it
    // in sysfs

    exportfd = open("/sys/class/gpio/export", O_WRONLY);
    if (exportfd < 0)
    {
        printf("Cannot open GPIO to export it\n");
        exit(1);
    }

    write(exportfd, "897", 4);
    close(exportfd);

    printf("GPIO exported successfully\n");

    // Update the direction of the GPIO to be an output

    directionfd = open("/sys/class/gpio/gpio897/direction", O_RDWR);
    if (directionfd < 0)
    {
        printf("Cannot open GPIO direction it\n");
        exit(1);
    }

    write(directionfd, "out", 4);
    close(directionfd);

    printf("GPIO direction set as output successfully\n");

    // Get the GPIO value ready to be toggled

    valuefd = open("/sys/class/gpio/gpio897/value", O_RDWR);
    if (valuefd < 0)
    {
        printf("Cannot open GPIO value\n");
        exit(1);
    }

    printf("GPIO value opened, now toggling...\n");

    // toggle the GPIO as fast a possible forever, a control c is needed
    // to stop it

    while (1)
    {
        write(valuefd,"1", 2);
        sleep(1);
        write(valuefd,"0", 2);
        sleep(1);       
    }
}

这里我使用的是petalinux的方式编译应用程序,当然你也可以通过其他方式进行编译(比如arm-xinlinx-linux-gcc)等。

编译通过后生成arm架构的应用程序,通过网络共享的方式在ARM平台上运行。

三、解决软连接问题

在修改应用程序权限为可执行程序后,发现报错为不存在。可是明明文件就在当前目录下,那么我们就需要排查是否是缺失库问题。
运行命令 file plkey


plkey: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=9890fd4041c0507eca6d75fa3f39971dbcd6f42b, stripped

或者更详细的检查:
运行命令 readelf plkey -h

ELF 头:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF32
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              EXEC (可执行文件)
  系统架构:                          ARM
  版本:                              0x1
  入口点地址:               0x10538
  程序头起点:          52 (bytes into file)
  Start of section headers: 2728 (bytes into file)
 标志: 0x5000402, Version5 EABI, hard-float ABI, <unknown>
 本头的大小: 52 (字节)
 程序头大小: 32 (字节)
 Number of program headers: 8
 节头大小: 40 (字节)
 节头数量: 28
 字符串表索引节头: 27

节头:
 [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
 [ 0] NULL 00000000 000000 000000 00 0 0 0
 [ 1] .interp PROGBITS 00010134 000134 000019 00 A 0 0 1
 [ 2] .note.ABI-tag NOTE 00010150 000150 000020 00 A 0 0 4
 [ 3] .note.gnu.build-i NOTE 00010170 000170 000024 00 A 0 0 4
 [ 4] .gnu.hash GNU\_HASH 00010194 000194 00006c 04 A 5 0 4
 [ 5] .dynsym DYNSYM 00010200 000200 0000a0 10 A 6 1 4
 [ 6] .dynstr STRTAB 000102a0 0002a0 00005d 00 A 0 0 1
 [ 7] .gnu.version VERSYM 000102fe 0002fe 000014 02 A 5 0 2
 [ 8] .gnu.version\_r VERNEED 00010314 000314 000020 00 A 6 1 4
 [ 9] .rel.dyn REL 00010334 000334 000008 08 A 5 0 4
 [10] .rel.plt REL 0001033c 00033c 000048 08 AI 5 12 4
 [11] .init PROGBITS 00010384 000384 00000c 00 AX 0 0 4
 [12] .plt PROGBITS 00010390 000390 000080 04 AX 0 0 4
 [13] .text PROGBITS 00010410 000410 0002c0 00 AX 0 0 4
 [14] .fini PROGBITS 000106d0 0006d0 000008 00 AX 0 0 4
 [15] .rodata PROGBITS 000106d8 0006d8 00014c 00 A 0 0 4
 [16] .ARM.exidx ARM\_EXIDX 00010824 000824 000008 00 AL 13 0 4
 [17] .eh\_frame PROGBITS 0001082c 00082c 000004 00 A 0 0 4
 [18] .init\_array INIT\_ARRAY 00020830 000830 000004 00 WA 0 0 4
 [19] .fini\_array FINI\_ARRAY 00020834 000834 000004 00 WA 0 0 4
 [20] .jcr PROGBITS 00020838 000838 000004 00 WA 0 0 4
 [21] .dynamic DYNAMIC 0002083c 00083c 0000e8 08 WA 6 0 4
 [22] .got PROGBITS 00020924 000924 000034 04 WA 0 0 4
 [23] .data PROGBITS 00020958 000958 000008 00 WA 0 0 4
 [24] .bss NOBITS 00020960 000960 000004 00 WA 0 0 1
 [25] .ARM.attributes ARM\_ATTRIBUTES 00000000 000960 000039 00 0 0 1
 [26] .gnu\_debuglink PROGBITS 00000000 000999 00000c 00 0 0 1
 [27] .shstrtab STRTAB 00000000 0009a5 000100 00 0 0 1
Key to Flags:
 W (write), A (alloc), X (execute), M (merge), S (strings)
 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
 O (extra OS processing required) o (OS specific), p (processor specific)

There are no section groups in this file.

程序头:
 Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
 EXIDX 0x000824 0x00010824 0x00010824 0x00008 0x00008 R 0x4
 PHDR 0x000034 0x00010034 0x00010034 0x00100 0x00100 R E 0x4
 INTERP 0x000134 0x00010134 0x00010134 0x00019 0x00019 R 0x1
 [Requesting program interpreter: /lib/ld-linux-armhf.so.3]
 LOAD 0x000000 0x00010000 0x00010000 0x00830 0x00830 R E 0x10000
 LOAD 0x000830 0x00020830 0x00020830 0x00130 0x00134 RW 0x10000
 DYNAMIC 0x00083c 0x0002083c 0x0002083c 0x000e8 0x000e8 RW 0x4
 NOTE 0x000150 0x00010150 0x00010150 0x00044 0x00044 R 0x4
 GNU\_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10

 Section to Segment mapping:
 段节...
 00 .ARM.exidx 
 01 
 02 .interp 
 03 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version\_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .ARM.exidx .eh\_frame 
 04 .init\_array .fini\_array .jcr .dynamic .got .data .bss 
 05 .dynamic 
 06 .note.ABI-tag .note.gnu.build-id 
 07 

Dynamic section at offset 0x83c contains 24 entries:
 标记 类型 名称/值
 0x00000001 (NEEDED) 共享库:[libc.so.6]
 0x0000000c (INIT) 0x10384
 0x0000000d (FINI) 0x106d0
 0x00000019 (INIT\_ARRAY) 0x20830
 0x0000001b (INIT\_ARRAYSZ) 4 (bytes)
 0x0000001a (FINI\_ARRAY) 0x20834
 0x0000001c (FINI\_ARRAYSZ) 4 (bytes)
 0x6ffffef5 (GNU\_HASH) 0x10194
 0x00000005 (STRTAB) 0x102a0
 0x00000006 (SYMTAB) 0x10200
 0x0000000a (STRSZ) 93 (bytes)
 0x0000000b (SYMENT) 16 (bytes)
 0x00000015 (DEBUG) 0x0
 0x00000003 (PLTGOT) 0x20924
 0x00000002 (PLTRELSZ) 72 (bytes)
 0x00000014 (PLTREL) REL
 0x00000017 (JMPREL) 0x1033c
 0x00000011 (REL) 0x10334
 0x00000012 (RELSZ) 8 (bytes)
 0x00000013 (RELENT) 8 (bytes)
 0x6ffffffe (VERNEED) 0x10314
 0x6fffffff (VERNEEDNUM) 1
 0x6ffffff0 (VERSYM) 0x102fe
 0x00000000 (NULL) 0x0

重定位节 '.rel.dyn' 位于偏移量 0x334 含有 1 个条目:
 偏移量 信息 类型 符号值 符号名称
00020954 00000115 R\_ARM\_GLOB\_DAT 00000000 \_\_gmon\_start\_\_

重定位节 '.rel.plt' 位于偏移量 0x33c 含有 9 个条目:
 偏移量 信息 类型 符号值 符号名称


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以点击这里获取!](https://bbs.csdn.net/topics/618635766)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
xlnx,zynq7k-Gpio是指Xilinx Zynq-7000系列的FPGA芯片中的通用输入/输出(GPIO)引脚。这些引脚可以配置为输入或输出,并用于与外部设备进行通信。根据引用,配置MIO47、MIO48和MIO49为GPIO时,需要向特定的寄存器写入特定的值。具体来说,使用XLNX_ZYNQ7K_SR_REGISTER_WRITE宏将0xF80007BC地址处的寄存器设置为0x00001600,以配置MIO47为GPIO;将0xF80007C0地址处的寄存器设置为0x00001600,以配置MIO48为GPIO;将0xF80007C4地址处的寄存器设置为0x00001600,以配置MIO49为GPIO。 根据引用,设置dir和oen变量的某些位,以配置MIO32到MIO53之间的引脚为GPIO。通过将0x34000的对应位设置为1,可以将这些引脚配置为输出。具体的寄存器地址和写入值可以根据系统的具体情况进行配置。 需要注意的是,以上引用提供的代码片段可能是在特定的开发环境使用的,具体的配置和操作方式可能会因实际情况而异。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Xilinx zynq7000,zynq7k上GPIO使用笔记](https://blog.csdn.net/ambercctv/article/details/78328286)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值