本文参考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 个条目:
 偏移量     信息    类型              符号值      符号名称
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:

0x10538: 0x1 [cantunwind]


Symbol table '.dynsym' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.4 (2)
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND sleep@GLIBC_2.4 (2)
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND exit@GLIBC_2.4 (2)
     5: 00000000     0 FUNC    GLOBAL DEFAULT  UND open@GLIBC_2.4 (2)
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND close@GLIBC_2.4 (2)
     7: 00000000     0 FUNC    GLOBAL DEFAULT  UND write@GLIBC_2.4 (2)
     8: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.4 (2)
     9: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort@GLIBC_2.4 (2)

Histogram for `.gnu.hash' bucket list length (total of 13 buckets):
 Length  Number     % of total  Coverage
      0  5          ( 38.5%)
      1  8          ( 61.5%)    100.0%

Version symbols section '.gnu.version' contains 10 entries:
 地址: 00000000000102fe  Offset: 0x0002fe  Link: 5 (.dynsym)
  000:   0 (*本地*)       0 (*本地*)       2 (GLIBC_2.4)     2 (GLIBC_2.4)  
  004:   2 (GLIBC_2.4)     2 (GLIBC_2.4)     2 (GLIBC_2.4)     2 (GLIBC_2.4)  
  008:   2 (GLIBC_2.4)     2 (GLIBC_2.4)  

Version needs section '.gnu.version_r' contains 1 entries:
 地址:0x0000000000010314  Offset: 0x000314  Link: 6 (.dynstr)
  000000: 版本: 1  文件:libc.so.6  计数:1
  0x0010:名称:GLIBC_2.4  标志:无  版本:2

Displaying notes found at file offset 0x00000150 with length 0x00000020:
  Owner                 Data size   Description
  GNU                  0x00000010   NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 2.6.32

Displaying notes found at file offset 0x00000170 with length 0x00000024:
  Owner                 Data size   Description
  GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 9890fd4041c0507eca6d75fa3f39971dbcd6f42b
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "7-A"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_FP_arch: VFPv3
  Tag_Advanced_SIMD_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_rounding: Needed
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align_needed: 8-byte
  Tag_ABI_align_preserved: 8-byte, except leaf SP
  Tag_ABI_enum_size: int
  Tag_ABI_VFP_args: VFP registers
  Tag_CPU_unaligned_access: v6
  Tag_MPextension_use: Allowed
  Tag_Virtualization_use: TrustZone

我们发现中间出现一行

 [Requesting program interpreter: /lib/ld-linux-armhf.so.3]

说明运行该文件需要/lib/ld-linux-armhf.so.3文件。

接下来,我们在arm平台的ls /lib 查看可使用的库文件。

这里使用arm平台下ld-2.21.so来“替代”程序本身所需的文件ld-linux-armhf.so.3。
使用软连接的方式。

ln -s  当前arm平台已存在的文件    程序所需缺失的文件

然后,重新运行程序就可以啦。

INCLUDEPATH += /usr/local/qwt-6.1.3/include
LIBS += -L “/usr/local/qwt-6.1.3/lib/” -lqwt

https://blog.csdn.net/woshidahuaidan2011/article/details/43604059

Logo

更多推荐