18550|36

5979

帖子

8

TA的资源

版主

楼主
 

【Altera SoC体验之旅】高速数据采集之中断 [复制链接]

 
本帖最后由 chenzhufly 于 2015-4-17 01:26 编辑

作者:chenzhufly  QQ:36886052
1、  硬件环境
硬件平台:Embest SoC --LarkBoard
软件平台:开发板-linux-3.10.31
          Quartus 14.0

2、系统概述
     简单点说,就是FPGA准备好数据了,现在需要通知ARM过来取数据。在传统的设计里面可以把FPGA的一个IO挂在ARM的外部中断上,准备好数据了就触发一次中断,大喊一声“HI,我来啦!准备接客”。那么在soc中怎么设计呢,如下图所示:

1)  ADC采集来的数据先进FIFO缓存
2)  在FPGA内部生成IRQ逻辑,并挂在lwhps上

3、系统生成
在qsys中我们要生成如下的硬件系统,整体连接关系如下:

中断号应该是几呢?请看下面分解。

中断的参数设计如下:

地址映射关系如下:

HDL Example如下:
  1. lark_pcie u0 (
  2.         .memory_mem_a                          (<connected-to-memory_mem_a>),                          //                         memory.mem_a
  3.         .memory_mem_ba                         (<connected-to-memory_mem_ba>),                         //                               .mem_ba
  4.         .memory_mem_ck                         (<connected-to-memory_mem_ck>),                         //                               .mem_ck
  5.         .memory_mem_ck_n                       (<connected-to-memory_mem_ck_n>),                       //                               .mem_ck_n
  6.         .memory_mem_cke                        (<connected-to-memory_mem_cke>),                        //                               .mem_cke
  7.         .memory_mem_cs_n                       (<connected-to-memory_mem_cs_n>),                       //                               .mem_cs_n
  8.         .memory_mem_ras_n                      (<connected-to-memory_mem_ras_n>),                      //                               .mem_ras_n
  9.         .memory_mem_cas_n                      (<connected-to-memory_mem_cas_n>),                      //                               .mem_cas_n
  10.         .memory_mem_we_n                       (<connected-to-memory_mem_we_n>),                       //                               .mem_we_n
  11.         .memory_mem_reset_n                    (<connected-to-memory_mem_reset_n>),                    //                               .mem_reset_n
  12.         .memory_mem_dq                         (<connected-to-memory_mem_dq>),                         //                               .mem_dq
  13.         .memory_mem_dqs                        (<connected-to-memory_mem_dqs>),                        //                               .mem_dqs
  14.         .memory_mem_dqs_n                      (<connected-to-memory_mem_dqs_n>),                      //                               .mem_dqs_n
  15.         .memory_mem_odt                        (<connected-to-memory_mem_odt>),                        //                               .mem_odt
  16.         .memory_mem_dm                         (<connected-to-memory_mem_dm>),                         //                               .mem_dm
  17.         .memory_oct_rzqin                      (<connected-to-memory_oct_rzqin>),                      //                               .oct_rzqin
  18.         .clk_clk                               (<connected-to-clk_clk>),                               //                            clk.clk
  19.         .reset_reset_n                         (<connected-to-reset_reset_n>),                         //                          reset.reset_n
  20.         .hps_0_h2f_reset_reset_n               (<connected-to-hps_0_h2f_reset_reset_n>),               //                hps_0_h2f_reset.reset_n
  21.         .hps_0_f2h_cold_reset_req_reset_n      (<connected-to-hps_0_f2h_cold_reset_req_reset_n>),      //       hps_0_f2h_cold_reset_req.reset_n
  22.         .hps_0_f2h_debug_reset_req_reset_n     (<connected-to-hps_0_f2h_debug_reset_req_reset_n>),     //      hps_0_f2h_debug_reset_req.reset_n
  23.         .hps_0_f2h_warm_reset_req_reset_n      (<connected-to-hps_0_f2h_warm_reset_req_reset_n>),      //       hps_0_f2h_warm_reset_req.reset_n
  24.         .pio_led_external_connection_export    (<connected-to-pio_led_external_connection_export>),    //    pio_led_external_connection.export
  25.         .pio_button_external_connection_export (<connected-to-pio_button_external_connection_export>)  // pio_button_external_connection.export
  26.     );
复制代码

做到这里硬件系统就设计完成了!

4、关于中断号
    从上图看到,我们的中断是挂在f2h_irq0上,实际的物理中断是多少呢,需要认真看手册了
总共fpga到arm的有64个中断源,分别分配在f2h_irq0和f2h_irq1上,所以上面的设计对应的物理中断号是77,记住了哦,下面还有用!

5、产生中断源
简单的写了一个计数器,作为中断源,如下:
  1. module count_int (                           
  2.     input clk,                                       
  3.     input reset,                                                              
  4.                                                      
  5.     output avl_irq
  6. );                                                   

  7. reg  [31:0] s_cnt;

  8. always @(posedge clk or negedge reset)
  9.     begin
  10.         if (!reset)
  11.             s_cnt <= 32'd0;
  12.         else
  13.             s_cnt <= s_cnt + 1'b1;
  14.     end  

  15. assign avl_irq = s_cnt[24];                             

  16. endmodule   
