U-Boot的设备管理

U-Boot的设备管理

目录

一、初始设备链表、初始化设备和注册设备
1.1 devices_init函数
1.2 devices结构的定义
1.3 drv_system_init 函数
二、设备注册
2.1 device_register (device_t * dev)
2.2 device_deregister(char *devname)
三、设备搜索


U-Boot通过devices_init函数创建设备链表,然后在devices_init函数中初始化设备并将设备添加到设备链表中。U-Boot使用devices_t结构体来管理设备,设备链表也就是devices_t结构体的链表。通过i2c_init、drv_lcd_init、drv_video_init、drv_keyboard_init、drv_logbuff_init、drv_system_init、serial_devices_init、drv_usbtty_init和drv_nc_init函数初始化设备(这些函数是否执行是通过宏来决定的),并通过device_register函数注册设备。

一、初始设备链表、初始化设备和注册设备

U-Boot在第二阶段中通过devices_init函数创建设备链表,初始化设备并将其注册到设备链表中。该函数在common/devices.c文件中,其对应的头文件是nclude/devices.h。

1.1 devices_init函数

[plain]  view plain copy
  1. int devices_init (void)  
  2. {  
  3. #ifndef CONFIG_ARM     /* already relocated for current ARM implementation */  
  4.     ulong relocation_offset = gd->reloc_off;  
  5.     int i;  
  6.   
  7.     /* relocate device name pointers */  
  8.     for (i = 0; i < (sizeof (stdio_names) / sizeof (char *)); ++i) {  
  9.         stdio_names[i] = (char *) (((ulong) stdio_names[i]) +  
  10.                         relocation_offset);  
  11.     }  
  12. #endif  
  13.   
  14.     /* Initialize the list */  
  15.     devlist = ListCreate (sizeof (device_t));//创建设备列表  
  16.   
  17.     if (devlist == NULL) {  
  18.         eputs ("Cannot initialize the list of devices!\n");  
  19.         return -1;  
  20.     }  
  21. #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)  
  22.     i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);//初始化i2c接口,i2c没有注册到devlist中去  
  23. #endif  
  24. #ifdef CONFIG_LCD  
  25.     drv_lcd_init ();  
  26. #endif  
  27. #if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)  
  28.     drv_video_init ();  
  29. #endif  
  30. #ifdef CONFIG_KEYBOARD  
  31.     drv_keyboard_init ();  
  32. #endif  
  33. #ifdef CONFIG_LOGBUFFER  
  34.     drv_logbuff_init ();  
  35. #endif  
  36.     drv_system_init ();//这里其实是定义了一个串口设备,并且注册到devlist中  
  37. #ifdef CONFIG_SERIAL_MULTI  
  38.     serial_devices_init ();  
  39. #endif  
  40. #ifdef CONFIG_USB_TTY  
  41.     drv_usbtty_init ();  
  42. #endif  
  43. #ifdef CONFIG_NETCONSOLE  
  44.     drv_nc_init ();  
  45. #endif  
  46.   
  47.     return (0);  
  48. }  

经过devices_init(),创建了devlist,但是只有一个串口设备注册在内。

1.2 devices结构的定义

[plain]  view plain copy
  1. /* Device information */  
  2. typedef struct {  
  3.     int flags;          /* Device flags: input/output/system    */  
  4.     int ext;            /* Supported extensions         */  
  5.     char    name[16];       /* Device name  设备名称            */  
  6.   
  7. /* GENERAL functions 启动和停止函数 */  
  8.   
  9.     int (*start) (void);        /* To start the device          */  
  10.     int (*stop) (void);     /* To stop the device           */  
  11.   
  12. /* OUTPUT functions 输出函数 */  
  13.   
  14.     void (*putc) (const char c);    /* To put a char            */  
  15.     void (*puts) (const char *s);   /* To put a string (accelerator)    */  
  16.   
  17. /* INPUT functions  输入函数*/  
  18.   
  19.     int (*tstc) (void);     /* To test if a char is ready...    */  
  20.     int (*getc) (void);     /* To get that char         */  
  21.   
  22. /* Other functions */  
  23.   
  24.     void *priv;         /* Private extensions           */  
  25. } device_t;  

1.3 drv_system_init 函数

drv_system_init 函数初始化串口设备,源码如下:

[plain]  view plain copy
  1. static void drv_system_init (void)  
  2. {  
  3.     device_t dev;//定义一个结构体  
  4.   
  5.     memset (&dev, 0, sizeof (dev));//为刚刚定义的结构体分配内存  
  6.   
  7.     strcpy (dev.name, "serial");//名称  
  8.     dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;   
  9.   
  10. #ifdef CONFIG_SERIAL_SOFTWARE_FIFO  
  11.     dev.putc = serial_buffered_putc;  
  12.     dev.puts = serial_buffered_puts;  
  13.     dev.getc = serial_buffered_getc;  
  14.     dev.tstc = serial_buffered_tstc;  
  15. #else  
  16.     dev.putc = serial_putc;  
  17.     dev.puts = serial_puts;  
  18.     dev.getc = serial_getc;  
  19.     dev.tstc = serial_tstc;  
  20. #endif  
  21.   
  22.     device_register (&dev);//注册函数  
  23.   
  24. #ifdef CFG_DEVICE_NULLDEV  
  25.     memset (&dev, 0, sizeof (dev));  
  26.   
  27.     strcpy (dev.name, "nulldev");  
  28.     dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;  
  29.     dev.putc = nulldev_putc;  
  30.     dev.puts = nulldev_puts;  
  31.     dev.getc = nulldev_input;  
  32.     dev.tstc = nulldev_input;  
  33.   
  34.     device_register (&dev);  
  35. #endif  
  36. }  

