Driver Attributes/Device Attributes 及作為linux的一種讀寫介面的用法(timed_output執行個體)

來源:互聯網
上載者:User

(1)Driver Attributes

struct driver_attribute {        struct attribute        attr;        ssize_t (*show)(struct device_driver *driver, char *buf);        ssize_t (*store)(struct device_driver *, const char * buf, size_t count);};

       Device drivers can export attributes via their sysfs directories.Drivers can declare attributes using a DRIVER_ATTR macro that works identically to the DEVICE_ATTR macro.執行個體:在GSENSOR 8452驅動中申明的屬性,可以在ADB中查看到屬性。

static DRIVER_ATTR(chipinfo,             S_IRUGO, show_chipinfo_value,      NULL);

static struct driver_attribute *mma8452q_attr_list[] = {
         &driver_attr_chipinfo,     /*chip information*/
         ........................................
};

static int mma8452q_create_attr(struct device_driver *driver)
{
          for(idx = 0; idx < num; idx++)
          {
                  if(err = driver_create_file(driver, mma8452q_attr_list[idx]))
                  {           
                           GSE_ERR("driver_create_file (%s) = %d\n", mma8452q_attr_list[idx]->attr.name, err);
                           break;
                 }
          }   
         return err;
}

之後,在終端路徑/sys/bus/platform/drivers/gsensor,就可以看到屬性值

(2)Device Attributes配合device_create_file

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

        Attributes of devices can be exported via drivers using a simple procfs-like interface,Attributes are declared using a macro called DEVICE_ATTR.執行個體,在電池驅動中添加的屬性,也可以在ADB中查出。

static ssize_t show_Power_On_Voltage(struct device *dev,struct device_attribute *attr, char *buf)
{
       int ret_value=1;
       ret_value = Batt_VoltToPercent_Table[0].BattVolt;
       printk("[EM] Power_On_Voltage : %d\n", ret_value);
       return sprintf(buf, "%u\n", ret_value);
}
static DEVICE_ATTR(Power_On_Voltage, 0664, show_Power_On_Voltage, store_Power_On_Voltage);

static int mt6573_battery_probe(struct platform_device *dev) 
{

    ...............................

    device_create_file(&(dev->dev), &dev_attr_Power_On_Voltage);

    ..............................

}

之後,在路徑/sys/devices/platform/mt6573-battery中可以看到屬性

(3)Device Attributes配合sysfs_create_file

         同樣是DEVICE_ATTR,建立sysfs的函數不同,得到的結果也不同。device_create_file的形參是struct device *和struct device_attribute *,而sysfs_create_file的形參是struct kobject *和struct attribute *。所以兩者的使用方法有區別:前者用在模組XXX_probe(struct platform_device *dev)中,因為需要&(dev->dev)得到要求的第一個形參;後者用在類似某I2C_probe(struct
i2c_client *client,xxx)中,因為需要&client->dev.kobj得到要求的第一個形參;兩者的第二個參數差別不大,struct device_attribute的一個成員就是struct attribute。下面舉一個使用sysfs_create_file的執行個體,實現使用ADB的cat 和echo命令來顯示韌體版本號碼和命令升級,其中執行個體中具體調用到的函數請見http://blog.csdn.net/zhandoushi1982/article/details/7704416。在TP驅動檔案中中添加DEVICE_ATTR屬性