复制代码

把输出挂在HPS的模块上就可以
  1. .pio_button_external_connection_export                  (avl_irq)
复制代码

6、linux驱动
1)首先要告知内核,要挂在这个中断啊,dts中需要添加
  1.   altera_pio: gpio@0xff200000{
  2.                         compatible = "altr,pio-1.0";
  3.                         reg = <0xff200010 0x10>;
  4.                         //reg = <0xff200000 0x10>;
  5.                         interrupts = <0 45 4>;
  6.                         //interrupts = <0 40 4>;
  7.                         altr,gpio-bank-width = <32>;
  8.                         altr,interrupt_type = <2>;                //failing edge
  9.                         #gpio-cells = <2>;
  10.                         gpio-controller;
  11.                         //inter_gpios = < &altera_pio 0 1 >;
  12.                         #interrupt-cells = <1>;
  13.                         interrupt-controller;               
  14.                 };
复制代码

注意:
  • reg = <0xff200010 0x10>;和上面的地址分配是对应的
  • interrupts = <0 45 4>;,这个45需要加上32,那么和上面的中断号77也是对应的

2)挂载自己的驱动程序
还要告知内核,我用了它的哪个中断源,取个名字叫key_int吧
  1. <blockquote>key_int {
复制代码
自己写的简单驱动如下:
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/device.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/leds.h>
  7. #include <linux/io.h>
  8. #include <linux/uaccess.h>

  9. #include <linux/semaphore.h>
  10. #include <linux/cdev.h>

  11. #include <linux/types.h>
  12. #include <linux/fs.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/irq.h>
  15. #include <linux/of.h>
  16. #include <linux/of_gpio.h>
  17. #include <linux/of_device.h>
  18. #include <linux/gpio.h>

  19. int key_gpio;
  20. int key_irq;
  21. /*******************************************/
  22. //中断处理函数:
  23. static irqreturn_t key_interrupt (int irq, void *dev_id)
  24. {
  25. //       printk("=============key_interrupt=============\n");
  26.         return 0;
  27. }

  28. int button_release(struct platform_device *pdev)
  29. {
  30.     return 0;   
  31. }

  32. int button_probe(struct platform_device *pdev)
  33. {
  34.         int result;
  35.         struct device_node *node = pdev->dev.of_node;
  36.         key_gpio = of_get_named_gpio(node,"inter_gpios",0);
  37.         key_irq = __gpio_to_irq(key_gpio);
  38.         printk("=============key_irq = %d=============\n",key_irq);        

  39.         result = request_irq(key_irq, key_interrupt,IRQF_TRIGGER_FALLING, "key_int", NULL);
  40.   if(result)
  41.        {
  42.           printk(KERN_INFO"[FALLED: Cannot register Key  Interrupt!]\n");
  43.        }

  44.         return 0;
  45. }

  46. static struct of_device_id altera_gpio_of_match[] = {
  47.         { .compatible = "altr,key-int", },
  48.         {},
  49. };
  50. MODULE_DEVICE_TABLE(of, altera_gpio_of_match);

  51. static struct platform_driver button_fops = {
  52.         .driver = {
  53.                 .name        = "key_int",
  54.                 .owner        = THIS_MODULE,
  55.                 .of_match_table = of_match_ptr(altera_gpio_of_match),
  56.         },
  57.     .probe = button_probe,
  58.     .remove = button_release,
  59. };

  60. // 模块加载函数
  61. static int __init button_init(void)
  62. {
  63.     printk(KERN_ALERT "key modules is install\n");   
  64.     return    platform_driver_register(&button_fops);   
  65.    
  66. }

  67. // 模块卸载函数
  68. static void  __exit button_cleanup(void)
  69. {
  70.     printk("Goodbye,chenzhufly!\n");
  71.     platform_driver_unregister(&button_fops);   
  72. }

  73. module_init(button_init);
  74. module_exit(button_cleanup);

  75. MODULE_AUTHOR("chenzhufly");
  76. MODULE_LICENSE("Dual BSD/GPL");
复制代码

7、测试
看到key_int了吗?

8、小结
1)学习的过程总是苦逼的,但结果总是异常的简单明了,纵观下来,其实所涉及的东西并不多,但如何能在一开始就融汇贯通,难度相当的大啊
2)soc中断设计比传统的arm+fpga架构要好使很多,避免很多麻烦的事情,自从调通以后,我就喜欢上了它
3)提醒一下3.10内核的linux版本,不支持arm端的IO中断,有需要的需要自己移植了,不要再在这个上面浪费时间了



此帖出自FPGA/CPLD论坛

最新回复

学习学习。  详情 回复 发表于 2018-9-21 16:12

赞赏

1

查看全部赞赏

点赞 关注(1)
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 

回复
举报

1025

帖子

1

TA的资源

纯净的硅(高级)

沙发
 
研究了半天得出的结论就是3.10以上的kernel不支持IO中断了?
此帖出自FPGA/CPLD论坛
 
 

