正点原子I.MX6ULL mini适配xueliu dw1000驱动

May 11, 2024

相较于网上的其他驱动而言,这个驱动结构较为简单,并且需要的内核版本也较低,可以在略微修改之后兼容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,
};

编写一版驱动 根据教程 img.png img_1.png 我们可以对应修改即可

解决缺少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”问题的研究


Profile picture

Written by Prosumer , an undergraduate student at ShanghaiTech.
Welcome to my GitHub:)