https://blog.csdn.net/xzyiverson/article/details/13095137
上一个实验用PL端的资源开发Custom IPcore的,并且在裸跑的程序中调用了这个IPcore,现在我们需要为这个Ipcore开发Linux系统上的设备驱动。该实验为pwm_ip嵌入式Linux驱动开发。记录下自己做这个实验的心路历程。
转载注明出处:来自xzyfeixiang的专栏,网址:
实验尝试:
尝试一:这里想偷个懒:启动linux系统后(demo迷你系统),重新配置FPGA,再想加载光盘中给的驱动,结果证明这个是不行的,因为迷你系统也用到了fpga,重新配置系统崩溃了。图1
尝试二:还是回归生成BOOT.BIN的方法,之前有一个实验zedboard--拷贝到SD卡启动的fsbl引导裸跑程序实验(九)
即用fsbl工程来替代那个helloworld.c工程,同时拷贝一个u-boot.elf文件加上之前的fpga的bit文件,一起来生成这个BOOT.BIN文件。
光盘中的u-boot.elf,新建fsbl工程生成的fsbl.elf,以及前面fpga的bit文件,xilinx tools->Create bootimage 图2,用来替换原来sd卡中的BOOT.BIN文件(记得一定要将sd卡中的BOOT.BIN文件备份),系统无法启动,出现下面的东西 图3
评注:出现图3的错误是很正常的,错误有两处:一是原demo系统是用到了fpga的,这样单独把上个实验的bit文件拷过来是不正确的,应该是在原来的xps工程里加入ip核,重新产生bit文件,在Create boot image。二是Create boot image的时候顺序是不能错的。
于是,上网找资料,在懒兔子那里找到了方向,首先要有这个文件ZedBoard_OOB_Design.zip,链接http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,1028&Prod=ZEDBOARD
解压这个文件zedBoard上默认的XPS系统工程位于hw\xps_proj文件夹下,启动xps打开工程system.xmp,然后和上个实验一样,添加自定义ip核,你可以看到这个工程里面本身就有很多ip核。
评注:很多次尝试还是不成功,后面看到这个文件ZedBoard_OOB_Design.zip是14.1的,我的版本是14.2,果断下载了ZedBoard_Linux_Design_14_2.zip这个文件。下面记录下成功的步骤。
实验步骤:
版本14.2 ,demo文件ZedBoard_Linux_Design_14_2.zip,解压该文件。我换成了project1_12的名字 图4
启动xps 图5打开工程,在hw\xps_proj文件夹下
Hardware- Createor Import Periphera 来到欢迎界面 图6
Next,创建新的模板(默认选择) 图7
Next 默认 图8
Next命名工程 图9
采用AXI4-Lite 图10
Next,这里只要 User logic master support 图11
Next,我们要两个寄存器,分别是占空比寄存器和周期寄存器,图12
Next,不做任何修改 图13
Next,不需要仿真平台 图14
Next, 全选图15
第一个选项表示生成的User Logic使用VerilogHDL
第二个选项表示同时生成一个ISE的工程,便于调试和测试Ipcore
第三个选项表示生成软件驱动库文件,方便在SDK里使用Ipcore
Next,点击finish就可以了 图16
我们自己配置的IP核就建立好了,接下来添加刚完成的IP核,在IP Catalog里面的USER选项中找到它 图17
双击PWM_IP,出现 图18
选择YES, 图19
点击两次ok,出现 图20
注意一下不要粘贴外面的(如word文档里面的),容易出错,输入法选择在英文输入法下。
右击pwm_ip_0,View MPD,添加PORT pwm_out=””,DIR=O,如图21(添加在60行),保存并关闭
右击pwm_ip_0,Brouse HDLsources,打开pwm_ip.vhd.添加代码
1添加(138行) 将pwm_out接口设置为模块的输出接口
pwm_out :out std_logic; 图22
2添加(253行)将pwm_out接口到user_logic设备
pwm_out :out std_logic; 图23
3添加(342)将设备的pwm_out接口和IP核的pwm_out接口连接
pwm_out =>pwm_out, 图24
保存,退出,右击pwm_ip_0,Brouse HDLsources,打开user_logic.v.添加代码
1添加(58行),声明pwm_out接口,添加pwm_out, 图25
2添加(88行)定义pwm_out为输出,而且位宽为1,添加
output pwm_out; 图26
3接下来就是用户实现段了,令slv_reg0为周期寄存器,slv_reg1为占空比寄存器。此外我们还需要一个计数器(pwm_counter),下一个周期的开始信号(Over Period)和预输出信号(pre_pwm_out)。
在110添加逻辑
wire ovprd;
reg [C_SLV_DWIDTH-1 :0] pwm_counter;
wire pre_pwm_out;
图27
pwm产生器的逻辑
在124行添加逻辑 图28
// USER logic implementation added here
always @(posedgeBus2IP_Clk)
begin
if(!Bus2IP_Resetn || ovprd ||~slv_reg1[31])
pwm_counter=32'h8000_0000;
else if(slv_reg1[31])
pwm_counter=pwm_counter+1'b1;
elsepwm_counter=pwm_counter;
end
assignovprd=(pwm_counter[30:0]==slv_reg0[30:0])?1'b1:1'b0;
assignpre_pwm_out=(slv_reg1<pwm_counter)?1'b0:1'b1;
assignpwm_out=pre_pwm_out & slv_reg1[31];
保存,退出,在project菜单中选择RescanUser Repositories,从port中可以看到我们新添加的引脚pwm_out.选择External Ports把引脚引出去,如图29
然后注意了,我们要占用GPIO,在zynq视图中点击General Settings。设为7
图30
可以看到GPIO现在为【6:0】,现在在address页面,你可以看到现在还没有给我们定义的ip核分配地址,之前的ip核的地址是lock的状态的,这样可以保证你为新ip核分配地址的时候不会导致他们变化,如果变了就有写麻烦,变化了就要改变devicetree,另外注明14.1的devicetree和14.2的是不同的,我之前的demo系统时用的14.1的东西,这里要用14.2里面的devicetree来替换。否则系统启动不了。 图31 图32
回到正题,点击产生地址 图33,给我们定义的ip核产生了地址、
双击ucf文件,这一步也很重要,注释和添加约束 图34
保存,关闭ucf,点击产生bitstream,这下很费时间,耐心等待。
漫长的等待结束以后,Export Design 图35
新建一个c工程,选择fsbl工程。Finish后会自动编译生成zynq_fsbl_0.elf,
xilinx tools->Create boot image,找到刚刚生成的system.bit,demo文件里面的u-boot.elf,加上上面的fsbl.elf文件,如图37,注意顺序一定不能反,先是zynq_fsbl_0.elf,system.bit,u-boot.elf。要不然生成的boot.bin文件是无法启动系统的。
输入Output 文件夹 我这里输入C:\zedboard\project1_12\BOOT
Create image,这里会在我们刚刚设置的BOOT文件夹下生成如下文件 图38
其中u-boot.bin就是我们需要的BOOT.BIN文件。替换sd卡里面的就行了,这样还不够,必须替换相应的devicetree文件,因为我原来的demo是14.1的demo里面的,这里编译的是14.2的,替换就可以了,文件系统和zimage可以不用换。
启动系统,这里使用光盘里面的ko文件直接测试,挂载U盘,
insmod pwm_driver.ko
cd /sys/class/pwm_driver/pwm_device/
echo 1000 >pwm_frequency
echo 50 >pwm_duty
echo 30 >pwm_duty
echo 90 >pwm_duty
今天启动了这个系统后,发现原来可以开机运行的软件现在不能开机启动了,只是换了BOOT.BIN文件和devicetree文件,看来是要重新制作下ramdisk了,这个原因有待考证。 --------------------- 作者:肖志远 来源: 原文:https://blog.csdn.net/xzyiverson/article/details/13095137 版权声明:本文为博主原创文章,转载请附上博文链接!