树莓派uboot的串口初始化(uboot驱动结构 2通用解析)

先上一张看不清的图片 具体的下载资源里面的看 用dia看




蓝色的部分是我们定义的部分

更加详细的部分看 

http://blog.csdn.net/groundhappy/article/details/53256086

这里说通用的部分



uboot在初始化的时候会调用initf_dm->dm_init_and_scan->dm_scan_platdata(lists_bind_drivers)扫描所有的设备。

lists_bind_drivers对于所有的driver_info结构体产生一个设备。

我们定义了

U_BOOT_DEVICE(bcm2835_serials) = {  
    .name = "serial_pl01x",  
    .platdata = &serial_platdata,  
}; 
U_BOOT_DEVICE宏就是定义driver_info结构的

我们定义了一个串口设备。这个设备是bcm2835_serials。设备所需要的驱动的名字是"serial_pl01x",而他私有的数据存放在serial_platdata里面。比如在开发板A上地址寄存器地址映射到了0X100000。在B开发板上是0X20000。这样的数据就可以放在serial_platdata里面。

首先要去寻找名字是serial_pl01x的驱动。通过lists_driver_lookup_name("serial_pl01x")我们找到了struct driver对象。

这个driver对象也定义了

U_BOOT_DRIVER(serial_pl01x) = {  
    .name   = "serial_pl01x",  
    .id = UCLASS_SERIAL,  
    .of_match = of_match_ptr(pl01x_serial_id),  
    .ofdata_to_platdata = of_match_ptr(pl01x_serial_ofdata_to_platdata),  
    .platdata_auto_alloc_size = sizeof(struct pl01x_serial_platdata),  
    .probe = pl01x_serial_probe,  
    .ops    = &pl01x_serial_ops,  
    .flags = DM_FLAG_PRE_RELOC,  
    .priv_auto_alloc_size = sizeof(struct pl01x_priv),  
}; 

根据 U_BOOT_DEVICE(bcm2835_serials)里面的.name 首先我们找到了"serial_pl01x"这个驱动结构,然后根据driver里面的.id立马知道了这个设备是UCLASS_SERIAL设备。并且我们知道对于这个设备的操作是.ops=&pl01x_serial_ops。这个结构最后说。


接下来就是在gd->uclass_root里面找到管理UCLASS_SERIAL的结构。分配一个udevice设备放进去。

uclass_get(driv->id)也就是根据UCLASS_SERIAL,获取对应的uclass指针。首先在gd->uclass_root里面寻找对应的UCLASS节点

如果没有找到。调用uclass_add根据class_id 寻找对应的驱动。这里说明一下一个设备有不同层次的驱动。

第一层是uclass的类驱动。所有的设备都需要使用这一部分,也就是不管是串口还是I2C还是SPI还是其他设备,都有一部分通用的接口函数需要写。比如init destroy等等。

第二层是驱动同一类型但是不同型号的设备需,比如A B两种类型的串口可能寄存器位置等不一样,但是他们都属于串口。


找到了一个定义了UCLASS_DRIVER(serial)他的.id是UCLASS_SERIAL。因此根据这个驱动的结构体

calloc一个 uclass对象,并挂载到uclass_root里面。 这个uclass对象就保存ID为UCLASS_SERIAL的各类信息。

属于串口的类驱动,可以看到串口类驱动通用部分只提供了移除和插入的函数。

UCLASS_DRIVER(serial) = {
.id = UCLASS_SERIAL,
.name = "serial",
.flags  = DM_UC_FLAG_SEQ_ALIAS,
.post_probe  = serial_post_probe,
.pre_remove  = serial_pre_remove,
.per_device_auto_alloc_size = sizeof(struct serial_dev_priv),
};


得到uclass结构指针之后就calloc了一个udevice结构。

接下来就是一系列的赋值并将这个udevice挂入uclass的链表里面。


最后就是driver当中的.ops成员。pl01x_serial_ops

struct dm_serial_ops {
	int (*setbrg)(struct udevice *dev, int baudrate);
	int (*getc)(struct udevice *dev);
	int (*putc)(struct udevice *dev, const char ch);
	int (*pending)(struct udevice *dev, bool input);
	int (*clear)(struct udevice *dev);
#if CONFIG_POST & CONFIG_SYS_POST_UART
	int (*loop)(struct udevice *dev, int on);
#endif
};

定义了这样的选项。

static const struct dm_serial_ops pl01x_serial_ops = {  
    .putc = pl01x_serial_putc,  
    .pending = pl01x_serial_pending,  
    .getc = pl01x_serial_getc,  
    .setbrg = pl01x_serial_setbrg,  
}; 

。后续可以通过udevice->driver->ops来执行操作。其他的类型的串口也需要实现dm_serial_ops里面的函数。

点击打开链接  图片下载






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值