zynq linux下的gpio应用实践
INCLUDEPATH += /usr/local/qwt-6.1.3/includeLIBS += -L “/usr/local/qwt-6.1.3/lib/” -lqwt
本文参考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
更多推荐
所有评论(0)