我正在尝试为Linux内核编写ADXL345加速度计的测试驱动程序。我将开发过程分为两个阶段。第一阶段是通过拉动机制读取的值。第二阶段是在加速度计的两个中断段发生中断时缓存数据。
这里有一个很好的文档 - > Linux official kernel documentation
我调查了我的代码 - > https://github.com/rslemos/itrigue/blob/master/alsadriver/itrigue.c
在我接下来的示例中,没有声明和使用 spi_driver 结构。
adxlSpiDevice = spi_new_device(master, &adxlSpiDeviceInfo);
但是官方驱动程序的源代码spi_driver声明了。
module_spi_driver(adxl34x_driver);
所以我很困惑我必须选择哪种方法,或者我必须同时使用这两种方法?
这是我的完整代码:
/**
* @file idealSpiDriver.c
* @author Mehmet Ozgur Bayhan
* @date 10.11.2016
* @version 0.1
* @brief An introductory SPI driver.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/gpio.h>
#include <linux/spi/spi.h>
/* MP - Can be initialize as a parameter of a module */
// TODO : Set real values for these
static uint onoff_gpio = 139;
static uint adxl_spi_bus = 4;
static uint adxl_spi_cs = 0;
static uint speed_hz = 1500000;
static uint bits_per_word = 16;
/* -MP */
static struct spi_device *adxlSpiDevice;
static void adxl_spi_write(uint16_t write_data)
{
spi_write(adxlSpiDevice, &write_data, sizeof write_data);
}
static int adxl_spi_read(void *buf, size_t len)
{
return spi_read(adxlSpiDevice, *buf, len);
}
static int adxl_spi_init(void)
{
struct spi_master *spiMaster;
int retval;
struct spi_board_info adxlSpiDeviceInfo;
adxlSpiDeviceInfo.modalias = "idealSpiDriver";
adxlSpiDeviceInfo.max_speed_hz = speed_hz;
adxlSpiDeviceInfo.bus_num = adxl_spi_bus;
adxlSpiDeviceInfo.chip_select = adxl_spi_cs;
adxlSpiDeviceInfo.mode = 0;
master = spi_busnum_to_master(adxlSpiDeviceInfo.bus_num);
if ( !master )
{
return -ENODEV;
}
adxlSpiDevice = spi_new_device(master, &adxlSpiDeviceInfo);
if ( !adxlSpiDevice )
{
return -ENODEV;
}
adxlSpiDevice->bits_per_word = bits_per_word;
retval = spi_setup(adxlSpiDevice);
if ( retval )
{
spi_unregister_device(adxlSpiDevice);
}
else
{
printk(KERN_WARNING "MOB : Cant initialize spi device\n");
}
return retval;
}
// TODO: add __init before production
static int adxl_driver_init(void)
{
int retval;
retval = adxl_spi_init();
if (retval > 0)
{
printk(KERN_INFO "MOB : IdealSpiDriver loaded\n");
}
return retval;
}
// TODO: add __exit before production
static void adxl_driver_exit(void)
{
spi_unregister_device(adxlSpiDevice);
printk(KERN_INFO "MOB : IdealSpiDriver unloaded\n");
}
module_init(adxl_driver_init);
module_exit(adxl_driver_exit);
//static struct spi_driver adxl34x_driver = {
// .driver = {
// .name = "adxl34x",
// .pm = &adxl34x_spi_pm,
// },
// .probe = adxl34x_spi_probe,
// .remove = adxl34x_spi_remove,
//};
//module_spi_driver(adxl34x_driver);
MODULE_AUTHOR("Mehmet Ozgur Bayhan");
MODULE_DESCRIPTION("Test Driver For ADXL345 Accelerometer");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");
我打算通过这种方式添加角色设备并从用户空间中提取数据。那么我必须注册 adxl34x_driver 结构吗?如果是,为什么?