由于VL53L4CD具有更高的精度,更低的功耗,所以尝试将VL53L4CD移植到X2000上进行测试。
en.VL53L4CD_LinuxDriver
二、SDK中加入驱动
1、加入源码
在\module_driver\devices下创建VL53L4CD文件夹,再将\en.VL53L4CD_LinuxDriver\VL53L4CD_LinuxDriver_V2.1.1\kernel中的stmvl53l4cd_i2c.c、stmvl53l4cd_module.c、stmvl53l4cd_i2c.h文件拷贝到\module_driver\devices\VL53L4CD下。
2、添加Makefile
再创建一个Makefile,写入内容如下:
#
# Makefile for the stmvl53l4cd drivers.
#
include $(DRIVERS_DIR)/tools/common_module.mk
EXTRA_CFLAGS +=-Wno-error=date-time
EXTRA_CFLAGS +=-Wno-date-time
MODULE_NAME:= stmvl53l4cd
module-y += stmvl53l4cd_i2c.o
module-y += stmvl53l4cd_module.o
KBUILD_EXTRA_SYMBOLS := $(DRIVERS_DIR)/drivers/utils/Module.symvers
obj-m = $(MODULE_NAME).o
$(MODULE_NAME)-y = $(module-y)
3、修改stmvl53l4cd_module.c文件
/*
* GPIO number connected to VL53L4CD interrupt signal GPIO1
*/
--#define IRQ_GPIO -1
--static int intr_gpio_nb = IRQ_GPIO;
++static int intr_gpio_nb;
++//irq gpio info
++module_param_gpio_named(stmvl53l4cd_irq_gpio, intr_gpio_nb, 0644);
--module_param(intr_gpio_nb, int, 0000);
--MODULE_PARM_DESC(intr_gpio_nb, "select gpio number to use for vl53l4cd interrupt");
++static u32 i2c_bus_num;
++struct i2c_client * i2c_connect_client = NULL;
++/* get data */
++module_param_named(stmvl53l4cd_i2c_bus_num , i2c_bus_num, int, 0644);
++static struct i2c_board_info stmvl53l4cd_info = {
++ .type = STMVL53L4CD_DRV_NAME,
++ .addr = STMVL53L4CD_SLAVE_ADDR,
++};
static int __init st_tof_module_init(void)
{
int ret = 0;
printk("stmvl53l4cd: module init\n");
/* register as a i2c client device */
ret = i2c_add_driver(&stmvl53l4cd_i2c_driver);
if (ret) {
i2c_del_driver(&stmvl53l4cd_i2c_driver);
printk("stmvl53l4cd: could not add i2c driver\n");
return ret;
}
++ i2c_connect_client = i2c_register_device(&stmvl53l4cd_info, i2c_bus_num);
++ if (i2c_connect_client == NULL) {
++ printk("failed to register i2c device\n");
++ i2c_del_driver(&stmvl53l4cd_i2c_driver);
++ return -EINVAL;
++ }
i2c_driver_added = 1;
return ret;
}
static int stmvl53l4cd_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret;
stmvl53l4cd_i2c_client = client;
printk("stmvl53l4cd: probing i2c\n");
raw_data_buffer = kzalloc(VL53L4CD_COMMS_CHUNK_SIZE, GFP_DMA | GFP_KERNEL);
if (raw_data_buffer == NULL)
return -ENOMEM;
st_tof_miscdev.minor = MISC_DYNAMIC_MINOR;
st_tof_miscdev.name = "stmvl53l4cd";
st_tof_miscdev.fops = &stmvl53l4cd_ranging_fops;
st_tof_miscdev.mode = 0444;
ret = misc_register(&st_tof_miscdev);
if (ret) {
pr_err("stmvl53l4cd : Failed to create misc device, err = %d\n", ret);
return -1;
}
misc_registered = 1;
if (intr_gpio_nb != -1)
{
ret = get_gpio(intr_gpio_nb, "vl53l5_intr_gpio", 0);
if (ret != 0) {
pr_err("Failed to acquire INTR GPIO(%d)\n", intr_gpio_nb);
} else {
gpio_own_flags.intr_gpio_owned = 1;
st_tof_irq_num = gpio_to_irq(intr_gpio_nb);
init_waitqueue_head(&wq);
ret = request_threaded_irq(st_tof_irq_num,
NULL,
st_tof_intr_handler,
IRQF_TRIGGER_RISING|IRQF_ONESHOT,
"st_tof_sensor",
NULL);
if (ret) {
-- pr_err("stmvl53l4cd: Failed to Register IRQ handler,"
-- " GPIO = %d, st_tof_irq_num = %d\n",
-- IRQ_GPIO, st_tof_irq_num);
++ pr_err("stmvl53l4cd: Failed to Register IRQ handler,"
++ " GPIO = %d, st_tof_irq_num = %d\n",
++ intr_gpio_nb, st_tof_irq_num);
kfree(raw_data_buffer);
misc_deregister(&st_tof_miscdev);
misc_registered = 0;
return -EPERM;
} else {
-- printk("stmvl53l4cd: Registered IRQ handler, GPIO = %d, "
-- "st_tof_irq_num = %d\n",
-- IRQ_GPIO, st_tof_irq_num);
++ printk("stmvl53l4cd: Registered IRQ handler, GPIO = %d, "
++ "st_tof_irq_num = %d\n",
++ intr_gpio_nb, st_tof_irq_num);
irq_handler_registered = 1;
}
}
}
return ret;
}
4、添加配置文件
在\module_driver\package\devices\other路径下添加
VL53L4CD\Config.in
VL53L4CD\vl53l4cd.mk
两个文件。
VL53L4CD\Config.in的内容如下:
menuconfig MD_STMVL53l4CD
bool "stmvl53l4cd"
config MD_VL53L4CD_IRQ_GPIO
string "gpio irq(VL53L4CD 中断引脚)"
choice from SOC_GPIO_PINS
config MD_VL53L4CD_I2C_BUSNUM
int "i2c bus num(VL53L4CD挂接的i2c总线号)"
default -1
endmenu
用于配置所连接的I2C总线编号、IRQ GPIO编号。
VL53L4CD\vl53l4cd.mk内容如下:
#-------------------------------------------------------
package_name = stmvl53l4cd
package_depends = utils
package_module_src = devices/VL53L4CD/
package_make_hook =
package_init_hook =
package_finalize_hook = stmvl53l4cd_finalize_hook
package_clean_hook =
#-------------------------------------------------------
stmvl53l4cd_init_file = output/stmvl53l4cd.sh
define stmvl53l4cd_finalize_hook
$(Q)cp devices/VL53L4CD/stmvl53l4cd.ko output/
$(Q)echo "insmod stmvl53l4cd.ko \\" >> $(stmvl53l4cd_init_file)
$(Q)echo " stmvl53l4cd_i2c_bus_num=$(MD_VL53L4CD_I2C_BUSNUM) \\" >> $(stmvl53l4cd_init_file)
$(Q)echo " stmvl53l4cd_irq_gpio=$(MD_VL53L4CD_IRQ_GPIO) \\" >> $(stmvl53l4cd_init_file)
$(Q)echo >> $(stmvl53l4cd_init_file)
endef
用于将编译生成的驱动模块拷贝到\module_driver\output目录下,生成驱动的加载脚本。
other\Config.in文件中加入VL53L4CD的配置:
source /package/devices/other/VL53L4CD/Config.in
other\other.mk文件中加入VL53L4CD的mk:
package-$(MD_STMVL53l4CD) += package/devices/other/VL53L4CD/vl53l4cd.mk
5、配置文件中选中VL53L4CD
cd到tools/iconfigtool/IConfigToolApp/目录,执行./IConfigTool,选择要修改的配置文件
点击Open
依次点击 模块驱动->外设->其它类型驱动列表,选中stmvl53l4cd
点击 stmvl53l4cd后的==>,然后选择IRQ GPIO和填写I2C总线编号
cd到build目录,执行
make x2100_nand_defconfig
make app_module_driver
make buildroot
编程成功后,会生成新的rootfs.squashfs,重新烧写rootfs.squashfs文件。
1、查看是否正确加载
执行cmd_i2c detect 5命令查看i2c5总线上是否有设备
# cmd_i2c detect 5
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- UU -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
可见i2c5总线上有地址为0x29的设备,并且注册了驱动。
2、查看dev是否有设备
# ls /dev/stm*
/dev/stmvl53l4cd