相较于网上的其他驱动而言,这个驱动结构较为简单,并且需要的内核版本也较低,可以在略微修改之后兼容linux4.1版本,因而选择该驱动
首先,为这个驱动配套一版设备树
我们需要根据
rstn = devm_gpiod_get(&spi->dev, "rstn", GPIOD_OUT_LOW);
static const struct of_device_id dw1000_of_match[] = {
{ .compatible = "decaWave,dw1000", },
{ },
};
MODULE_DEVICE_TABLE(of, dw1000_of_match);
static const struct spi_device_id dw1000_device_id[] = {
{ .name = "dw1000", },
{ },
};
MODULE_DEVICE_TABLE(spi, dw1000_device_id);
static struct spi_driver dw1000_driver = {
.id_table = dw1000_device_id,
.driver = {
.of_match_table = dw1000_of_match,
.name = "dw1000",
},
.probe = dw1000_probe,
.remove = dw1000_remove,
};
解决缺少IEEE802154模块问题
移植完设备树,并将驱动编译成功发到开发板上,调试时发现报错
dw1000: Unknown symbol ieee802154_alloc_hw (err 0)
dw1000: Unknown symbol ieee802154_xmit_complete (err 0)
dw1000: Unknown symbol ieee802154_rx_irqsafe (err 0)
dw1000: Unknown symbol ieee802154_unregister_hw (err 0)
dw1000: Unknown symbol ieee802154_free_hw (err 0)
dw1000: Unknown symbol ieee802154_register_hw (err 0)
dw1000: Unknown symbol ieee802154_alloc_hw (err 0)
dw1000: Unknown symbol ieee802154_xmit_complete (err 0)
dw1000: Unknown symbol ieee802154_rx_irqsafe (err 0)
dw1000: Unknown symbol ieee802154_unregister_hw (err 0)
为了加载该模块,需要在相应的defconfig(正点原子为imx_alientek_emmc_defconfig)中加入
CONFIG_IEEE802154=y
CONFIG_MAC802154=y
然后重新
make imx_alientek_emmc_defconfig
make all -j12
然后发现报错变为了
dw1000: no symbol version for ieee802154_free_hw
dw1000: Unknown symbol ieee802154_free_hw (err -22)
dw1000: no symbol version for ieee802154_register_hw
dw1000: Unknown symbol ieee802154_register_hw (err -22)
dw1000: no symbol version for ieee802154_alloc_hw
dw1000: Unknown symbol ieee802154_alloc_hw (err -22)
dw1000: no symbol version for ieee802154_xmit_complete
dw1000: Unknown symbol ieee802154_xmit_complete (err -22)
dw1000: no symbol version for ieee802154_rx_irqsafe
dw1000: Unknown symbol ieee802154_rx_irqsafe (err -22)
dw1000: no symbol version for ieee802154_unregister_hw
dw1000: Unknown symbol ieee802154_unregister_hw (err -22)
dw1000: no symbol version for ieee802154_free_hw
dw1000: Unknown symbol ieee802154_free_hw (err -22)
dw1000: no symbol version for ieee802154_register_hw
dw1000: Unknown symbol ieee802154_register_hw (err -22)
dw1000: no symbol version for ieee802154_alloc_hw
dw1000: Unknown symbol ieee802154_alloc_hw (err -22)
dw1000: no symbol version for ieee802154_xmit_complete
dw1000: Unknown symbol ieee802154_xmit_complete (err -22)
dw1000: no symbol version for ieee802154_rx_irqsafe
dw1000: Unknown symbol ieee802154_rx_irqsafe (err -22)
dw1000: no symbol version for ieee802154_unregister_hw
dw1000: Unknown symbol ieee802154_unregister_hw (err -22)
modprobe: can't load module dw1000.ko (dw1000.ko): Invalid argument
这就是因为虽然我们的内核更新了,但是驱动没能成功重新链接相应符号 所以我们要重新编译驱动 这是相应的Makefile
obj-m += dw1000.o
KERNELDIR := /home/alientek/linux/IMX6ULL/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga
ENV:=ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
CURRENT_PATH := $(shell pwd)
build: kernel_modules
kernel_modules:
$(MAKE) $(ENV) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:
$(MAKE) $(ENV) -C $(KERNELDIR) M=$(CURRENT_PATH) clean
make之后传到板子的根文件系统中
发现并解决设备树冲突/问题
驱动能够运行了,但是发现读不到东西
dw1000 spi2.0: Detected DW1000 chip id: 0x00000000
这是因为当前的设备树有冲突,可以运行命令
dmesg | grep spi
发现报错
imx6ul-pinctrl 20e0000.iomuxc: pin MX6UL_PAD_UART2_TX_DATA already requested by 21e8000.serial; cannot claim for 2010000.ecspi
imx6ul-pinctrl 20e0000.iomuxc: pin-37 (2010000.ecspi) status -22
查看设备树可以发现,是因为uart2和我们使用了相同的引脚,将uart2设置为disable即可 结果发现,还是没成功,chip id应该是0xDECA0130,结果是
dw1000 spi2.0: Detected DW1000 chip id: 0x80808000
为了能够及时发现自己的设备树编写和驱动probe的过程中是否有问题,我们可以加上下面两句:
printk("dw1000: rstn gpio is %d\n", gpiod_to_irq(rstn));
printk("dw1000: spi pins are %d\n", spi->cs_gpio);
同时,可以把dev_dbg重新定义为
#define dev_dbg(dev, fmt, args...) \
printk(KERN_DEBUG "%s: " fmt, dev_name(dev), ##args)
然后发现
dw1000: rstn gpio is 36
dw1000: spi pins are -2
这就说明我们spi的cs_gpio有问题,回看设备树 发现
cs-gpio = <&gpio1 20 GPIO_ACTIVE_LOW>;
改为
cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
终于,发现能够成功打印出
dw1000 spi2.0: Detected DW1000 chip id: 0xdeca0130
dw1000 spi2.0: OTP Rev: 0x60
dw1000 spi2.0: OTP LDO Turn: 0xfe
dw1000 spi2.0: OTP XTAL Trim: 0xfe
dw1000 spi2.0: Microcode is loaded
但是由于当前版本的linux中没有ieee802154_is_valid_extended_unicast_addr函数,所以暂时
OTP EUI not found
参考: xueliu/dw1000-linux驱动源码 关于内核模块挂载出现“no symbol version for”问题的研究