回复

5979

帖子

8

TA的资源

版主

板凳
 
是不支持arm上IO中断
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

5979

帖子

8

TA的资源

版主

4
 
驱动不支持
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

5979

帖子

8

TA的资源

版主

5
 
这个是fpga触发arm中断 还是支持的  哈哈
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

372

帖子

0

TA的资源

一粒金砂(高级)

6
 
请教几个问题:
1、存ADC数据的FIFO是在fpga逻辑中例化的还是在Qsys中例化的,图中并未看到你的fifo挂靠到Qsys之中?
2、你的ADC是另外申请的?记得之前DE1-soc好像带了一个ADC板子
此帖出自FPGA/CPLD论坛

点评

1、FIFO是在fpga逻辑中例化的[/backcolor] 2、板子是Embest的,自带了ADC[/backcolor]  详情 回复 发表于 2015-4-17 11:27
 
 
 

回复

14

帖子

0

TA的资源

一粒金砂(初级)

7
 
我是楼主吗??
此帖出自FPGA/CPLD论坛
个人签名献给今天所有心情不好的人.?
 
 
 

回复

5979

帖子

8

TA的资源

版主

8
 
coyoo 发表于 2015-4-17 10:06
请教几个问题:
1、存ADC数据的FIFO是在fpga逻辑中例化的还是在Qsys中例化的,图中并未看到你的fifo挂靠到Qsys之中?
2、你的ADC是另外申请的?记得之前DE1-soc好像带了一个ADC板子

1、FIFO是在fpga逻辑中例化的

2、板子是Embest的,自带了ADC
此帖出自FPGA/CPLD论坛

点评

在逻辑中例化的FIFO,最终数据怎么通过Qsys互联送到ARM呢?  详情 回复 发表于 2015-4-17 12:14
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

372

帖子

0

TA的资源

一粒金砂(高级)

9
 
chenzhufly 发表于 2015-4-17 11:27
1、FIFO是在fpga逻辑中例化的

2、板子是Embest的,自带了ADC

在逻辑中例化的FIFO,最终数据怎么通过Qsys互联送到ARM呢?
此帖出自FPGA/CPLD论坛
 
 
 

回复

5979

帖子

8

TA的资源

版主

10
 
这个还没做呢 呵呵 等我发文章
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

1204

帖子

1

TA的资源

纯净的硅(初级)

11
 
哇哇,好厉害,学习学习。
此帖出自FPGA/CPLD论坛
 
 
 

回复

384

帖子

0

TA的资源

一粒金砂(中级)

12
 
厉害,不愧是之前搞嵌入式的,我只是在裸机下弄过fpga到arm的中断,有空真得学习一下。
此帖出自FPGA/CPLD论坛

点评

裸机fpga到arm、中断调通了么?我也是开始弄裸机跑,中断函数进不去啊  详情 回复 发表于 2016-12-4 22:39
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

13
 
这一段是什么意思?

QQ截图20150522102046.bmp (235.56 KB, 下载次数: 5)

QQ截图20150522102046.bmp
此帖出自FPGA/CPLD论坛

点评

请问这里你懂了么?我还是没看懂  详情 回复 发表于 2016-1-6 18:35
 
 
 

回复

5979

帖子

8

TA的资源

版主

14
 
函数啊
有疑问直接说过
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

15
 
楼主,请教一下 ,这个物理中断号是怎么确定的呀?
此帖出自FPGA/CPLD论坛

点评

软件带了个文件,可以在里面对应看一下所有的物理中断地址 /*! * This type definition enumerates all the interrupt identification types. */ typedef enum ALT_INT_INTERRUPT_e { ALT_INT_INTERRU  详情 回复 发表于 2016-12-4 22:40
 
 
 

回复

5979

帖子

8

TA的资源

版主

16
 
这个中断号 是在内核申请的 我没有关心
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

23

帖子

0

TA的资源

一粒金砂(中级)

17
 
楼主,我想问一下你有没有接触DSP Builder,我对里面的时钟不理解,能不能帮我解释一下。我外部是50MHz的晶振,有没有可能让板子跑的更快?
此帖出自FPGA/CPLD论坛
 
 
 

回复

5979

帖子

8

TA的资源

版主

18
 
那当然可以,外部时钟只不过是提供个时钟源而已,系统的运行时钟还可以通过倍频提高,每个芯片的等级不一样,可以稳定运行的频率也会不同,这个可以查看相关的技术手册得到
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

19
 
请教一下, key_gpio = of_get_named_gpio(node,"inter_gpios",0);  这句话里的 “inter_gpios” 是在哪里定义的,是要自己手动在 dts 文件里添加吗?是什么格式的?
此帖出自FPGA/CPLD论坛

点评

你解决了吗?楼主代码中的inter_gpios为什么注释了?  详情 回复 发表于 2016-9-20 17:00
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

20
 
同问,inter_gpio在哪里定义的啊?还有
key_int {没有贴完啊,就差这点弦没搭接起来,烦请楼主及时答疑解惑。非常感谢!
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表