android中device_attr 设备属性节点

本文详细介绍了如何使用device_create_file()和sysfs_create_file()函数创建sys文件接口及设备节点,并通过实例展示了如何实现GPIO控制和LED状态的读写操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 使用device_create_file( )函数创建sys文件接口

设备属性
sysfs 中的设备入口可有属性. 相关的结构是:

struct device_attribute {
struct attribute attr;
ssize_t (*show)(struct device *dev, char *buf);
ssize_t (*store)(struct device *dev, const char *buf,
size_t count);
};


这些属性结构可在编译时建立, 使用这些宏:
DEVICE_ATTR(name, mode, show, store);
结果结构通过前缀 dev_attr_ 到给定名子上来命名. 属性文件的实际管理使用通常的函数对来处理:
int device_create_file(struct device *device, struct device_attribute *entry);
void device_remove_file(struct device *dev, struct device_attribute *attr);

struct bus_type 的 dev_attrs 成员指向一个缺省的属性列表, 这些属性给添加到总线的每个设备创建.

2. 使用sysfs_create_file( )函数创建一个节点

static ssize_t gsensor_vendor_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{    
    char  val;    
    //val = simple_strtoul(buf, NULL, 10);    
    sscanf(buf, "%d", &val);
    if(val == 0)
    {        
        gpio_set_value(MMA8452_CON_PIN, 0);    
    }
    else
    {        
        gpio_set_value(MMA8452_CON_PIN, 1);    
    }    
    return strlen(buf);
}

static DEVICE_ATTR(vendor, 0777, gsensor_vendor_show, gsensor_vendor_store);

static struct kobject *android_gsensor_kobj;

static int gsensor_sysfs_init(void)
{
    int ret ;

    android_gsensor_kobj = kobject_create_and_add("android_gsensor", NULL);
    if (android_gsensor_kobj == NULL) {
        mmaprintk(KERN_ERR
               "MMA8452 gsensor_sysfs_init:"\
               "subsystem_register failed\n");
        ret = -ENOMEM;
        goto err;
    }

    ret = sysfs_create_file(android_gsensor_kobj, &dev_attr_vendor.attr);   // "vendor"
    if (ret) {
        mmaprintk(KERN_ERR
               "MMA8452 gsensor_sysfs_init:"\
               "sysfs_create_group failed\n");
        goto err4;
    }

    return 0 ;
err4:
    kobject_del(android_gsensor_kobj);
err:
    return ret ;
}




2.创建多个文件节点

ssize_t led_3g_green_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    u8 val;
    val = simple_strtoul(buf, NULL, 10);
    if(val == 0){
        gpio_set_value(MX53_HMS_3G_LED_GREEN_EN, 0);
    }else{
        gpio_set_value(MX53_HMS_3G_LED_GREEN_EN, 1);
    }
    return count;
}

ssize_t led_3g_green_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    sprintf(buf, "%d\n", gpio_get_value(MX53_HMS_3G_LED_GREEN_EN));
    return strlen(buf);
}

ssize_t led_3g_amber_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    u8 val;
    val = simple_strtoul(buf, NULL, 10);
    if(val == 0){
        gpio_set_value(MX53_HMS_3G_LED_AMBER_EN, 0);
    }else{
        gpio_set_value(MX53_HMS_3G_LED_AMBER_EN, 1);
    }
    return count;
}

ssize_t led_3g_amber_show(struct device *dev, struct device_attribute *attr, char *buf)
{
    sprintf(buf, "%d\n", gpio_get_value(MX53_HMS_3G_LED_AMBER_EN));
    return strlen(buf);
}

static DEVICE_ATTR(led_3g_green, S_IRUGO|S_IWUSR, led_3g_green_show, led_3g_green_store);
static DEVICE_ATTR(led_3g_amber, S_IRUGO|S_IWUSR, led_3g_amber_show, led_3g_amber_store);

static struct attribute* leds_mxc_gpio_attrs[] =
{
    &dev_attr_led_3g_green.attr,
    &dev_attr_led_3g_amber.attr,
    NULL
};
    
static const struct attribute_group leds_mxc_gpio_group =
{
    .attrs = leds_mxc_gpio_attrs,
};


result = sysfs_create_group(&drv_data->pdev->dev.kobj, &leds_mxc_gpio_group);
    if (result) {
        dev_err(&pdev->dev, "Create device file failed! ERRNO: %d\n",result);
        goto free_drv_data;
    }


<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/gradient_background"> <!-- 标题栏 --> <RelativeLayout android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?android:attr/actionBarSize" android:background="#44bd32"> <Button android:id="@+id/fanHui" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="8dp" android:layout_marginEnd="8dp" android:background="@android:color/transparent" android:foreground="?android:attr/selectableItemBackground" android:text="返回" android:textColor="@android:color/white" android:textSize="16sp" /> </RelativeLayout> <!-- 底部按钮 --> <LinearLayout android:id="@+id/footer_buttons" android:layout_width="match_parent" android:layout_height="1dp" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal"> <!-- <Button--> <!-- android:id="@+id/device_location"--> <!-- android:layout_width="match_parent"--> <!-- android:layout_height="match_parent"--> <!-- android:gravity="center"--> <!-- android:text="设备定位"--> <!-- android:textSize="19sp"--> <!-- android:background="#44bd32"--> <!-- android:textColor="@android:color/white" />--> </LinearLayout> <RelativeLayout android:id="@+id/video_container" android:layout_width="match_parent" android:layout_height="380dp" android:layout_above="@id/footer_buttons" android:layout_below="@id/toolbar" android:layout_marginBottom="298dp" android:background="@android:color/black" android:padding="0dp"> <!-- 视频播放器 --> <VideoView android:id="@+id/video_player" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerInParent="true" /> <!-- 播放控制条 --> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#99000000" android:orientation="horizontal" android:padding="8dp"> <ImageButton android:id="@+id/btn_play_pause" android:layout_width="40dp" android:layout_height="40dp" android:background="?attr/selectableItemBackgroundBorderless" android:src="@drawable/ic_play_sel" /> <SeekBar android:id="@+id/video_seekbar" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" /> <TextView android:id="@+id/tv_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="00:00/00:00" android:textColor="@android:color/white" android:textSize="14sp" /> </LinearLayout> <GridLayout android:id="@+id/thumbnail_grid" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/footer_buttons" android:layout_below="@id/video_container" android:layout_marginBottom="300dp" android:background="@android:color/white" android:columnCount="4" android:orientation="horizontal" android:padding="8dp" android:rowCount="2"> <!-- 动态添加的缩略图将放在这里 --> <!-- 示例缩略图 (可选) --> <ImageView android:layout_width="50dp" android:layout_height="wrap_content" android:layout_margin="4dp" android:adjustViewBounds="true" android:contentDescription="萤石缩略图" android:src="@drawable/default_thumbnail" /> <ImageView android:layout_width="50dp" android:layout_height="wrap_content" android:layout_margin="4dp" android:adjustViewBounds="true" android:contentDescription="萤石缩略图" android:src="@drawable/default_thumbnail" /> <!-- 更多缩略图... --> </GridLayout> </RelativeLayout> </RelativeLayout> 把布局文件中android:id="@+id/thumbnail_grid"放置在播放控制条的下面
最新发布
06-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值