二、设备注册

有连个设备注册函数,一个的参数时devces结构体,另一个的参数是设备的名称

2.1 device_register (device_t * dev)

设备注册,将结构体添加到devlist的后面,device_register函数的源码如下:

[plain]  view plain copy
  1. int device_register (device_t * dev)  
  2. {  
  3.     ListInsertItem (devlist, dev, LIST_END);  
  4.     return 0;  
  5. }  

[plain]  view plain copy
  1. /*******************************/  
  2.   
  3. /*  
  4.  * returns 1 if the item is inserted, returns 0 if out of memory or  
  5.  * bad arguments were passed.  
  6.  */  
  7. int ListInsertItem (list_t list, void *ptrToItem, int itemPosition)  
  8. {  
  9.     return ListInsertItems (list, ptrToItem, itemPosition, 1);  
  10. }  
  11.   
  12. /*******************************/  
  13.   
  14. int ListInsertItems (list_t list, void *ptrToItems, int firstItemPosition,  
  15.              int numItemsToInsert)  
  16. {  
  17.     int numItems = (*list)->numItems;  
  18.   
  19.     if (firstItemPosition == numItems + 1)  
  20.         firstItemPosition = LIST_END;  
  21.     else if (firstItemPosition > numItems)  
  22.         return 0;  
  23.   
  24.     if ((*list)->numItems >= (*list)->listSize) {  
  25.         if (!ExpandListSpace (list, -numItemsToInsert))  
  26.             return 0;  
  27.     }  
  28.   
  29.     if (firstItemPosition == LIST_START) {  
  30.         if (numItems == 0) {  
  31.             /* special case for empty list */  
  32.             firstItemPosition = LIST_END;  
  33.         } else {  
  34.             firstItemPosition = 1;  
  35.         }  
  36.     }  
  37.   
  38.     if (firstItemPosition == LIST_END) {    /* add at the end of the list */  
  39.         if (ptrToItems)  
  40.             memcpy (ITEMPTR (list, numItems), ptrToItems,  
  41.                     (*list)->itemSize * numItemsToInsert);  
  42.         else  
  43.             memset (ITEMPTR (list, numItems), 0,  
  44.                     (*list)->itemSize * numItemsToInsert);  
  45.   
  46.         (*list)->numItems += numItemsToInsert;  
  47.     } else {                    /* move part of list up to make room for new item */  
  48.         memmove (ITEMPTR (list, firstItemPosition - 1 + numItemsToInsert),  
  49.              ITEMPTR (list, firstItemPosition - 1),  
  50.              (numItems + 1 - firstItemPosition) * (*list)->itemSize);  
  51.   
  52.         if (ptrToItems)  
  53.             memmove (ITEMPTR (list, firstItemPosition - 1), ptrToItems,  
  54.                      (*list)->itemSize * numItemsToInsert);  
  55.         else  
  56.             memset (ITEMPTR (list, firstItemPosition - 1), 0,  
  57.                     (*list)->itemSize * numItemsToInsert);  
  58.   
  59.         (*list)->numItems += numItemsToInsert;  
  60.     }  
  61.   
  62.     return 1;  
  63. }  

2.2 device_deregister(char *devname)

[plain]  view plain copy
  1. int device_deregister(char *devname)  
  2. {  
  3.     int i,l,dev_index;  
  4.     device_t *dev = NULL;  
  5.     char temp_names[3][8];  
  6.   
  7.     dev_index=-1;  
  8.     for (i=1; i<=ListNumItems(devlist); i++) {  
  9.         dev = ListGetPtrToItem (devlist, i);  
  10.         if(strcmp(dev->name,devname)==0) {  
  11.             dev_index=i;  
  12.             break;  
  13.         }  
  14.     }  
  15.     if(dev_index<0) /* device not found */  
  16.         return 0;  
  17.     /* get stdio devices (ListRemoveItem changes the dev list) */  
  18.     for (l=0 ; l< MAX_FILES; l++) {  
  19.         if (stdio_devices[l] == dev) {  
  20.             /* Device is assigned -> report error */  
  21.             return -1;  
  22.         }  
  23.         memcpy (&temp_names[l][0],  
  24.             stdio_devices[l]->name,  
  25.             sizeof(stdio_devices[l]->name));  
  26.     }  
  27.     ListRemoveItem(devlist,NULL,dev_index);  
  28.     /* reassign Device list */  
  29.     for (i=1; i<=ListNumItems(devlist); i++) {  
  30.         dev = ListGetPtrToItem (devlist, i);  
  31.         for (l=0 ; l< MAX_FILES; l++) {  
  32.             if(strcmp(dev->name,temp_names[l])==0) {  
  33.                 stdio_devices[l] = dev;  
  34.             }  
  35.         }  
  36.     }  
  37.     return 0;  
  38. }  

三、设备搜索

[plain]  view plain copy
  1. /* search a device */  
  2. device_t *search_device (int flags, char *name)  
  3. {  
  4.     int i, items;  
  5.     device_t *dev = NULL;  
  6.   
  7.     items = ListNumItems (devlist);  
  8.     if (name == NULL)  
  9.         return dev;  
  10.   
  11.     for (i = 1; i <= items; i++) {  
  12.         dev = ListGetPtrToItem (devlist, i);  
  13.         if ((dev->flags & flags) && (strcmp (name, dev->name) == 0)) {  
  14.             break;  
  15.         }  
  16.     }  
  17.     return dev;  
  18. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值