赞
踩
最近在做有关zynq的项目。刚刚入手,以下是一些比较初级的操作,只适合入门道友观摩
setenv bootargs ‘console=ttyPS0,115200 root=/dev/nfs rw nfsroot=192.168.1.25:/home/growup/linux/nfs/rootfs ip=192.168.1.24:192.168.1.25:192.168.1.1:255.255.255.0::eth0:off‘
saveenv
setenv bootargs 'console=ttyPS0,115200 root=/dev/nfs nfsroot=192.168.1.25:/home/jdcy/linux/nfs/rootfs, proto=tcp,nfsvers=4 ip=dhcp rw'
mount -t nfs -o nolock 192.168.1.27:/home/jdcy/linux/nfs/mod /mnt
setenv root=/dev/nfs rw nfsroot=192.168.1.25:/home/zynq/linux/nfs/rootfs ip=192.168.1.24:192.168.1.25:192.168.1.1:255.255.255.0::eth0:off‘
setenv bootcmd 'tftpboot 0x2080000 zImage; tftpboot 0x2000000 system.dtb; bootz 0x2080000 - 0x2000000 '
sudo apt-get install qemu-user-static
cd /home/jdcy/xilinx_zynq/pkg/ubuntu16
sudo cp /usr/bin/qemu-arm-static ./usr/bin/
vi ./etc/apt/sources.list
示例代码 A4.2.1 中科大 Ubuntu arm 软件源
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-security main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial-proposed main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ xenial main restricted universe multiverse
#!/bin/bash
sudo mount -t proc /proc /home/zynq/linux/rootfs/ubuntu_rootfs/proc
sudo mount -t sysfs /sys /home/zynq/linux/rootfs/ubuntu_rootfs/sys
sudo mount -o bind /dev /home/zynq/linux/rootfs/ubuntu_rootfs/dev
sudo mount -o bind /dev/pts /home/zynq/linux/rootfs/ubuntu_rootfs/dev/pts
sudo chroot /home/zynq/linux/rootfs/ubuntu_rootfs
#!/bin/bash
sudo umount /home/zynq/linux/rootfs/ubuntu_rootfs/dev/pts
sudo umount /home/zynq/linux/rootfs/ubuntu_rootfs/dev
sudo umount /home/zynq/linux/rootfs/ubuntu_rootfs/sys
sudo umount /home/zynq/linux/rootfs/ubuntu_rootfs/proc
./mount.sh
退出
exit
./unmount.sh
apt install xubuntu-desktop
https://github.com/Xilinx/device-tree-xlnx/releases
open_hw_design /home/jdcy/xilinx_zynq/proj/Navigator_7020.sdk/navigator_7020_wrapper.hdf
set_repo_path /home/jdcy/xilinx_zynq/pkg/device-tree-xlnx-xilinx-v2018.3
create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
generate_target -dir /home/jdcy/xilinx_zynq/pkg/work/linux-4.14/arch/arm/boot/dts
得到设备树文件
petalinux-build -c bootloader
petalinux-build -c u-boot
petalinux-package --boot --fsbl --u-boot --force
(注意zynq的ps端引导第一阶段是fsbl文件先引导u-boot,所以BOOT.BIN是u-boot与fsbl打包在一起生成的,这个步骤只能使用petalinux来生成)
编译 kerne
CONFIG_ARCH_ZYNQ选项下
echo 'export PATH=$PATH:'`which arm-linux-gnueabihf-gcc | xargs dirname` | tee -a ~/.bashrc
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make xilinx_zynq_defconfig
make zImage -j8
make system-top.dtb -j8
进入到 Petalinux 工程目录下
petalinux-config -c rootfs
配置无需密码登录后编译Image Features —>debug-tweaks
petalinux-build -c rootfs
setenv bootcmd run default_bootcmd setenv bootargs 'console=ttyPS0,115200 root=/dev/mmcblk0p2 rootwait rw rootfstype=ext4' env default -a setenv bitstream_load_address 0x100000 setenv bitstream_image system.bit setenv bitstream_size 0x300000 setenv kernel_img zImage setenv dtbnetstart 0x2000000 setenv netstart 0x2080000 setenv cp_dtb2ram 'mmcinfo && fatload mmc 0:1 ${dtbnetstart} ${dtb_img}' setenv default_bootcmd 'if mmcinfo; then run uenvboot; echo Copying Linux from SD to RAM... && load mmc 0 ${bitstream_load_address} ${bitstream_image} && fpga loadb 0 ${bitstream_load_address} ${bitstream_size} && run cp_kernel2ram && run cp_dtb2ram && bootz ${netstart} - ${dtbnetstart}; fi' saveenv boot setenv bootcmd 'tftpboot 0x2080000 zImage; tftpboot 0x2000000 system.dtb; bootz 0x2080000 - 0x2000000' mount -t nfs -o nolock 192.168.1.27:/home/jdcy/linux/nfs/mod /mnt
新建一个 hsi_test.tcl
# tcl script test
hsi::open_hw_design /home/jdcy/xilinx_zynq/proj/Navigator_7020.sdk/navigator_7020_wrapper.hdf
hsi::set_repo_path /home/jdcy/xilinx_zynq/pkg/device-tree-xlnx-xilinx-v2018.3
hsi::create_sw_design device-tree -os device_tree -proc ps7_cortexa9_0
hsi::generate_target -dir /home/jdcy/xilinx_zynq/pkg/work/linux-4.14/arch/arm/boot/dts
xsct hsi_test.tcl
使用mmap映射DDR到用户空间,直接通过指针操作内存。
使用DMA(Direct Memory Access)技术,通过DMA控制器从DDR中读取数据。
使用内核缓冲区,将DDR中的数据先读入内核缓冲区,再通过用户空间和内核空间之间的数据传输接口(如read/write)将数据传到用户空间。
使用文件系统,将DDR中的数据存储为文件,使用文件读写接口进行操作。
使用共享内存,将DDR中的数据存储在共享内存中,通过共享内存接口进行操作。
使用缓存技术,将DDR中的数据缓存在缓存中,降低读取延迟。
使用多线程技术,将读取数据的操作放在一个单独的线程中,避免阻塞主线程。
对于需要频繁读取的数据,可将其预先加载到缓存中,提高读取效率。
printk 可以根据日志级别对消息进行分
类,一共有 8 个消息级别,这 8 个消息级别定义在文件 include/linux/kern_levels.h 里面
printk(KERN_EMERG “gsmi: Log Shutdown Reason\n”);
在 Linux 内核文档中,有一些文件是描述设备树(Device Tree)的,主要内容包括:
Documentation/devicetree/bindings/:该目录下包含了各个子系统的设备树绑定文档,描述了各个设备节点的属性、绑定方式等。
Documentation/devicetree/booting-without-of.txt:该文件是一个指南,介绍了如何在没有 OF(Open Firmware)的平台上启动 Linux 内核。
Documentation/devicetree/usage-model.txt:该文件介绍了设备树的一般使用模型,包括设备树源码的组织方式、设备树的绑定过程、设备驱动的匹配过程等。
Documentation/devicetree/overlay-notes.txt:该文件介绍了设备树覆盖层的使用方法和限制,包括如何在运行时更新设备树、设备树覆盖层的优缺点等。
Documentation/devicetree/changesets.txt:该文件介绍了设备树变更集的使用方法,包括如何创建变更集、如何使用变更集更新设备树等。
Documentation/devicetree/testing.txt:该文件介绍了如何使用设备树进行系统测试,主要内容包括如何为测试目的构建设备树、如何在测试中使用设备树等。
这些文档主要涵盖了设备树的各个方面,包括设备树的结构、属性和绑定方式,以及如何使用设备树进行系统启动、设备驱动开发和系统测试等。通过阅读这些文档,可以更好地理解和应用设备树技术。
该文档介绍了Zynq-7000 All Programmable SoC的架构和组成部分,包括ARM Cortex-A9处理器、PL(Programmable Logic)、PS(Processing System)、中断控制器、DMA控制器等。此外,该文档还介绍了Zynq-7000 SoC的主要功能模块和接口,如GPIO、I2C、SPI、UART、Timer等,以及它们的寄存器映射、状态和操作方法。
该文档提供了关于编写Zynq-7000 SoC驱动程序和应用程序的详细信息,包括Linux和Bare-Metal驱动程序的开发方法、硬件抽象层(HAL)库的使用方法、中断处理程序的编写、虚拟文件系统(VFS)的实现、板级支持包(BSP)的开发、设备树的编写等。
该文档介绍了Xilinx Zynq-7000 All Programmable SoC的体系结构,包括外设的接口和操作特点等。对于Zynq SoC的驱动程序开发,了解该文档中的寄存器映射和外设操作方法非常有帮助。
该文档介绍了Xilinx软件开发工具包(SDK)的使用方法,包括创建新工程、添加驱动程序和应用程序、调试程序、生成可执行文件等。
Linux内核已经支持Zynq平台,包括了一些常用驱动程序,例如GPIO、I2C、SPI、UART等。可以通过阅读Linux内核文档,了解Zynq驱动程序的使用和开发方法,包括Documentation/devicetree/bindings/arm/xilinx/、Documentation/devicetree/bindings/gpio、Documentation/devicetree/bindings/i2c等。
通过上述文档的学习,可以更深入地了解和应用Zynq平台的驱动程序开发
Linux设备树(Device Tree)是一种描述硬件信息的文本文件格式,用于指定系统中的硬件设备的连接方式和属性以及驱动程序所需要的信息。以下是Linux设备树中常用的属性:
compatible:指定设备的厂商和型号,通常由厂商提供设备树文件时给出。 reg:指定设备的物理地址和地址范围。 interrupts:指定设备的中断号、优先级和触发方式等。 clocks:指定设备的时钟信息。 gpio:指定设备使用的GPIO信息。 interrupt-parent:指定中断控制器的节点名称。 status:指定设备的状态,如"disabled"、"okay"等。 phandle:指定设备节点的全局句柄。 linux,phandle:指定设备节点的句柄。 label:指定设备的唯一标识符。 pinctrl-0:指定设备的引脚控制信息。 dma-coherent:指定设备是否支持DMA一致性。 interrupts-extended:扩展中断信息。 interrupt-map:中断映射信息。 clock-names:指定设备使用的时钟名称。
这些属性用于描述设备的硬件信息和接口,以及驱动程序需要的信息。通过对设备树的解析,Linux内核可以自动识别硬件和加载相应的驱动程序,从而实现对硬件的控制和管理。
1 alloc_chrdev_region(); /* 申请设备号 */
2 cdev_init(); /* 初始化 cdev */
3 cdev_add(); /* 添加 cdev */
4 class_create(); /* 创建类 */
5 device_create(); /* 创建设备 */
1 cdev_del(); /* 删除 cdev */
2 unregister_chrdev_region(); /* 注销设备号 */
3 device_destroy(); /* 删除设备 */
4 class_destroy(); /* 删除类 */
int misc_register(struct miscdevice * misc)
int misc_deregister(struct miscdevice *misc)
/* 匹配列表 */ static const struct of_device_id beep_of_match[] = { { .compatible = "alientek,beeper" }, { /* Sentinel */ } }; /* platform驱动结构体 */ static struct platform_driver mybeep_driver = { .driver = { .name = "zynq-beep", // 驱动名字,用于和设备匹配 .of_match_table = beep_of_match, // 设备树匹配表,用于和设备树中定义的设备匹配 }, .probe = mybeep_probe, // probe函数 .remove = mybeep_remove, // remove函数 这两个函数需要实现 }; module_platform_driver(mybeep_driver);
/* * @description : platform驱动的probe函数,当驱动与设备 * 匹配成功以后此函数就会执行 * @param - pdev : platform设备指针 * @return : 0,成功;其他负值,失败 */ static int mybeep_probe(struct platform_device *pdev) { struct miscdevice *mdev; int ret; dev_info(&pdev->dev, "BEEP device and driver matched successfully!\n"); /* 初始化BEEP */ ret = mybeep_init(pdev); if (ret) return ret; /* 初始化beep_data变量 */ mdev = &beep_dev.mdev; mdev->name = "zynq-beep"; // 设备名 mdev->minor = MISC_DYNAMIC_MINOR; // 动态分配次设备号 mdev->fops = &mybeep_fops; // 绑定file_operations结构体 /* 向linux系统misc驱动框架核心层注册一个beep设备 */ return misc_register(mdev); } /* * @description : platform驱动模块卸载时此函数会执行 * @param - dev : platform设备指针 * @return : 0,成功;其他负值,失败 */ static int mybeep_remove(struct platform_device *pdev) { /* 注销模块时关闭BEEP */ gpio_set_value(beep_dev.gpio, 0); /* 注销misc设备驱动 */ misc_deregister(&beep_dev.mdev); dev_info(&pdev->dev, "BEEP driver has been removed!\n"); return 0; }
①、如果要处理的内容不希望被其他中断打断,那么可以放到上半部。
②、如果要处理的任务对时间敏感,可以放到上半部。
③、如果要处理的任务与硬件有关,可以放到上半部
④、除了上述三点以外的其他任务,优先考虑放到下半部。
上半部处理很简单,直接编写中断处理函数就行了,关键是下半部该怎么做呢? Linux 内
核提供了多种下半部机制,接下来我们来学习一下这些下半部机制。
/include/ "system-conf.dtsi" #include <dt-bindings/gpio/gpio.h> / { model = "Navigator Development Board"; compatible = "alientek,zynq-7020","xlnx,zynq-7000"; leds { compatible = "gpio-leds"; gpio-led1 { label = "led1"; gpios = <&gpio0 54 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; gpio-led2 { label = "pl_led0"; gpios = <&gpio0 55 GPIO_ACTIVE_HIGH>; default-state = "on"; }; gpio-led3 { label = "pl_led1"; gpios = <&gpio0 56 GPIO_ACTIVE_HIGH>; default-state = "on"; }; gpio-led4 { label = "ps_led0"; gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; default-state = "on"; }; gpio-led5 { label = "ps_led1"; gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; default-state = "on"; }; gpio-led6 { label = "led2"; gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; default-state = "on"; }; }; keys { compatible = "gpio-keys"; autorepeat; gpio-key1 { label = "pl_key1"; gpios = <&gpio0 57 GPIO_ACTIVE_LOW>; linux,code = <105>; // Right debounce-interval = <20>; // 20ms }; gpio-key2 { label = "pl_key2"; gpios = <&gpio0 58 GPIO_ACTIVE_LOW>; linux,code = <106>; // Left debounce-interval = <20>; }; gpio-key3 { label = "ps_key1"; gpios = <&gpio0 12 GPIO_ACTIVE_LOW>; linux,code = <103>; // Up debounce-interval = <20>; }; gpio-key4 { label = "ps_key2"; gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; linux,code = <108>; // Down debounce-interval = <20>; }; touch-key { label = "touch_key"; gpios = <&gpio0 59 GPIO_ACTIVE_HIGH>; linux,code = <28>; // ENTER gpio-key,wakeup; debounce-interval = <20>; }; }; beeper { compatible = "gpio-beeper"; gpios = <&gpio0 60 GPIO_ACTIVE_HIGH>; }; usb_phy0: phy0@e0002000 { compatible = "ulpi-phy"; #phy-cells = <0>; reg = <0xe0002000 0x1000>; view-port = <0x0170>; drv-vbus; }; }; &i2c0 { clock-frequency = <100000>; eeprom@50 { compatible = "24c64"; reg = <0x50>; pagesize = <32>; }; rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; }; &usb0 { dr_mode = "otg"; usb-phy = <&usb_phy0>; }; &pwm_0 { compatible = "digilent,axi-pwm"; #pwm-cells = <2>; clock-names = "pwm"; npwm = <1>; }; &lcd_vtc { compatible = "xlnx,v-tc-5.01.a"; }; &lcd_vdma { dma-ranges = <0x00000000 0x00000000 0x40000000>; // 1GB }; &hdmi_vtc { clocks = <&hdmi_dynclk>, <&clkc 15>; compatible = "xlnx,v-tc-5.01.a"; }; &hdmi_dynclk { compatible = "digilent,axi-dynclk"; #clock-cells = <0>; }; &hdmi_vdma { dma-ranges = <0x00000000 0x00000000 0x40000000>; // 1GB }; &amba_pl { xlnx_vdmafb_lcd { compatible = "xilinx,vdmafb"; status = "okay"; vtc = <&lcd_vtc>; clocks = <&clk_wiz_0 0>; clock-names = "lcd_pclk"; dmas = <&lcd_vdma 0>; dma-names = "lcd_vdma"; pwms = <&pwm_0 0 5000000>; reset-gpio = <&gpio0 61 GPIO_ACTIVE_LOW>; lcdID-gpio = <&gpio1 0 0 GPIO_ACTIVE_LOW &gpio1 1 0 GPIO_ACTIVE_LOW &gpio1 2 0 GPIO_ACTIVE_LOW>; display-timings { timing_4342: timing0 { clock-frequency = <9000000>; hactive = <480>; vactive = <272>; hback-porch = <40>; hfront-porch = <5>; hsync-len = <1>; vback-porch = <8>; vfront-porch = <8>; vsync-len = <1>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; timing_4384: timing1 { clock-frequency = <31000000>; hactive = <800>; vactive = <480>; hback-porch = <88>; hfront-porch = <40>; hsync-len = <48>; vback-porch = <32>; vfront-porch = <13>; vsync-len = <3>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; timing_7084: timing2 { clock-frequency = <33300000>; hactive = <800>; vactive = <480>; hback-porch = <46>; hfront-porch = <210>; hsync-len = <1>; vback-porch = <23>; vfront-porch = <22>; vsync-len = <1>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; timing_7016: timing3 { clock-frequency = <51200000>; hactive = <1024>; vactive = <600>; hback-porch = <140>; hfront-porch = <160>; hsync-len = <20>; vback-porch = <20>; vfront-porch = <12>; vsync-len = <3>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; timing_1018: timing4 { clock-frequency = <71100000>; hactive = <1280>; vactive = <800>; hback-porch = <80>; hfront-porch = <70>; hsync-len = <10>; vback-porch = <10>; vfront-porch = <10>; vsync-len = <3>; hsync-active = <0>; vsync-active = <0>; de-active = <1>; pixelclk-active = <0>; }; }; }; xlnx_vdmafb_hdmi { compatible = "xilinx,vdmafb"; status = "okay"; vtc = <&hdmi_vtc>; clocks = <&hdmi_dynclk>; clock-names = "lcd_pclk"; dmas = <&hdmi_vdma 0>; dma-names = "lcd_vdma"; hdmi; display-timings { timing_1080p: timing5 { clock-frequency = <148500000>; hactive = <1920>; vactive = <1080>; hback-porch = <148>; hsync-len = <44>; hfront-porch = <88>; vback-porch = <36>; vsync-len = <5>; vfront-porch = <4>; hsync-active = <0>; vsync-active = <0>; de-active = <0>; pixelclk-active = <1>; }; }; }; };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。