misc_register


雜項設備

linux里面的misc雜項設備是主設備號為 10的驅動設備
定義頭文件<linux/miscdevice.h>
 
雜項設備的結構體:
struct miscdevice{
  int minor; //雜項設備的此設備號(如果設置為MISC_DYNAMIC_MINOR,表示系統自動分配未使用的minor)
  const char *name;
  const stuct file_operations *fops;//驅動主題函數入口指針
  struct list_head list;
  struct device *parent;
  struct device *this device;
  const char *nodename;(在/dev下面創建的設備驅動節點)
  mode_t mode;
};

 

 
注冊和釋放
注冊:int misc_register(struct miscdevice *misc)
釋放:int misc_deregister(struct miscdevice *misc)
 
misc_device是特殊字符設備。注冊驅動程序時采用misc_register函數注冊,此函數中會自動創建設備節點,即設備文件。無需mknod指令創建設備文件。因為misc_register()會調用class_device_creat或者device_creat().
雜項字符設備和一般字符設備的區別:
1.一般字符設備首先申請設備號。  但是雜項字符設備的主設備號為10次設備號通過結構體struct miscdevice中的minor來設置。
2.一般字符設備要創建設備文件。 但是雜項字符設備在注冊時會自動創建。
3.一般字符設備要分配一個cdev(字符設備)。  但是雜項字符設備只要創建struct miscdevice結構即可。
4.一般字符設備需要初始化cdev(即給字符設備設置對應的操作函數集struct file_operation). 但是雜項字符設備在結構體truct miscdevice中定義。
5.一般字符設備使用注冊函數 int cdev_add struct (cdev *p,devt_t dev, unsigned)(第一個參數為之前初始化的字符設備,第二個參數為設備號,第三個參數為要添加設備的個數) 而雜項字符設備使用int misc_register(struct miscdevice *misc)來注冊
 
驅動調用的實質:
就是通過  設備文件找到與之 對應設備號的設備,再通過 設備初始化時 綁定的操作函數硬件進行控制
 
 內核態
#include <linux/miscdevice.h>
 
static unsigned long led_table [] =
{
S3C2410_GPB(5),
S3C2410_GPB(6),
S3C2410_GPB(7),
S3C2410_GPB(8),
};
 
static unsigned int led_cfg_table [] =
{
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
S3C2410_GPIO_OUTPUT,
};
static long phy_ioctl (struct file *pstFilp, unsigned int Cmd, unsigned long ulArg)
{
   ulret
= copy_from_user(&data, (phy_data_s *)ulArg, sizeof(phy_data_s)); switch(Cmd) { case PHY_READ: ulret = ReadPagedPhyReg(data.slot, data.port, data.page, data.addr, &(data.data)); if(ulret != ERROR_SUCCESS) { DEBUG_PRINT(KERN_EMERG "Reading phy reg failed.\n"); return ulret; } break; } ulret = copy_to_user((phy_data_s *)ulArg, &data, sizeof(phy_data_s));    return 0; }

 

 
 
static struct file_operations dev_fops = {
  .owner = THIS_MODULE,
  .unlocked_ioctl = phy_ioctl ,
};
 
static struct miscdevice misc = {
  .minor = MISC_DYNAMIC_MINOR,
  .name = "misc_phy",,
  .fops = &dev_fops,
};
 
static int __init dev_init(void)
{
int ret;
 
int i;
for (i = 0; i < 4; i++)
{
s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
s3c2410_gpio_setpin(led_table[i], 0);
}
 
ret = misc_register(&misc);
 
printk (DEVICE_NAME" initialized\n");
 
return ret;
}
 
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
 
module_init(dev_init);
module_exit(dev_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("www.e-online.cc");
MODULE_DESCRIPTION("LEDS control for GT2440 Board");
 用戶態
int main(int argc, char *argv[])
{
int op;
int ret = 0;
char *s_op = "rd";
int tmp = 0;
int i;

if(argc == 4 )
{
  if(!strcmp(argv[1], "link"))
  {
    op = PHY_link_status;
  }

  ret = sscanf(argv[2], "%d", &tmp);

  if(1 != ret)
  {
    printf("%s:%d argv[2] error\n",__FUNCTION__,__LINE__);
    return -1;
  }
  stPhyInfo.slot = (unsigned char)tmp;

  ret = sscanf(argv[3], "%d", &tmp);
  if(1 != ret)
  {
    printf("%s:%d argv[3] error\n",__FUNCTION__,__LINE__);
    return -1;
  }
  stPhyInfo.port = (unsigned char)tmp;

  fd = open("/dev/misc_phy",O_RDWR);
  if(fd < 0)
  {
    printf("%s:%d open fail\n",__FUNCTION__,__LINE__);
    return -1;
  }

  ret = ioctl(fd, op, (unsigned long)&stPhyInfo);
  if(ret != ERROR_SUCCESS)
  {
    printf("%s:%d . Ioctl fail.\n",__FUNCTION__,__LINE__);
    return ret;
  }
  close(fd);

  return 0;

}

 

 
引用http://blog.sina.com.cn/s/blog_966f8e8501010xhw.html。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM