드라이버데이11

4792 단어
问题1:安装模块没有打印信息
解决方法:linux内核默认优先级的设置为7,改为4
메뉴 설정을 하다
커널 해킹 --->
(4) 기본 메시지 로그 수준(1-7)
uImage 만들기
问题2:卸载模块失败

디렉토리를 '3.4.39-tarena'로 변경할 수 없습니다: 해당 파일 또는 디렉토리가 없습니다
변경 방법: mkdir/lib/modules/3.4.39-tarena -p

内核中关于I2C设备驱动的编程框架
总线驱动模型
6.1 기술
드라이버/i2c/i2c-core.c
bus_register(&i2c_bus_type)
6.2 设备
구조 장치
구조체 platform_device
구조체 i2c_client
{
구조체 장치 개발
unsigned short addr;//从设备地址
문자 이름[I2C_NAME_SIZE];//匹配
//장치장치链接到哪个I2C控制器
struct i2c_adapter 어댑터;
...
}
/정정 初始化 注册i2c_client*/
i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
무효 i2c_unregister_device(struct i2c_client *)
}
6.3 设备驱动
구조체 device_driver
구조체 플랫폼_드라이버
구조체 i2c_driver {
조사
제거하다
struct device_driver 드라이버;
//该driver可以驱动的设备ID列表
const struct i2c_device_id *id_table;
...
}
i2c_add_driver
i2c_del_driver

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/fs.h>



MODULE_LICENSE("GPL");
MODULE_AUTHOR("XuPengYuan");


struct i2c_device_id mma8653_id[] = 
{
        {"mma8653", 0},  
        {}
};

struct i2c_client *g_client = NULL;

void mma8653_hw_init(struct i2c_client *client)
{
    int id = 0;
    id = i2c_smbus_read_byte_data(client, 0x0d);
    printk("%s: salve addr=%#x ID=%#x\n", __func__, client->addr, id);
    i2c_smbus_write_byte_data(client, 0x2a, 0);
    i2c_smbus_write_byte_data(client, 0x0e, 0);
}

#define GETXYZ_CMD 0x10001
struct mma8653_data
{
    short x;
    short y;
    short z;
};

void config_active()
{
    unsigned char data = 0;
    data = i2c_smbus_read_byte_data(g_client, 0x2a);
    data |= 1;
    i2c_smbus_write_byte_data(g_client, 0x2a, data);
}

void mma8653_read_acc(struct mma8653_data *pdata)
{
    unsigned char tmp[6];
    i2c_smbus_read_i2c_block_data(g_client, 0x01, 6, tmp);
    pdata->x = tmp[0] << 8 | tmp[1];
    pdata->x >>= 6;
    pdata->y = tmp[2] << 8 | tmp[3];
    pdata->y >>= 6;
    pdata->z = tmp[4] << 8 | tmp[5];
    pdata->z >>= 6;

}

long mma8653_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
    struct mma8653_data acc;
    int ret = 0;
    switch(cmd)
    {
        case GETXYZ_CMD:
                config_active();
                mma8653_read_acc(&acc);
                ret = copy_to_user((void *)arg, &acc, sizeof(acc));
                break;
         default:
                return -EINVAL;
    }
    return 0;
}

struct file_operations mma8653_fops = 
{
    .owner = THIS_MODULE,
    .unlocked_ioctl = mma8653_ioctl,
};

struct miscdevice mma8653_misc = 
{
    .minor = MISC_DYNAMIC_MINOR,
    .name = "mma865x",
    .fops = &mma8653_fops,
};

int mma8653_probe(struct i2c_client * client, const struct i2c_device_id *id)
{
    printk("xpy call %s\n", __func__);
    misc_register(&mma8653_misc);    
    g_client = client;
    mma8653_hw_init(client);
    return 0;
}
int mma8653_remove(struct i2c_client *client)
{
    printk("xpy call %s\n", __func__);
    misc_deregister(&mma8653_misc);
    return 0;
}
struct i2c_driver mma8653_drv = 
{
      .driver = 
      {
        .name = "mma865x",
      },
      .probe = mma8653_probe,
      .remove = mma8653_remove,
      .id_table = mma8653_id,
};

int __init mma8653_drv_init(void)
{
    i2c_add_driver(&mma8653_drv);
    return 0;
}

void __exit mma8653_drv_exit(void)
{
    i2c_del_driver(&mma8653_drv);
}


module_init(mma8653_drv_init);
module_exit(mma8653_drv_exit);




#include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>
#include <stdio.h>

#include <unistd.h>

#define GETXYZ_CMD 0x10001

struct acc_data
{
    short x;
    short y;
    short z;
}acc;

int main(void)
{
    int fd = open("/dev/mma865x", O_RDWR);
    if (fd < 0) 
    {
        perror("open");
        return -1;
    }
    while(1)
    {
        ioctl(fd, GETXYZ_CMD, &acc);
        printf("x=%d y=%d z=%d\n", acc.x, acc.y, acc.z);
        usleep(1000*1000);
    }
    close(fd);
    return 0;
}

좋은 웹페이지 즐겨찾기