Linux中debugfs的应用实例
来源:互联网 发布:大数据hive 编辑:程序博客网 时间:2024/05/22 07:44
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
struct at24c02_data {
uint8_t addr;
uint8_t data;
struct dentry *dir;
struct i2c_client *client;
};
// 检查寄存器索引是否有效
static bool at24c02_debug_addr_is_valid(uint8_t addr)
{
if (addr < 0 || addr > 0xff) {
pr_err("eeprom reg address is invalid: 0x%x\n", addr);
return false;
}
return true;
}
// 读取寄存器索引
static int at24c02_debug_addr_get(void *_data, u64 *val)
{
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr))
*val = pdata->addr;
return 0;
}
// 设置寄存器索引
static int at24c02_debug_addr_set(void *_data, u64 val)
{
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(val))
pdata->addr = val;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_addr_fops, at24c02_debug_addr_get,
at24c02_debug_addr_set, "0x%02llX\n");
// 读取pdata->addr寄存器的值,存放在val所指向的地址中
static int at24c02_debug_data_get(void *_data, u64 *val)
{
int rt = 0;
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr)) {
rt = i2c_smbus_read_byte_data(pdata->client, pdata->addr);
if (rt < 0)
pr_err("at24c02 read register 0x%x failed %d\n", pdata->addr, rt);
else
*val = rt;
}
return 0;
}
// 向pdata->addr寄存器写入val
static int at24c02_debug_data_set(void *_data, u64 val)
{
int rt = 0;
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr)) {
rt = i2c_smbus_write_byte_data(pdata->client, pdata->addr, val);
if (rt < 0)
pr_err("at24c02 write register 0x%x failed %d\n", pdata->addr, rt);
}
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_data_fops, at24c02_debug_data_get,
at24c02_debug_data_set, "0x%02llX\n");
static int at24c02_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rt = 0;
struct at24c02_data *pdata;
struct dentry *temp;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, "SMBUS Word Data not Supported\n");
return -EIO;
}
pdata = devm_kzalloc(&client->dev,
sizeof(struct at24c02_data), GFP_KERNEL);
if (!pdata) {
dev_err(&client->dev, "Not enough memory\n");
return -ENOMEM;
}
pdata->client = client;
i2c_set_clientdata(client, pdata);
pdata->dir = debugfs_create_dir("eeprom_debug", NULL);
if (pdata->dir == NULL || IS_ERR(pdata->dir)) {
pr_err("debugfs_create_dir failed(%ld)\n", PTR_ERR(pdata->dir));
rt = PTR_ERR(pdata->dir);
return rt;
}
temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, pdata->dir, pdata,
&debug_addr_fops);
if (temp == NULL || IS_ERR(temp)) {
pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
rt = PTR_ERR(pdata->dir);
return rt;
}
temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, pdata->dir, pdata,
&debug_data_fops);
if (temp == NULL || IS_ERR(temp)) {
pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
rt = PTR_ERR(pdata->dir);
return rt;
}
pr_err("%s succeeded\n", __func__);
return 0;
}
static int at24c02_i2c_remove(struct i2c_client *client)
{
struct at24c02_data *pdata = i2c_get_clientdata(client);
debugfs_remove_recursive(pdata->dir);
kfree(pdata);
return 0;
}
static const struct i2c_device_id at24c02_id[] = {
{ "at24c02", 0 },
};
MODULE_DEVICE_TABLE(i2c, at24c02_id);
static struct i2c_driver at24c02_i2c_driver = {
.driver = {
.name = "at24c02",
.owner = THIS_MODULE,
},
.probe = at24c02_i2c_probe,
.remove = at24c02_i2c_remove,
.id_table = at24c02_id,
};
static int at24c02_i2c_init(void)
{
return i2c_add_driver(&at24c02_i2c_driver);
}
module_init(at24c02_i2c_init);
static void at24c02_i2c_exit(void)
{
i2c_del_driver(&at24c02_i2c_driver);
}
module_exit(at24c02_i2c_exit);
MODULE_AUTHOR("yuntaohe");
MODULE_DESCRIPTION("at24c02 eeprom driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("i2c:at24c02");
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/debugfs.h>
struct at24c02_data {
uint8_t addr;
uint8_t data;
struct dentry *dir;
struct i2c_client *client;
};
// 检查寄存器索引是否有效
static bool at24c02_debug_addr_is_valid(uint8_t addr)
{
if (addr < 0 || addr > 0xff) {
pr_err("eeprom reg address is invalid: 0x%x\n", addr);
return false;
}
return true;
}
// 读取寄存器索引
static int at24c02_debug_addr_get(void *_data, u64 *val)
{
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr))
*val = pdata->addr;
return 0;
}
// 设置寄存器索引
static int at24c02_debug_addr_set(void *_data, u64 val)
{
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(val))
pdata->addr = val;
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_addr_fops, at24c02_debug_addr_get,
at24c02_debug_addr_set, "0x%02llX\n");
// 读取pdata->addr寄存器的值,存放在val所指向的地址中
static int at24c02_debug_data_get(void *_data, u64 *val)
{
int rt = 0;
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr)) {
rt = i2c_smbus_read_byte_data(pdata->client, pdata->addr);
if (rt < 0)
pr_err("at24c02 read register 0x%x failed %d\n", pdata->addr, rt);
else
*val = rt;
}
return 0;
}
// 向pdata->addr寄存器写入val
static int at24c02_debug_data_set(void *_data, u64 val)
{
int rt = 0;
struct at24c02_data *pdata = _data;
if (at24c02_debug_addr_is_valid(pdata->addr)) {
rt = i2c_smbus_write_byte_data(pdata->client, pdata->addr, val);
if (rt < 0)
pr_err("at24c02 write register 0x%x failed %d\n", pdata->addr, rt);
}
return 0;
}
DEFINE_SIMPLE_ATTRIBUTE(debug_data_fops, at24c02_debug_data_get,
at24c02_debug_data_set, "0x%02llX\n");
static int at24c02_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rt = 0;
struct at24c02_data *pdata;
struct dentry *temp;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, "SMBUS Word Data not Supported\n");
return -EIO;
}
pdata = devm_kzalloc(&client->dev,
sizeof(struct at24c02_data), GFP_KERNEL);
if (!pdata) {
dev_err(&client->dev, "Not enough memory\n");
return -ENOMEM;
}
pdata->client = client;
i2c_set_clientdata(client, pdata);
pdata->dir = debugfs_create_dir("eeprom_debug", NULL);
if (pdata->dir == NULL || IS_ERR(pdata->dir)) {
pr_err("debugfs_create_dir failed(%ld)\n", PTR_ERR(pdata->dir));
rt = PTR_ERR(pdata->dir);
return rt;
}
temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, pdata->dir, pdata,
&debug_addr_fops);
if (temp == NULL || IS_ERR(temp)) {
pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
rt = PTR_ERR(pdata->dir);
return rt;
}
temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, pdata->dir, pdata,
&debug_data_fops);
if (temp == NULL || IS_ERR(temp)) {
pr_err("debugfs_create_file failed: rc=%ld\n", PTR_ERR(temp));
rt = PTR_ERR(pdata->dir);
return rt;
}
pr_err("%s succeeded\n", __func__);
return 0;
}
static int at24c02_i2c_remove(struct i2c_client *client)
{
struct at24c02_data *pdata = i2c_get_clientdata(client);
debugfs_remove_recursive(pdata->dir);
kfree(pdata);
return 0;
}
static const struct i2c_device_id at24c02_id[] = {
{ "at24c02", 0 },
};
MODULE_DEVICE_TABLE(i2c, at24c02_id);
static struct i2c_driver at24c02_i2c_driver = {
.driver = {
.name = "at24c02",
.owner = THIS_MODULE,
},
.probe = at24c02_i2c_probe,
.remove = at24c02_i2c_remove,
.id_table = at24c02_id,
};
static int at24c02_i2c_init(void)
{
return i2c_add_driver(&at24c02_i2c_driver);
}
module_init(at24c02_i2c_init);
static void at24c02_i2c_exit(void)
{
i2c_del_driver(&at24c02_i2c_driver);
}
module_exit(at24c02_i2c_exit);
MODULE_AUTHOR("yuntaohe");
MODULE_DESCRIPTION("at24c02 eeprom driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("i2c:at24c02");
调试:
root@(none) /sys/kernel/debug/eeprom_debug$ echo 0xaa > addr
root@(none) /sys/kernel/debug/eeprom_debug$ echo 0x55 > data
root@(none) /sys/kernel/debug/eeprom_debug$ cat data
0x55
0 0
- Linux中debugfs的应用实例
- Linux中debugfs的解析
- linux的debugfs
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的debugfs
- Linux内核里的DebugFS
- linux内核里的Debugfs
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- Linux内核里的DebugFS
- linux debugfs
- linux debugfs
- QQ联系人菜单2:
- 错误:/bin/sh: 1: protoc: not found
- MTK6797 Accdet驱动分析总结
- webView使用大全
- 隐马尔可夫模型(五)——隐马尔可夫模型的解码问题(维特比算法)
- Linux中debugfs的应用实例
- Android开发中远程连接
- 14.4.6 Configuring Thread Concurrency for InnoDB 配置Thread 并发
- 在高速信号换层时打回流地VIA过孔,减小回流路径
- 画布画笔
- 修改ubuntu的apt-get软件源
- Android中简易天气预报的设计与实现 (1)
- 处理输入框被键盘遮盖的问题
- 爬虫