fpga:petalinux
差别
这里会显示出您选择的修订版和当前版本之间的差别。
后一修订版 | 前一修订版 | ||
fpga:petalinux [2023/02/07 15:05] – 创建 zhangguo | fpga:petalinux [2023/03/17 10:12] (当前版本) – 外部编辑 127.0.0.1 | ||
---|---|---|---|
行 1: | 行 1: | ||
====== petalinux ====== | ====== petalinux ====== | ||
+ | |||
+ | ===== - create project ===== | ||
+ | |||
+ | |||
+ | <code bash> | ||
+ | source / | ||
+ | |||
+ | petalinux-create -t project --template zynq -n xxx_name | ||
+ | petalinux-config --get-hw-description . | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ===== - create modules ===== | ||
+ | 相当于创建linux模块驱动 | ||
+ | |||
+ | <code bash> | ||
+ | petalinux-create -t modules -n xxx_module --enable | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== - create app ===== | ||
+ | 创建一个linux平台下的app可执行程序 | ||
+ | |||
+ | <code bash> | ||
+ | petalinux-create -t apps -n xxx_app | ||
+ | </ | ||
+ | |||
+ | 然后进入recipes-apps/ | ||
+ | |||
+ | |||
+ | |||
+ | ===== - build ===== | ||
+ | <code bash> | ||
+ | petalinux-build -c rootfs | ||
+ | petalinux-build -c xxx_module | ||
+ | petalinux-build -c xxx_app -x do_install | ||
+ | |||
+ | |||
+ | |||
+ | petalinux-build | ||
+ | </ | ||
+ | |||
+ | ===== - app单独编译& | ||
+ | |||
+ | <code bash> | ||
+ | petalinux-build -c xxx_app -x do_compile | ||
+ | ls build/ | ||
+ | |||
+ | # 然后可以将此文件通过scp的方式,copy到zynq设备,修改权限chmod 777 ./myapp3, 执行程序./ | ||
+ | # 这样的方式不用每次app修改后都烧写到flash, 通过scp的方式加快app开发调试速度。 | ||
+ | |||
+ | </ | ||
+ | ===== - package to BOOT.BIN ===== | ||
+ | |||
+ | <code bash> | ||
+ | petalinux-package --boot --fsbl zynq_fsbl.elf --u-boot --kernel --fpga system.bit --force | ||
+ | # --boot, 打包成BOOT.BIN文件 | ||
+ | # -- 输入fsdb文件 | ||
+ | # --u-boot, 输入默认u-boot文件, 一般是指u-boot.elf | ||
+ | # --kernel ,输入petalinux内核, 默认是指image.ub | ||
+ | # --fpga, 指定FPGA bits文件。 | ||
+ | # | ||
+ | </ | ||
+ | |||
+ | ===== - 一个简单的驱动开发例程——GPIO流水灯(Petalinux部分) ===== | ||
+ | https:// | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== - 实现app开机启动 ===== | ||
+ | |||
+ | 参考ug1144, | ||
+ | |||
+ | 参考: https:// | ||
+ | |||
+ | <code bash> | ||
+ | |||
+ | |||
+ | 实现开机启动 | ||
+ | 本章节内容参考UG1144。 | ||
+ | (1)创建myapp-init应用 | ||
+ | |||
+ | cd < | ||
+ | petalinux-create -t apps --template install -n myapp-init --enable | ||
+ | |||
+ | (2)修改myapp-init.bb配置文件 | ||
+ | 配置文件的位置在: | ||
+ | |||
+ | project-spec/ | ||
+ | 修改文件内容为: | ||
+ | |||
+ | # | ||
+ | # This file is the myapp-init recipe. | ||
+ | # | ||
+ | SUMMARY = " | ||
+ | SECTION = " | ||
+ | LICENSE = " | ||
+ | LIC_FILES_CHKSUM =" | ||
+ | MIT; | ||
+ | SRC_URI = " | ||
+ | " | ||
+ | S = " | ||
+ | FILESEXTRAPATHS_prepend := " | ||
+ | inherit update-rc.d | ||
+ | INITSCRIPT_NAME = " | ||
+ | INITSCRIPT_PARAMS = "start 99 S ." | ||
+ | do_install() { | ||
+ | | ||
+ | | ||
+ | } | ||
+ | FILES_${PN} += " | ||
+ | (3)修改myapp-init脚本文件内容 | ||
+ | 脚本文件的位置在: | ||
+ | |||
+ | project-spec/ | ||
+ | myapp-init/ | ||
+ | |||
+ | 本文修改的内容为加载xilinx-axidma.ko module和在后台启动程序xxx_app | ||
+ | |||
+ | #!/bin/sh | ||
+ | |||
+ | cd / | ||
+ | insmod xxx_module.ko | ||
+ | |||
+ | cd /usr/bin | ||
+ | ./xxx_app & | ||
+ | ## 注意,最好在此加上& | ||
+ | ## 比如下面的任务是配置网络, 这对于需要网络的开机启动尤其重要 | ||
+ | |||
+ | 完成后进行petalinux-build,使用新生成的镜像,下次就可以开机自启动了。 | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | 开机启动执行log example: | ||
+ | |||
+ | <code bash> | ||
+ | Hello PetaLinux World, startup test.... | ||
+ | blink: loading out-of-tree module taints kernel. | ||
+ | < | ||
+ | < | ||
+ | blink_init: Registers mapped to mmio = 0xf09d0000 | ||
+ | Registeration is a success the major device number is 245. | ||
+ | If you want to talk to the device driver, | ||
+ | create a device file by following command. | ||
+ | |||
+ | mknod / | ||
+ | |||
+ | The device file name is important, because | ||
+ | the ioctl program assumes that's the file you'll use | ||
+ | ################################ | ||
+ | Blink LED Application device_open(c7e4c6c0) | ||
+ | |||
+ | ################################ | ||
+ | ************************************************ | ||
+ | start LED sparkle... | ||
+ | ************************************************ | ||
+ | app led on | ||
+ | KERNEL PRINT : set_blink_ctrl | ||
+ | |||
+ | app led off | ||
+ | KERNEL PRINT : reset_blink_ctrl | ||
+ | |||
+ | app led on | ||
+ | KERNEL PRINT : set_blink_ctrl | ||
+ | |||
+ | app led off | ||
+ | KERNEL PRINT : reset_blink_ctrl | ||
+ | |||
+ | device_release(ef1d9370, | ||
+ | ################################ | ||
+ | INIT: Entering runlevel: 5ation | ||
+ | Configuring network interfaces... IPv6: ADDRCONF(NETDEV_UP): | ||
+ | udhcpc (v1.24.1) started | ||
+ | Sending discover... | ||
+ | Sending discover... | ||
+ | macb e000b000.ethernet eth0: link up (1000/Full) | ||
+ | IPv6: ADDRCONF(NETDEV_CHANGE): | ||
+ | Sending discover... | ||
+ | Sending select for 192.168.0.166... | ||
+ | Lease of 192.168.0.166 obtained, lease time 268435455 | ||
+ | / | ||
+ | done. | ||
+ | Starting Dropbear SSH server: Generating key, this may take a while... | ||
+ | Public key portion is: | ||
+ | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCh7/ | ||
+ | NQ0Q4i58cvtTIIJmeEQI3rM9WD7V+o/ | ||
+ | OFJYrdmt4Rc5T0BZdF3LtuXaVOF7mJ7aavI7vpsme1JIvzAOkGMSXH+HqY2wG4Ak6D07WdH78AaQsI86vDLA1WLaPP4oCMjiLjeFKIuAbnhl | ||
+ | d+HuJtwvj5fx4GZcRyQ5VrwVE7anQmAu4Olw/ | ||
+ | Fingerprint: | ||
+ | dropbear. | ||
+ | hwclock: can't open '/ | ||
+ | Starting syslogd/ | ||
+ | Starting tcf-agent: OK | ||
+ | |||
+ | PetaLinux 2018.3 petalinux_boot_from_flash /dev/ttyPS0 | ||
+ | |||
+ | petalinux_boot_from_flash login: random: crng init done | ||
+ | |||
+ | PetaLinux 2018.3 petalinux_boot_from_flash /dev/ttyPS0 | ||
+ | |||
+ | petalinux_boot_from_flash login: | ||
+ | |||
+ | </ | ||
+ | |||
+ | 从上面的执行log看出来,很明显获取IP地址是在开机启动执行程序完成之后才开始的,所以一定要注意这一点。 | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | ===== - zynq设备上运行指定驱动的app程序 ===== | ||
+ | |||
+ | 在zynq fpga运行过程。 | ||
+ | |||
+ | < | ||
+ | |||
+ | root@petalinux_boot_from_flash:/ | ||
+ | / | ||
+ | root@petalinux_boot_from_flash:/ | ||
+ | blink.ko | ||
+ | |||
+ | modprobe blink.ko | ||
+ | mknod / | ||
+ | ls / | ||
+ | blinkapp | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ===== - linux 加载module ===== | ||
+ | |||
+ | <code bash> | ||
+ | insmod blink.ko | ||
+ | # 如果有同名文件module已经加载,可以先lsmode查看 | ||
+ | |||
+ | lsmod # 列出已经加载的module | ||
+ | |||
+ | rmmod blink.ko | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ===== - module驱动代码实例 ===== | ||
+ | ==== - 一个简单的device module 驱动代码 ==== | ||
+ | |||
+ | 主要描述用户数据和内核数据之间如何互通,因为不能直接访问,需要通过copy_to_user & copy_from_user函数来完成。 | ||
+ | |||
+ | <code c> | ||
+ | |||
+ | |||
+ | #include < | ||
+ | |||
+ | #include < | ||
+ | |||
+ | |||
+ | |||
+ | /* | ||
+ | * This function is called whenever a process which has already opened the | ||
+ | * device file attempts to read from it. | ||
+ | */ | ||
+ | static ssize_t device_read( struct file *file, /* see include/ | ||
+ | char __user * buffer, /* buffer to be filled with data */ | ||
+ | size_t length, /* length of the buffer */ | ||
+ | loff_t * offset) | ||
+ | { | ||
+ | int ret; | ||
+ | |||
+ | char k_buffer[20] = {0}; // kernel core buffer | ||
+ | |||
+ | memcpy(k_buffer, | ||
+ | |||
+ | ret = copy_to_user(buffer, | ||
+ | |||
+ | |||
+ | return SUCCESS; | ||
+ | } | ||
+ | /* | ||
+ | * This function is called when somebody tries to | ||
+ | * write into our device file. | ||
+ | */ | ||
+ | static ssize_t device_write(struct file *file, | ||
+ | const char __user * buffer, | ||
+ | size_t length, | ||
+ | loff_t * offset) | ||
+ | { | ||
+ | |||
+ | // user function | ||
+ | int ret; | ||
+ | char k_buffer[20] = {0}; // kernel core buffer | ||
+ | ret = copy_from_user(k_buffer, | ||
+ | |||
+ | | ||
+ | printk(" | ||
+ | // end | ||
+ | |||
+ | return SUCCESS; | ||
+ | } | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== - gpio驱动led举例 ==== | ||
+ | |||
+ | 驱动部分: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // | ||
+ | static int major_num; | ||
+ | // 定义设备文件名 | ||
+ | #define DEVICE_NAME " | ||
+ | |||
+ | // | ||
+ | #define CLASS_NAME " | ||
+ | static struct class* gpio_class; | ||
+ | static struct device* gpio_device; | ||
+ | |||
+ | #define LEDS_BASE_ADDR (0x41200000) // | ||
+ | |||
+ | static unsigned *leds; | ||
+ | |||
+ | static int leds_drv_open(struct inode *Inode, struct file *File) | ||
+ | { | ||
+ | *leds = 0x0; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | static ssize_t leds_drv_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | ||
+ | { | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | static ssize_t leds_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | ||
+ | { | ||
+ | unsigned int ret = 0; | ||
+ | unsigned int tmp_val; | ||
+ | |||
+ | ret = copy_from_user(& | ||
+ | |||
+ | *leds = tmp_val & 0xf; | ||
+ | |||
+ | return ret; | ||
+ | } | ||
+ | |||
+ | // 描述与设备文件触发的事件对应的回调函数指针 | ||
+ | static struct file_operations dev_fops = | ||
+ | { | ||
+ | .owner = THIS_MODULE, | ||
+ | .open = leds_drv_open, | ||
+ | .read = leds_drv_read, | ||
+ | .write = leds_drv_write, | ||
+ | }; | ||
+ | |||
+ | // 初始化Linux驱动 | ||
+ | static int __init leds_drv_init(void) | ||
+ | { | ||
+ | int ret; | ||
+ | |||
+ | leds = ioremap(LEDS_BASE_ADDR, | ||
+ | |||
+ | // | ||
+ | major_num = register_chrdev(0, | ||
+ | |||
+ | // | ||
+ | gpio_class = class_create(THIS_MODULE, | ||
+ | |||
+ | if(IS_ERR(gpio_class)) | ||
+ | { | ||
+ | unregister_chrdev(major_num, | ||
+ | printk(KERN_ALERT " | ||
+ | return PTR_ERR(gpio_class); | ||
+ | } | ||
+ | // | ||
+ | gpio_device = device_create(gpio_class, | ||
+ | |||
+ | if(IS_ERR(gpio_device)) | ||
+ | { | ||
+ | class_destroy(gpio_class); | ||
+ | unregister_chrdev(major_num, | ||
+ | printk(KERN_ALERT " | ||
+ | return PTR_ERR(gpio_device); | ||
+ | } | ||
+ | printk(KERN_INFO " | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | // 卸载Linux驱动 | ||
+ | static void __exit leds_drv_exit(void) | ||
+ | { | ||
+ | iounmap(leds); | ||
+ | |||
+ | // 删除设备文件, | ||
+ | device_destroy(gpio_class, | ||
+ | class_destroy(gpio_class); | ||
+ | |||
+ | unregister_chrdev(major_num, | ||
+ | |||
+ | // 输出日志信息 | ||
+ | printk(" | ||
+ | } | ||
+ | |||
+ | // 注册初始化Linux驱动的函数 | ||
+ | module_init(leds_drv_init); | ||
+ | // 注册卸载Linux驱动的函数 | ||
+ | module_exit(leds_drv_exit); | ||
+ | |||
+ | MODULE_LICENSE(" | ||
+ | |||
+ | </ | ||
+ | |||
+ | 应用程序app部分: | ||
+ | |||
+ | <code c> | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | |||
+ | |||
+ | int main(int argc, char** argv) | ||
+ | { | ||
+ | int fd; | ||
+ | | ||
+ | fd = open("/ | ||
+ | | ||
+ | if(fd < 0) | ||
+ | { | ||
+ | printf(" | ||
+ | } | ||
+ | |||
+ | unsigned int leds = 0; | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | write(fd, &leds, 4); | ||
+ | | ||
+ | leds++; | ||
+ | leds %= 0xf; | ||
+ | sleep(1); | ||
+ | } | ||
+ | |||
+ | close(fd); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | </ |
fpga/petalinux.1675753551.txt.gz · 最后更改: 2023/03/17 10:12 (外部编辑)