コード static int __init mydev_init(void) { int ret; printk("<1>Hello module world.\n"); printk("<1>Module parameters were (0x%08x) and \"%s\"\n", myint, mystr); static struct resource foomatic_resources[] = { { .start = 0x43c00000, .end = 0x43c0ffff, .flags = IORESOURCE_MEM, .name = "io-memory" }, { .start = 20, .end = 20, .flags = IORESOURCE_IRQ, .name = "irq", } }; pdev = platform_device_register_simple(DRIVER_NAME, 0, foomatic_resources, ARRAY_SIZE(foomatic_resources)); printk("ARRAY_SIZE(foomatic_resources) %x\n", ARRAY_SIZE(foomatic_resources)); if (pdev == NULL) { printk("Adding platform device pdev\"%x\" failed\n", pdev); kfree(pdev); return -ENODEV; } else{ printk("Adding platform device pdev\"%x\" successfull\n", pdev); } return platform_driver_register(&mydev_driver); } pdevは問題なく取得できました。 次に呼ばれるprobe機能を以下に示します: // mydev構造体 struct mydev_local { int irq; unsigned long mem_start; unsigned long mem_end; void __iomem *base_addr; }; // 割り込みHandler static irqreturn_t mydev_irq(int irq, void *lp) { printk("mydev interrupt\n"); return IRQ_HANDLED; } // modprobe mydev.koで呼ばれるModule static int mydev_probe(struct platform_device *pdev) { struct resource *r_irq; /* Interrupt resources */ struct resource *r_mem; /* IO mem resources */ struct device *dev = &pdev->dev; struct mydev_local *lp = NULL; int rc = 0; dev_info(dev, "Device Tree Probing\n"); /* Get iospace for the device */ r_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r_mem) { dev_err(dev, "invalid address\n"); return -ENODEV; } lp = (struct mydev_local *) kmalloc(sizeof(struct mydev_local), GFP_KERNEL); if (!lp) { dev_err(dev, "Cound not allocate mydev device\n"); return -ENOMEM; } dev_set_drvdata(dev, lp); lp->mem_start = r_mem->start; lp->mem_end = r_mem->end; if (!request_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1, DRIVER_NAME)) { dev_err(dev, "Couldn't lock memory region at %p\n", (void *)lp->mem_start); rc = -EBUSY; goto error1; } lp->base_addr = ioremap(lp->mem_start, lp->mem_end - lp->mem_start + 1); if (!lp->base_addr) { dev_err(dev, "mydev: Could not allocate iomem\n"); rc = -EIO; goto error2; } /* Get IRQ for the device */ r_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!r_irq) { dev_info(dev, "no IRQ found\n"); dev_info(dev, "mydev at 0x%08x mapped to 0x%08x\n", (unsigned int __force)lp->mem_start, (unsigned int __force)lp->base_addr); return 0; } lp->irq = r_irq->start; rc = request_irq(lp->irq, &mydev_irq, 0, DRIVER_NAME, lp); if (rc) { dev_err(dev, "testmodule: Could not allocate interrupt %d.\n", lp->irq); goto error3; } dev_info(dev,"mydev at 0x%08x mapped to 0x%08x, irq=%d\n", (unsigned int __force)lp->mem_start, (unsigned int __force)lp->base_addr, lp->irq); return 0; error3: free_irq(lp->irq, lp); error2: release_mem_region(lp->mem_start, lp->mem_end - lp->mem_start + 1); error1: kfree(lp); dev_set_drvdata(dev, NULL); return rc; } ```Zynq-700(ARM)割り込みがかからない Hardware : Microzed 開発環境 :Hyper-V+CentOS7 開発用OS :petalinux2016.2 です。 割り込みがかからず苦慮しております。 独自手法で開始してしまったためgpioも使用していません。 mydevはPIO、およびそれ以外の制御事項を含みます。 gpioに備わる割り込み要求intrは自作し、Zynqのinterrupt Fabric端子に入力しています。事実上gpioと同じと思います。 割り込み以外の機能は問題なく動作しています。 Xilinx社が配布しているドライバ用Templateをベースに開発を進めています。 以下その手順です: まず”元”になるPointer:pdevをinit 関数で取得します: これを実行させると、どのError表示も行われませんが、割り込みはかかりません。 割り込み要求はmydevのintr Portに10Hzの繰り返し波形、あるいはボタンによるLevel信号を印加することで、結果を確認しています。 オシロスコープで波形は確認済です。 他のPin入出力は良好に動作しているので、ここが問題とは考えにくいです。 Target側 cat /proc/interrupts の結果です。 18: 7179 1714 GIC 29 Edge twd 20: 0 0 GIC 38 Level mydev 21: 43 0 GIC 39 Level f8007100.adc 全く受かっていないようです。 Level割り込みになっているようなので、終了処理をしないと次が受かりません。 しかしゼロですからそれもないでしょう。 lp->irq=20の理由が分かりません。 Xynq-7000ではPL割り込みは61番以降なのです。 これは明らかに範囲外です。 しかしXilinxのCommunityで差し支えないような記述を見たこともあります。 関知する必要はないのでしょうか。 =20の出どころを探ってみました。 以下はdevice-treeのpl.dtsi Fileの内容です: / { amba_pl: amba_pl { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; ranges ; my_ip_0: my_ip@43c00000 { compatible = "xlnx,my-ip-189.2"; interrupt-parent = <&intc>; interrupts = <0 29 4>; reg = <0x43c00000 0x10000>; xlnx,s00-axi-my-ip-addr-width = <0x4>; xlnx,s00-axi-my-ip-data-width = <0x20>; }; }; }; この中に"20"は見当たりません。 petalinuxの場合*.dtb Fileはimage.ubに繰り込まれているので、特段の操作は不要と明記されていたように思います。しかし念のため起動用sdcardにsystem.dtbを格納してあります。参照の状況を見るため、下記を実行してみたのですが root@mydev:/sys/firmware/devicetree/base# cat compatible 何も表示されませんでした。 今回のケースではdevice-treeは参照されていなような感じがします。 "20"の出どころは謎です。 petalinuxの処理系がAssignしたのだから関知する必要はない、ということでしたら助かるのですが。 PLからの割り込みは61番以降という原則にこだわりがあったので lp->irq=20 → 61 に強引に書き換えてみました。これはxparameters.hで指定されている数値です。 cat /proc/interrupts の結果は 61: 0 0 zynq-gpio 38 Edge mydev でNGでした。ただI/F(?)がGICからzynq-gpioに、さらにLevel→Edgeに変更されています。本来は望ましい形です。 さらに割り込みPortに関しては謎がある、との指摘もありました。 http://www.tokudenkairo.co.jp/cosmoz/diary1609.html これに従い1本の割り込みをvivado上でxconcatを利用して候補となる16本全部に入力もしてみたですが、これもNGでした。 以上質問者があとできることはI/FがGICとなっているので、これに対応することです。 最低限Maskを開いてEnableにする、Level割り込みなので割り込みの都度Ackを返すなどは必須ではないかと思います。 この段階になると記述方法が分かりません。 わかりやすいサンプルあるいは直接的なCoding例などをご教示願えると助かります。 あるいはまったく別のところに原因がある、との指摘があればお願いいたします。
回答1件
あなたの回答
tips
プレビュー