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

我们首先应该在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 个条目:
 偏移量 信息 类型 符号值 符号名称
00020930 00000316 R\_ARM\_JUMP\_SLOT 00000000 sleep@GLIBC\_2.4
00020934 00000216 R\_ARM\_JUMP\_SLOT 00000000 puts@GLIBC\_2.4
00020938 00000816 R\_ARM\_JUMP\_SLOT 00000000 \_\_libc\_start\_main@GLIBC\_2.4
0002093c 00000116 R\_ARM\_JUMP\_SLOT 00000000 \_\_gmon\_start\_\_
00020940 00000516 R\_ARM\_JUMP\_SLOT 00000000 open@GLIBC\_2.4
00020944 00000416 R\_ARM\_JUMP\_SLOT 00000000 exit@GLIBC\_2.4
00020948 00000716 R\_ARM\_JUMP\_SLOT 00000000 write@GLIBC\_2.4
0002094c 00000916 R\_ARM\_JUMP\_SLOT 00000000 abort@GLIBC\_2.4
00020950 00000616 R\_ARM\_JUMP\_SLOT 00000000 close@GLIBC\_2.4

Unwind table index '.ARM.exidx' at offset 0x824 contains 1 entries:


为了做好运维面试路上的助攻手,特整理了上百道 **【运维技术栈面试题集锦】** ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,**小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。**

![](https://img-blog.csdnimg.cn/img_convert/cfaf24df90ee445bc583025268cb4cee.png)

本份面试集锦涵盖了

*   **174 道运维工程师面试题**
*   **128道k8s面试题**
*   **108道shell脚本面试题**
*   **200道Linux面试题**
*   **51道docker面试题**
*   **35道Jenkis面试题**
*   **78道MongoDB面试题**
*   **17道ansible面试题**
*   **60道dubbo面试题**
*   **53道kafka面试**
*   **18道mysql面试题**
*   **40道nginx面试题**
*   **77道redis面试题**
*   **28道zookeeper**

**总计 1000+ 道面试题, 内容 又全含金量又高**

*   **174道运维工程师面试题**

> 1、什么是运维?

> 2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

> 3、现在给你三百台服务器,你怎么对他们进行管理?

> 4、简述raid0 raid1raid5二种工作模式的工作原理及特点

> 5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

> 6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

> 7、Tomcat和Resin有什么区别,工作中你怎么选择?

> 8、什么是中间件?什么是jdk?

> 9、讲述一下Tomcat8005、8009、8080三个端口的含义?

> 10、什么叫CDN?

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

别?工作中你怎么选择?

> 6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

> 7、Tomcat和Resin有什么区别,工作中你怎么选择?

> 8、什么是中间件?什么是jdk?

> 9、讲述一下Tomcat8005、8009、8080三个端口的含义?

> 10、什么叫CDN?

> 11、什么叫网站灰度发布?

> 12、简述DNS进行域名解析的过程?

> 13、RabbitMQ是什么东西?

> 14、讲一下Keepalived的工作原理?

> 15、讲述一下LVS三种模式的工作过程?

> 16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

> 17、如何重置mysql root密码?
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值