内核驱动程序 - ZedBoard - Linux在访问地址后挂起

时间:2016-04-08 13:13:54

标签: linux kernel linux-device-driver fpga xilinx

我是新的ZedBoard。我的ZedBoard在Xilinx Linux 2015.4上运行(devicetree.dtb,boot.bin和uImage手动编译;其他文件来自带有预编译系统的原始存档)。 我只使用PS,AXI GPIO和LED创建非常简单的FPGA配置。在Vivado地址中我可以看到这一行:

Cell       Slave Interface Base name Offset addr. Range High addr.
axi_gpio_0 S_AXI           Reg       0x4120_0000  64K   0x4120_FFFF

我想为这个FPGA配置创建自己的内核驱动程序但是当我尝试将驱动程序插入系统时,Linux会在ioread / iowrite操作开始时挂起。 有关于init函数的代码:

#define DEV_NAME "my_led_dev"

dev_t dev_numbers;
struct cdev *my_led_cdev;
static unsigned long gpio_base = 0x41200000;
struct resource *res;


static int led_init(void) {
  void* kernel_gpio_base;

  /* Device registration */
  int state; 
  if ((state = alloc_chrdev_region(&dev_numbers, 0, 1, DEV_NAME)) != 0)
    printk(KERN_ALERT "failed to register a region dynamically\n");
  else 
    printk(KERN_ALERT "major number = %d\n", MAJOR(dev_numbers));

  my_led_cdev = cdev_alloc();
  my_led_cdev->owner = THIS_MODULE;

  state = cdev_add(my_led_cdev, dev_numbers, 1);
  if(state < 0) {
    printk(KERN_ALERT "device failed to be added\n");
    unregister_chrdev_region(dev_numbers, 1); 
    return -ENODEV;
  }
  printk (KERN_INFO "Device prepared\n");

  /* Get required resources. */
  res = request_mem_region(gpio_base, 0xFFFF, "my_gpio_led");
  if (res == NULL) {
    printk(KERN_ALERT "my_gpio: can't get I/O port address 0x%lx\n", gpio_base);
    return -ENODEV;
  }

  /* Port mapping */
  kernel_gpio_base = (void*) ioremap(gpio_base, 0xFFFF);
  if (kernel_gpio_base == NULL) {
    printk(KERN_ALERT "kernel remap my_gpio failed 0x%lx\n", gpio_base);
    release_mem_region (res->start, 65536);
    cdev_del(my_led_cdev); 
    unregister_chrdev_region(dev_numbers, 1); 
    return -ENODEV;
  }
  printk (KERN_INFO "Ports mapped\n");

  printk (KERN_INFO "Mapped port: %p", kernel_gpio_base);
  printk (KERN_INFO "Actual value: %d\n", ioread32 (kernel_gpio_base)); // There is problem. This message isn't printed and system hangs.
  iowrite8 (0xff, kernel_gpio_base);

  return 0;
}

我见过Xilinx和ZedBoard文档但没有结果。在Xilinx上插入模块后,我发现很少有关于悬挂的主题,但问题在于设备树,其中fclk-enable被禁用。实际上我使用默认DT而没有更改,fclk-enable的值为&lt; 0xf&gt;。

感谢您的帮助。提前谢谢。

1 个答案:

答案 0 :(得分:0)

如果CPU针对可编程逻辑发出内存事务并且没有响应,则CPU将挂起。没有内置总线错误或超时机制。

以下是我遇到此问题的一些原因:

  1. 未编程可编程逻辑
  2. AXI slave未响应正确的地址
  3. AXI奴隶中的错误
  4. 调试此方法的一种方法是使用集成逻辑分析仪跟踪AXI接口。