MPSoC 为PL提供了96个GPIO,通过EMIO管脚链接到PL。
普通PL设计,一般只会用到几个GPIO管脚。可以使用Vivado IPI中的Slice IP, 从其中分出指定数量的管脚。
Slice配置界面
上图中,输入宽度是95,因为pl_reset占用率一个管脚。slice从输入中提取emio的[7:5]三位,作为输出。
Xilinx Linux 中缺省使能了GPIO驱动。对于MPSoC,检查目录/sys/class/gpio,可以看到设备gpiochip338。
# ls -l /sys/class/gpio
total 0
export
gpiochip306 -> ../../devices/platform/amba/ff020000.i2c/i2c-0/0-0021/gpio/gpiochip306
gpiochip322 -> ../../devices/platform/amba/ff020000.i2c/i2c-0/0-0020/gpio/gpiochip322
gpiochip338 -> ../../devices/platform/amba/ff0a0000.gpio/gpio/gpiochip338
unexport
# ls /sys/class/gpio/gpiochip338/ -l
total 0
base
device -> ../../../ff0a0000.gpio
label
ngpio
power
subsystem -> ../../../../../../class/gpio
uevent
Linux GPIO Driver下的GPIO使用,可以参考Linux GPIO Driver;GPIO User Space App。
从上述文章可以看到,使用GPIO不简单。为了
为了简化使用GPIO,编写了以下脚本。使用下列脚本,一条命令就能设置一个GPIO的输出值。脚本接受两个输入参数。第一个参数表示GPIO编号,MIO GPIO从0开始,EMIO GPIO从78开始。第二个参数是输出值。如果输出值是1,可以省略第二个参数。
#/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
执行记录
# ./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