U-Boot的设备管理

 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函数

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

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

1.2 devices结构的定义

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

1.3 drv_system_init 函数

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

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

二、设备注册

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

2.1 device_register (device_t * dev)

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

int device_register (device_t * dev)  
  1. {  
  2.     ListInsertItem (devlist, dev, LIST_END);  
  3.     return 0;  
  4. }  

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

2.2 device_deregister(char *devname)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值