概述
GPIO LED AND KEY:
part1:gpio leds and gpio btns combination. (include 1~4)
part2:use gpio btns interrupt to trigger led on and off. (include 5, 6, 7)
part3:some useful tips. (include 8)
my vivado & sdk projects ( ready to download):
1.custom_ip ( only led exists)
2.custom_ip ( led with key)
3.custom_ip (led key and interrupts)
my driver package ( ready to download):
gpio_driver.tar.bz2
(1)Block Design:
(2)Constraints:
set_property PACKAGE_PIN T22 [get_ports {leds_8bits_tri_o[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[0]}]
set_property PACKAGE_PIN T21 [get_ports {leds_8bits_tri_o[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[1]}]
set_property PACKAGE_PIN U22 [get_ports {leds_8bits_tri_o[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[2]}]
set_property PACKAGE_PIN U21 [get_ports {leds_8bits_tri_o[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[3]}]
set_property PACKAGE_PIN V22 [get_ports {leds_8bits_tri_o[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[4]}]
set_property PACKAGE_PIN W22 [get_ports {leds_8bits_tri_o[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[5]}]
set_property PACKAGE_PIN U19 [get_ports {leds_8bits_tri_o[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[6]}]
set_property PACKAGE_PIN U14 [get_ports {leds_8bits_tri_o[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[7]}]
set_property PACKAGE_PIN P16 [get_ports {btns_5bits_tri_i[0]}]
set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[0]}]
set_property PACKAGE_PIN N15 [get_ports {btns_5bits_tri_i[2]}]
set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[2]}]
set_property PACKAGE_PIN T18 [get_ports {btns_5bits_tri_i[4]}]
set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[4]}]
set_property PACKAGE_PIN R18 [get_ports {btns_5bits_tri_i[3]}]
set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[3]}]
set_property PACKAGE_PIN R16 [get_ports {btns_5bits_tri_i[1]}]
set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[1]}]
(3) Standalone Program
#include <stdio.h>
#include "platform.h"
#include "xil_io.h"
#include "xgpio.h"
#include "xparameters.h"
//void print(char *str);
int main()
{
init_platform();
print("Hello Worldnr");
u32 btn_data;
//XGpio
//btn_data = Xil_In32(0x41200000);
// printf("data is xxx %dn",btn_data);
Xil_Out32(0x41200000 , 0x08);
sleep(1);
//Xil_Out32(0x41200000 , 0x00);
while(1){
//Xil_Out32(0x41210000 , 0x00000000);
btn_data = Xil_In32(0x41210000);
//if(btn_data & 0x01){
//Xil_Out32(0x41210000 , 0x01);
sleep(1);
printf("data is %ldn",btn_data);
//}
/*if(btn_data & 0x00000001)
Xil_Out32(0x41200000 , 0x01);
if(btn_data & 0x00000002)
Xil_Out32(0x41200000 , 0x02);
if(btn_data & 0x00000004)
Xil_Out32(0x41200000 , 0x04);
if(btn_data & 0x00000008)
Xil_Out32(0x41200000 , 0x08);
*/
}
//sleep(1);
return 0;
}
(4) Linux Driver:
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/wait.h>
#include <linux/cdev.h>
#define DEVICE_NAME "gpio_dev"
#define LED_PHY_ADDR 0x41200000
#define KEY_PHY_ADDR 0X41210000
/*
#define ULTRASONIC_IOC_MAGIC 'Z'
#define LED_SHUTDOWN _IOR(ULTRASONIC_IOC_MAGIC, 0, int)
#define LED_OPEN _IOR(ULTRASONIC_IOC_MAGIC, 1, int)
#define GET_KEY_STATUS _IOR(ULTRASONIC_IOC_MAGIC, 2, int)
*/
static unsigned long led_addr = 0;
static unsigned long key_addr = 0;
static struct class* gpio_class = NULL;
static struct device* gpio_device = NULL;
static int gpio_major = 0;
//arg means the led number, cmd controls it on or off
static ssize_t gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
//printk("fun(gpio_ioctl):");
u32 status = 0xff;
int ret;
switch(cmd){
case 0:
case 1:
//if(arg > 8)
// return -EINVAL;
status = ioread32(led_addr);
if(0 == cmd)
status &= ~(0x1 << arg);
else if(1 == cmd)
status |= (0x1 << arg);
iowrite32(status,led_addr);
//printk("debug1 cmd= %dn",cmd);
return 0;
case 3:
//printk("debug3 cmd=%dn",cmd);
status = ioread32(key_addr);
ret = __put_user(status, (u32 *)arg);
printk("key print = 0x%xn",status);
return 0;
default:
printk("default cmd=%dn",cmd);
return -EINVAL;
}
}
/*
static ssize_t key_read(struct file *file,u32 __user *buf, size_t count, loff_t *ppos)
{
u32 data;
int ret = 0;
data = ioread32(key_addr);
ret = __put_user(data, (u32 *)buf);
printk("key print = 0x%xn",data);
return (sizeof(u32));
}
*/
static struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = gpio_ioctl,
// .read = key_read,
};
static int __init gpio_init(void)
{
int ret;
printk("debug0");
ret = register_chrdev(0,DEVICE_NAME, &gpio_fops);
if(ret < 0)
{
printk("gpio: can't get major numbern");
return ret;
}
printk("debug1");
gpio_major = ret;
gpio_class = class_create(THIS_MODULE, "gpio_class");
if(IS_ERR(gpio_class))
{
printk("gpio: failed in creating classn");
unregister_chrdev(gpio_major, DEVICE_NAME);
return -1;
}
printk("debug2");
gpio_device = device_create(gpio_class,NULL,MKDEV(gpio_major,0),NULL,DEVICE_NAME);
if(IS_ERR(gpio_device))
{
printk("gpio: failed in creating device!n");
unregister_chrdev(gpio_major, DEVICE_NAME);
class_unregister(gpio_class);
class_destroy(gpio_class);
return -1;
}
led_addr = (unsigned long) ioremap(LED_PHY_ADDR, sizeof(u32));
key_addr = (unsigned long) ioremap(KEY_PHY_ADDR, sizeof(u32));
/*
iowrite32(0x00,led_addr);
mdelay(100);
iowrite32(0xff,led_addr);
*/
printk("gpio installed successfully!");
return 0;
}
static void __exit gpio_exit(void)
{
/*
iowrite32(0x00,led_addr);
mdelay(100);
iowrite32(0xff,led_addr);
*/
device_destroy(gpio_class,MKDEV(gpio_major, 0));
class_unregister(gpio_class);
class_destroy(gpio_class);
unregister_chrdev(gpio_major,DEVICE_NAME);
printk("gpio module exit!");
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_AUTHOR("seg");
MODULE_LICENSE("GPL");
(5) Linux App:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
static int led_fd;
int main(void)
{
int i;
// open device
led_fd = open("/dev/gpio_dev", 0);
if (led_fd < 0) {
perror("open device gpio_dev error!n");
exit(1);
}
printf("Please look at the ledsn");
// led all off
ioctl(led_fd, 1, 0);
ioctl(led_fd, 1, 1);
ioctl(led_fd, 1, 2);
ioctl(led_fd, 1, 3);
ioctl(led_fd, 1, 4);
ioctl(led_fd, 1, 5);
ioctl(led_fd, 1, 6);
ioctl(led_fd, 1, 7);
for(i=0;i<2;i++)
{
ioctl(led_fd, 0, 0);
usleep(50000);
ioctl(led_fd, 0, 1);
usleep(50000);
ioctl(led_fd, 0, 2);
usleep(50000);
ioctl(led_fd, 0, 3);
usleep(50000);
ioctl(led_fd, 0, 4);
usleep(50000);
ioctl(led_fd, 0, 5);
usleep(50000);
ioctl(led_fd, 0, 6);
usleep(50000);
ioctl(led_fd, 0, 7);
usleep(50000);
// led off one by one
ioctl(led_fd, 1, 0);
usleep(50000);
ioctl(led_fd, 1, 1);
usleep(50000);
ioctl(led_fd, 1, 2);
usleep(50000);
ioctl(led_fd, 1, 3);
usleep(50000);
ioctl(led_fd, 1, 4);
usleep(50000);
ioctl(led_fd, 1, 5);
usleep(50000);
ioctl(led_fd, 1, 6);
usleep(50000);
ioctl(led_fd, 1, 7);
usleep(50000);
}
while(1)
{
unsigned int key = 0;
//printf("original = %d , %x",key,key);
ioctl(led_fd, 3, &key);
printf("key = %dn",key);
for(i=0;i<8;i++)
ioctl(led_fd,0,i);
if(key & (0x01<<0))
ioctl(led_fd, 1, 0);
else if(key & (0x01<<1))
ioctl(led_fd, 1, 1);
else if(key & (0x01<<2))
ioctl(led_fd, 1, 2);
else if(key & (0x01<<3))
ioctl(led_fd, 1, 3);
else if(key & (0x01<<4))
ioctl(led_fd, 1, 4);
else{}
usleep(1000000);
}
close(led_fd);
return 0;
}
(5)Hardware Interrupt Vivado Project
(6)Hardware Interrupt SDK Project
#include "xparameters.h"
#include "xgpio.h"
#include "xil_exception.h"
#include "xscugic.h"
/************************** Constant Definitions *****************************/
#define LED_ADDR 0x41200000
#define KEY_ADDR 0X41210000
#define GPIO_DEVICE_ID XPAR_AXI_GPIO_1_DEVICE_ID
#define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_GPIO_1_VEC_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
#define INTC XScuGic
#define INTC_HANDLER XScuGic_InterruptHandler
#define GPIO_ALL_LEDS 0xFFFF
#define GPIO_ALL_BUTTONS 0xFFFF
/*
* The following constants define the GPIO channel that is used for the buttons
* and the LEDs. They allow the channels to be reversed easily.
*/
#define BUTTON_CHANNEL 1 /* Channel 1 of the GPIO Device */
#define LED_CHANNEL 2 /* Channel 2 of the GPIO Device */
#define BUTTON_INTERRUPT XGPIO_IR_CH1_MASK /* Channel 1 Interrupt Mask */
/*
* The following constant is used to wait after an LED is turned on to make
* sure that it is visible to the human eye. This constant might need to be
* tuned for faster or slower processor speeds.
*/
#define LED_DELAY 1000000
/**************************** Type Definitions *******************************/
typedef struct
{
u32 ButtonMask; /* The bit corresponding to the button */
u32 LedMask; /* The bit corresponding to the LED */
} MapButtonTable;
/************************** Function Prototypes ******************************/
int MapButton2Led(u32 Buttons, u32 *ButtonFoundPtr);
void SequenceLeds();
void GpioIsr(void *InstancePtr);
int SetupInterruptSystem();
/************************** Variable Definitions *****************************/
static XGpio Gpio; /* The Instance of the GPIO Driver */
static INTC Intc; /* The Instance of the Interrupt Controller Driver */
volatile int InterruptCount; /* Count of interrupts that have occured */
int main(void)
{
int Status;
SequenceLeds();
/* Initialize the GPIO driver. If an error occurs then exit */
Status = XGpio_Initialize(&Gpio, GPIO_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test on the GPIO. This is a minimal test and only
* verifies that there is not any bus error when reading the data
* register
*/
XGpio_SelfTest(&Gpio);
/*
* Setup the interrupts such that interrupt processing can occur. If
* an error occurs then exit
*/
Status = SetupInterruptSystem();
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
printf("in the loop:n");
while (1) {
}
return XST_SUCCESS;
}
void SequenceLeds()
{
u32 led = 0x01;
u32 out = 0x0;
int i;
for (i = 0; i < 8; i++) {
out = led << i;
Xil_Out32(LED_ADDR, out);
sleep(1);
}
Xil_Out32(LED_ADDR, 0x00);
}
/********************************************************************************************************************************************************/
void GpioIsr(void *InstancePtr)
{
XGpio *GpioPtr = (XGpio *)InstancePtr;
u32 Led;
u32 LedState;
u32 Buttons;
u32 ButtonFound;
u32 ButtonsChanged = 0;
static u32 PreviousButtons;
printf("Enter GpioIsr!n");
/*
* Disable the interrupt
*/
XGpio_InterruptDisable(GpioPtr, BUTTON_INTERRUPT);
/* Keep track of the number of interrupts that occur */
InterruptCount++;
Xil_Out32(LED_ADDR,0x00);
ButtonsChanged = Xil_In32(KEY_ADDR);
printf("BUTTON:%d;",ButtonsChanged);
//while (ButtonsChanged != 0) {
/*
* Determine which button changed state and then get
* the current state of the associated LED
*/
printf("SET_LED=%d",ButtonsChanged);
Xil_Out32(LED_ADDR,ButtonsChanged);
// LedState = Xil_In32(LED_ADDR) & Led;
/*
* Clear the button that is being processed so that it is
* done and others can be handled also
*/
// ButtonsChanged &= ~ButtonFound;
/* Toggle the state of the LED */
// if (LedState) {
// Xil_Out32(LED_ADDR,LedState & ~Led);
// } else {
// Xil_Out32(LED_ADDR,Led);
// }
// }
/* Clear the interrupt such that it is no longer pending in the GPIO */
(void)XGpio_InterruptClear(GpioPtr, BUTTON_INTERRUPT);
/*
* Enable the interrupt
*/
XGpio_InterruptEnable(GpioPtr, BUTTON_INTERRUPT);
}
int SetupInterruptSystem()
{
int Result;
INTC *IntcInstancePtr = &Intc;
XScuGic_Config *IntcConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == IntcConfig) {
return XST_FAILURE;
}
Result = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);
if (Result != XST_SUCCESS) {
return XST_FAILURE;
}
XScuGic_SetPriorityTriggerType(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
0xA0, 0x3);
/*
* Connect the interrupt handler that will be called when an
* interrupt occurs for the device.
*/
Result = XScuGic_Connect(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
(Xil_ExceptionHandler)GpioIsr, &Gpio);
if (Result != XST_SUCCESS) {
return Result;
}
printf("XST_SUCCESS");
/*
* Enable the interrupt for the GPIO device.
*/
XScuGic_Enable(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID);
/*
* Enable the GPIO channel interrupts so that push button can be
* detected and enable interrupts for the GPIO device
*/
XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
XGpio_InterruptGlobalEnable(&Gpio);
/*
* Initialize the exception table and register the interrupt
* controller handler with the exception table
*/
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER, IntcInstancePtr);
/* Enable non-critical exceptions */
Xil_ExceptionEnable();
return XST_SUCCESS;
}
(7) Interrupt driver edition
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/wait.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>
#include <asm/signal.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#define DEVICE_NAME "gpio_dev"
#define GPIO_BASEADDR 0x41200000
#define LED_PHY_ADDR 0x41200000
#define KEY_PHY_ADDR 0X41210000
#define INTERRUPT_ID 91
#define IRQ_MASK 0x1
#define IRQ_DEVICE_ID 0
#define XGPIO_GIE_OFFSET 0x11C /**< Glogal interrupt enable register */
#define XGPIO_ISR_OFFSET 0x120 /**< Interrupt status register */
#define XGPIO_IER_OFFSET 0x128 /**< Interrupt enable register */
#define XGPIO_GIE_GINTR_ENABLE_MASK 0x80000000
//#define is_keypad_irq() (!(inb(IRQ_STAT_ADDR) & IRQ_MASK))
//#define disable_irq() (iowrite32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET,ioread32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET) & ~IRQ_MASK))
//#define enable_irq() (iowrite32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET,ioread32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET) | IRQ_MASK))
//#define clear_irq() (iowrite32(KEY_PHY_ADDR+XGPIO_IER_OFFSET,ioread32(KEY_PHY_ADDR+XGPIO_IER_OFFSET) & IRQ_MASK))
static unsigned long led_addr = 0;
static unsigned long key_addr = 0;
static struct class* gpio_class = NULL;
static struct device* gpio_device = NULL;
static int gpio_major = 0;
typedef struct {
dev_t dev_no;
u32 IsReady;
int InterruptPresent;
u32 BaseAddress;
// spinlock_t lock;
atomic_t lock;
} KEY_DEV;
static KEY_DEV keydev;
//arg means the led number, cmd controls it on or off
static ssize_t gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
//printk("fun(gpio_ioctl):");
u32 status = 0xff;
int ret;
switch(cmd){
case 0:
case 1:
//if(arg > 8)
// return -EINVAL;
status = ioread32(led_addr);
if(0 == cmd)
status &= ~(0x1 << arg);
else if(1 == cmd)
status |= (0x1 << arg);
iowrite32(status,led_addr);
return 0;
case 3:
status = ioread32(key_addr);
ret = __put_user(status, (u32 *)arg);
printk("key print = 0x%xn",status);
return 0;
default:
printk("default cmd=%dn",cmd);
return -EINVAL;
}
}
static void InterruptClear()
{
u32 val;
val = ioread32(key_addr + XGPIO_ISR_OFFSET);
iowrite32(val & IRQ_MASK,key_addr + XGPIO_ISR_OFFSET);
printk("int cleared");
}
static irqreturn_t key_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
u32 status = 0xff;
//disable_irq(INTERRUPT_ID);
// disable_irq();
status = ioread32(key_addr);
iowrite32(status,led_addr);
printk("key print = 0x%xn",status);
// clear_irq();
//enable_irq(INTERRUPT_ID);
// enable_irq();
InterruptClear();
return 0;
}
static void InterruptEnable()
{
//from stand alone program
//XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
//XGpio_InterruptGlobalEnable(&Gpio);
u32 val;
printk("debug1 read addr = %lxn",key_addr+XGPIO_IER_OFFSET);
// 0x128
val = ioread32(key_addr + XGPIO_IER_OFFSET);
printk("debug2 val=%lxn",val);
// 0x128 0x1
iowrite32(val | IRQ_MASK,key_addr + XGPIO_IER_OFFSET);
printk("debug3 ");
// 0x11c 0x80000000
iowrite32(XGPIO_GIE_GINTR_ENABLE_MASK,key_addr + XGPIO_GIE_OFFSET);
}
static int key_open(struct inode *inode, struct file *filp)
{
int ret;
printk("open!n");
InterruptEnable();
printk("interrupt Enabled!n");
ret = request_irq(INTERRUPT_ID, key_interrupt,IRQF_TRIGGER_RISING, DEVICE_NAME, &keydev);
if(ret)
{
printk("could not register interrupt!");
return ret;
}
//disable_irq(INTERRUPT_ID);
//enable_irq(INTERRUPT_ID);
// enable_irq();
printk("register interrupt success!n");
return 0;
}
static struct file_operations gpio_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = gpio_ioctl,
.open = key_open,
// .read = key_read,
};
static int __init gpio_init(void)
{
int ret;
ret = register_chrdev(0,DEVICE_NAME, &gpio_fops);
if(ret < 0)
{
printk("gpio: can't get major numbern");
return ret;
}
gpio_major = ret;
gpio_class = class_create(THIS_MODULE, "gpio_class");
if(IS_ERR(gpio_class))
{
printk("gpio: failed in creating classn");
unregister_chrdev(gpio_major, DEVICE_NAME);
return -1;
}
gpio_device = device_create(gpio_class,NULL,MKDEV(gpio_major,0),NULL,DEVICE_NAME);
if(IS_ERR(gpio_device))
{
printk("gpio: failed in creating device!n");
unregister_chrdev(gpio_major, DEVICE_NAME);
class_unregister(gpio_class);
class_destroy(gpio_class);
return -1;
}
led_addr = (unsigned long) ioremap(LED_PHY_ADDR, sizeof(u32));
key_addr = (unsigned long) ioremap(KEY_PHY_ADDR, sizeof(u32));
/*
iowrite32(0x00,led_addr);
mdelay(100);
iowrite32(0xff,led_addr);
*/
printk("gpio installed successfully!n");
return 0;
}
static void __exit gpio_exit(void)
{
/*
iowrite32(0x00,led_addr);
mdelay(100);
iowrite32(0xff,led_addr);
*/
device_destroy(gpio_class,MKDEV(gpio_major, 0));
class_unregister(gpio_class);
class_destroy(gpio_class);
unregister_chrdev(gpio_major,DEVICE_NAME);
printk("gpio module exit!");
}
module_init(gpio_init);
module_exit(gpio_exit);
MODULE_AUTHOR("seg");
MODULE_LICENSE("GPL");
(8) Useful Tips for write linux driver
Part1: we can use commands below to test gpio led.
cd /sys/class/gpio/
echo 248 > ./export
cd gpio248/
echo "out" > ./direction
echo 1 > ./value
Part2: we can use commands below to see interrupts status.
cat /proc/interrupts
cat /proc/stat
转载于:https://www.cnblogs.com/shenerguang/p/3730047.html
最后
以上就是感性白昼为你收集整理的Learn ZYNQ Programming(1)的全部内容,希望文章能够帮你解决Learn ZYNQ Programming(1)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复