static ssize_t melfas_version_show(struct device *dev,struct device_attribute *attr, char *buf)//顯示韌體版本號碼{ssize_t num_read_chars = 0;u8   fwver = 0;if(mfs_i2c_read_single_reg(0x21,&fwver) ==false)num_read_chars = snprintf(buf, PAGE_SIZE, "get tp fw version fail!\n");//提示讀韌體號錯誤elsenum_read_chars = snprintf(buf, PAGE_SIZE, "%02X\n", fwver);return num_read_chars;//返回韌體版本號碼值}static DEVICE_ATTR(melfasver, S_IRUGO|S_IWUSR, melfas_version_show, melfas_version_store);static ssize_t melfas_fwupdate_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count){//函數的形參並沒有用到int UpResult;mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);UpResult = ms6000_firmware_upgrade();//可以在串口資訊看到升級過程if(UpResult== MS6000_RET_SUCCESS){printk("MFS6000 DOWNLOAD SUCCESS \r\n");msleep(100);}elsemfs6000_print_fail_result(UpResult);i2c_client->addr = MS6000_8BIT_I2CADDR;mt_set_gpio_mode(GPIO_I2C0_SCA_PIN, GPIO_I2C0_SCA_PIN_M_SCL);mt_set_gpio_mode(GPIO_I2C0_SDA_PIN, GPIO_I2C0_SDA_PIN_M_SDA);mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);return count;}static DEVICE_ATTR(melfasupdate, S_IRUGO|S_IWUSR, melfas_fwupdate_show, melfas_fwupdate_store);

在static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id)中添加:

int err = 0;     err = sysfs_create_file(&client->dev.kobj, &dev_attr_melfasver.attr);   if (0 != err) {printk("sysfs_create_file dev_attr_melfasver failed \r\n");sysfs_remove_file(&client->dev.kobj, &dev_attr_melfasver.attr);} else {        printk("melfas:dev_attr_melfasver- sysfs_create_file() succeeded.\n");    }err = sysfs_create_file(&client->dev.kobj, &dev_attr_melfasupdate.attr);   if (0 != err) {printk("sysfs_create_file dev_attr_melfasupdate failed \r\n");sysfs_remove_file(&client->dev.kobj, &dev_attr_melfasupdate.attr);} else {        printk("melfas:dev_attr_melfasupdate - sysfs_create_file() succeeded.\n");    }

    編譯燒錄,最後查看屬性的路徑是:

用cat melfasver即可回顯韌體版本號碼,用echo 1 > melfasupdate即可實現發命令升級。需要注意的是,要留意store的巨集指令引數,上文僅僅是提供一個操作介面並不帶參數;如果需要用到*buf這個參數,注意它是字元,比如*buf為'0'或者'1'。

 (4)timed_output_dev裝置的讀寫
       綜(3)所執行個體,利用屬性操作中對檔案進行讀寫,也是除了檔案操作IOCTL之外的一種好方法,除了手動操作之外,也可以通過程式訪問show store屬性。timed_output_dev,就是時間輸出類的一個常用介面(定義在Timed_output.c (kernel\drivers\staging\android)),它的特點是要用timed_output_dev_register進行註冊,這樣就會組建目錄:/sys/class/timed_output,以一個馬達舉例。

首先是定義此類型裝置的結構體:

static struct timed_output_dev mt6573_vibrator = {.name = "vibrator",.get_time = vibrator_get_time,.enable = vibrator_enable,};

再在馬達的初始化中完成:

  timed_output_dev_register(&mt6573_vibrator);

    進入/sys/class/timed_output/vibrator/目錄,按pwd即可在ADB中看到如下的屬性:

用echo 0或者1> enable即可進行馬達的開關控制。這個完成的是驅動層,在上層比如一個測試程式,則可以通過write來調用到timed_output_dev的store函數介面,從而調用到enable。類似,通過read可以得到show屬性值。

#define THE_DEVICE "/sys/class/timed_output/vibrator/enable"static int sendit(int timeout_ms){    int nwr, ret, fd;    char value[20];    fd = open(THE_DEVICE, O_RDWR);    if(fd < 0)        return errno;    nwr = sprintf(value, "%d\n", timeout_ms);    ret = write(fd, value, nwr);    close(fd);    return (ret == nwr) ? 0 : -1;}int vibrator_on(int timeout_ms){    return sendit(timeout_ms);}int vibrator_off(){    return sendit(0);}

 參考文章:http://blog.csdn.net/wtao616/article/details/6147721

參考文章:http://blog.csdn.net/zq5848/article/details/6857453

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.