全志A64 U-BOOT起始串口初始化流程详解

本文详细介绍了全志A64在U-BOOT启动过程中,如何通过common/board_f.c中的函数调用来初始化串口,包括波特率设置、硬件初始化等步骤,涉及到了serial_ns16550.c和serial.c等多个源文件中的关键函数及宏定义的使用。文章还探讨了为何选择ns16550通用驱动及其在不同板子上的应用。
摘要由CSDN通过智能技术生成

串口执行流程,首先是/common/board_f.c中
先调用

void board_init_f(ulong boot_flags)

该函数是汇编代码进入C代码前在_main中调用的地址重定向前的设备初始化函数,其中调用

initcall_run_list(init_sequence_f)

来执行init_sequence_f数组中的相关初始化函数,该数组的定义也在本文件中,其定义如下

static init_fnc_t init_sequence_f[]

该序列中关于串口的函数主要有

init_baud_rate,		/* initialze baudrate settings */
serial_init,		/* serial communications setup */

第一个是初始化初始化波特率,注意这里的初始化波特率并不是设置串口波特率,而是先查找环境变量区看是否存在波特率,若不存在根据宏定义来将波特率保存在全局数据(global data)其函数实现如下:

static int init_baud_rate(void)
{
   
	gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
	return 0;
}

第二个函数为串口初始化,主要关于硬件初始化,其实现函数如下:

int serial_init(void)
{
   
	return get_current()->start();
}

该函数位于driver/serial/serial.c中,其中get_current()函数实现如下:

static struct serial_device *get_current(void)
{
   
	struct serial_device *dev;

	if (!(gd->flags & GD_FLG_RELOC))
		dev = default_serial_console();
	else if (!serial_current)
		dev = default_serial_console();
	else
		dev = serial_current;

	/* We must have a console device */
	if (!dev) {
   
#ifdef CONFIG_SPL_BUILD
		puts("Cannot find console\n");
		hang();
#else
		panic("Cannot find console\n");
#endif
	}

	return dev;
}

该函数位于本文件中,其大致实现过程为,若第一次初始化串口(即在重定向前初始化串口),则将设备执行默认串口default_serial_console,若在重定向后再次初始化串口,则查找当前串口设备。其中default_serial_console实现函数如下:

__weak struct serial_device *default_serial_console(void)
{
   
#if CONFIG_CONS_INDEX == 1
	return &eserial1_device;
#elif CONFIG_CONS_INDEX == 2
	return &eserial2_device;
#elif CONFIG_CONS_INDEX == 3
	return &eserial3_device;
#elif CONFIG_CONS_INDEX == 4
	return &eserial4_device;
#elif CONFIG_CONS_INDEX == 5
	return &eserial5_device;
#elif CONFIG_CONS_INDEX == 6
	return &eserial6_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
}

其中在全志的config配置文件即sun50iw101.h中定义了CONFIG_CONS_INDEX为1,故我们使用eserial1_device这个设备,继续查找eserial1_device的函数如下:

#if defined(CONFIG_SYS_NS16550_COM1)
DECLARE_ESERIAL_FUNCTIONS(1);
struct serial_device eserial1_device =
	INIT_ESERIAL_STRUCTURE(1, "eserial0");
#endif
#if defined(CONFIG_SYS_NS16550_COM2)
DECLARE_ESERIAL_FUNCTIONS(2);
struct serial_device eserial2_device 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值