跳转到主要内容

【分享】在PL设计中使用MPSoC EMIO GPIO,并使用脚本设置MPSoC EMIO GPIO

judy 提交于

作者:付汉杰,<a href="mailto:hankf@xilinx.com">hankf@xilinx.com</a&gt;,文章转载自:<a id="link_3" href="https://forums.xilinx.com/t5/%E5%B5%8C%E5%85%A5%E5%BC%8F-%E5%B7%A5%E5%8…;

MPSoC 为PL提供了96个GPIO,通过EMIO管脚链接到PL。

普通PL设计,一般只会用到几个GPIO管脚。可以使用Vivado IPI中的Slice IP, 从其中分出指定数量的管脚。
<center><img src="http://xilinx.eetrend.com/files/2020-08/wen_zhang_/100050920-103985-1.p…; alt=""></center>
<p align="center"><strong>Slice配置界面</strong></p>

上图中,输入宽度是95,因为pl_reset占用率一个管脚。slice从输入中提取emio的[7:5]三位,作为输出。

Xilinx Linux 中缺省使能了GPIO驱动。对于MPSoC,检查目录/sys/class/gpio,可以看到设备gpiochip338。
<pre># ls -l /sys/class/gpio
total 0
export
gpiochip306 -&gt; ../../devices/platform/amba/ff020000.i2c/i2c-0/0-0021/gpio/gpiochip306
gpiochip322 -&gt;../../devices/platform/amba/ff020000.i2c/i2c-0/0-0020/gpio/gpiochip322
gpiochip338 -&gt; ../../devices/platform/amba/ff0a0000.gpio/gpio/gpiochip338
unexport

# ls /sys/class/gpio/gpiochip338/ -l
total 0
base
device -&gt; ../../../ff0a0000.gpio
label
ngpio
power
subsystem -&gt; ../../../../../../class/gpio
uevent</pre>

Linux GPIO Driver下的GPIO使用,可以参考<a href="https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842398/Linux+GP…; target="_blank" rel="nofollow noopener noreferrer">Linux GPIO Driver</a>;<a href="https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842142/GPIO+Use…; target="_blank" rel="nofollow noopener noreferrer">GPIO User Space App</a>。

从上述文章可以看到,使用GPIO不简单。

为了简化使用GPIO,编写了以下脚本。使用下列脚本,一条命令就能设置一个GPIO的输出值。脚本接受两个输入参数。第一个参数表示GPIO编号,MIO GPIO从0开始,EMIO GPIO从78开始。第二个参数是输出值。如果输出值是1,可以省略第二个参数。
<pre>
#/bin/bash

function gpio_output_func()
{

#echo "No.1 parameter: $1"
#echo "No.2 parameter: $2"

# MPSoC GPIO number.
gpio_num=$[338+$1]

# MPSoC EMIO GPIO number.
# gpio_num=$[338+78+$1]

echo "Set GPIO number: $gpio_num to value: $2"

if [ ! -f /sys/class/gpio/gpio$gpio_num/direction ]; then
# Export a GPIO pin
echo $gpio_num > /sys/class/gpio/export
fi

# Read the direction and value from the GPIO pin */
# ls -l /sys/class/gpio/gpio$gpio_num/

gpio_direction=`cat /sys/class/gpio/gpio$gpio_num/direction`
gpio_value=`cat /sys/class/gpio/gpio$gpio_num/value`
echo -e "GPIO number: $gpio_num previous direction: $gpio_direction, previous value: $gpio_value\b"

# Set the direction to an output and write a value 1 to GPIO pin */
echo out > /sys/class/gpio/gpio$gpio_num/direction
echo $2 > /sys/class/gpio/gpio$gpio_num/value

gpio_direction=`cat /sys/class/gpio/gpio$gpio_num/direction`
gpio_value=`cat /sys/class/gpio/gpio$gpio_num/value`
echo -e "GPIO number: $gpio_num current direction: $gpio_direction, current value: $gpio_value\b"

}

# Check GPIO chip
gpio_chip=`cat /sys/class/gpio/gpiochip338/label`
gpio_base=`cat /sys/class/gpio/gpiochip338/base`
gpio_number=`cat /sys/class/gpio/gpiochip338/ngpio`
echo "MPSoC GPIO information: chip: $gpio_chip, base: $gpio_base, number: $gpio_number."
# cat /sys/class/gpio/gpiochip338/label
# cat /sys/class/gpio/gpiochip338/base
# cat /sys/class/gpio/gpiochip338/ngpio
# The above line indicates that gpio 0th pin starts from 338 and ends at 511 (GPIO has total 174 pins for ZynqMP)

if [ "$2" = "" ]; then
gpio_output_func $1 1
else
gpio_output_func $1 $2
fi
</pre>

执行记录
<pre># ./gpio_single_output.sh 81
MPSoC GPIO information: chip: zynqmp_gpio, base: 338, number: 174.
Set GPIO number: 419 to value: 1
GPIO number: 419 previous direction: out, previous value: 0
GPIO number: 419 current direction: out, current value: 1

# ./gpio_single_output.sh 81 0
MPSoC GPIO information: chip: zynqmp_gpio, base: 338, number: 174.
Set GPIO number: 419 to value: 0
GPIO number: 419 previous direction: out, previous value: 1
GPIO number: 419 current direction: out, current value: 0</pre>

<center><img src="http://xilinx.eetrend.com/files/2020-08/wen_zhang_/100050920-103986-2.p…; alt=""></center>