参考:
下面这篇文章记录的命令中有些是双横线,但是好像发布后就成一条横线了。根据报错自行更改吧。
vivado工程建好,一个简单的PWM驱动程序。
新建PetaLinux工程
petalinux-create --type project --template zynq --name PetaLinux_PWM_Linux
导入硬件
$ cd PetaLinux_PWM_Linux/
$ petalinux-config --get-hw-description=/home/ysxubuntu/Documents/project/CH4LInux/Soc_Small_AddLedsIp_PWM_LInux/Soc_Small.sdk
petalinux-create --type project --template zynq --name PetaLinux_PWM_Linux
$ cd PetaLinux_PWM_Linux/
$ petalinux-config --get-hw-description=/home/ysxubuntu/Documents/project/CH4LInux/Soc_Small_AddLedsIp_PWM_LInux/Soc_Small.sdk
可以设置一下tftp服务器地址和路径 自己的路径在Subsystm Auto Hardware Setting-Ethernet Settings.
创建应用程序模板
$ petalinux-create -t apps --template c --name pwm_1.0 --enable
创建驱动模板
$ petalinux-create -t modules --name pwm_1.0 --enable
启用驱动和应用
$ petalinux-create -t apps --template c --name pwm_1.0 --enable
$ petalinux-create -t modules --name pwm_1.0 --enable
启用驱动和应用
驱动建好以后,要通过设置界面启动modules和apps才能编译驱动,否则直接编译会报错
petalinux-config -c rootfs
编译工程
写代码,先编译贝博betball网页,再编译各个模块和根文件系统.如果修改了某一个模块,也要进行 petalinux-build
petalinux-build -c kernelpetalinux-build -c pwm//编译modules
petalinux-build -c rootfs
petalinux-build -c pwm2//编译APP
petalinux-build
通过SD卡启动
生成BOOT.bin
petalinux-package --boot --format BIN --fsbl zynq_fsbl.elf --fpga system_wrapper.bit --u-boot
然后拷到卡里执行
通过JTAG启动
petalinux-package --prebuilt
直接执行 petalinux-boot --jtag --prebuilt 3
通过TFTP启动
petalinux-package --prebuilt
petalinux-boot --jtag --prebuilt 2
挂载驱动
petalinux-package --prebuilt
petalinux-boot --jtag --prebuilt 2
启动后,转到 cd /lib/modules/<板子版本号>/extra/文件夹执行modprobe pwm2.ko即可挂载驱动
经过验证,修改代码后如果只编译modules,无法产生作用。
直接写地址的方法
有一篇文章提供了不需要创建驱动的直接操作地址的方法,先实验一下。
从 components/plnx_workspace/device-tree/device-tree/pl.dtsi文件可以看到自己添加的AXI设备,同时可以看到地址
compatible = "xlnx,PWM-LITE-v1-0-1.0";
reg = <0x43c00000 0x10000>;
然后直接改了上面建的app源文件
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define GPIO_BASE (0x43c00000)
#define MAP_SIZE 0xFF
static int dev_fd;
int main(int argc, char **argv)
{
int i;
dev_fd = open("/dev/mem",O_RDWR | O_SYNC);
if (dev_fd < 0)
{
printf("open(/dev/mem) failed.");
return 0;
}
unsigned char *map_base=(unsigned char * )mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, GPIO_BASE );
printf("mapbase=%x\n",(unsigned int)map_base);
while(1)
for(i=0;i<8;i++)
{
*(map_base+i*8)=99;
*(map_base+i*8+4)=50;
usleep(1000000);
*(map_base+i*8)=99;
*(map_base+i*8+4)=99;
usleep(1000000);
}
if(dev_fd)
close(dev_fd);
munmap(map_base,MAP_SIZE);//解除映射关系
return 0;
}
可以看到LED在依次点亮了。