u-boot 阶段
lowlevel_init 调用了以下函数 实现了 putc ,但不支持 printf
spl_config_uart_baudrate
uart_asm_init
asm_putc
board_init_f 调用了以下函数,完成后,支持printf
initf_dm
init_baud_rate // 查找 环境变量 baudrate
gd->baudrate = env_get_ulong("baudrate", 10, 115200);
serial_init // 重新设置了一下波特率
serial_find_console_or_panic
gd->flags |= GD_FLG_SERIAL_READY;
serial_setbrg
console_init_f // 该函数执行完后printf 可用了
gd->have_console = 1;
console_update_silent
print_pre_console_buffer
board_init_r 调用了以下函数,提供了多个输出的可能
initr_dm
stdio_init_tables
INIT_LIST_HEAD(&devs.list);
serial_initialize
serial_init
serial_find_console_or_panic
gd->flags |= GD_FLG_SERIAL_READY;
serial_setbrg
// 为 console 机制 提供 一个 console
stdio_add_devices
// lcd
drv_lcd_init
// uart
drv_system_init
struct stdio_dev dev;
memset (&dev, 0, sizeof (dev));
strcpy (dev.name, "serial");
dev.flags = 0x00000002 | 0x00000001;
dev.putc = stdio_serial_putc;
dev.puts = stdio_serial_puts;
dev.getc = stdio_serial_getc;
dev.tstc = stdio_serial_tstc;
stdio_register (&dev); // 直接插入链表
stdio_register_dev
struct stdio_dev *_dev;
_dev = stdio_clone(dev);
list_add_tail(&_dev->list, &devs.list);
serial_stdio_init
// null
// 组织 所有的 console,并 初始化 console 系统
// 如果 设置了 CONFIG_CONSOLE_MUX is not set , 则填充 stdio_devices[1] , 打印使用 stdio_devices[1]->puts
// 如果 设置了 CONFIG_CONSOLE_MUX=y , 则填充 console 链表, 打印的话则 依次调用链表上的 stdio_devices 的 puts 成员
// 下面是 设置了 CONFIG_CONSOLE_MUX is not set 的情况
console_init_r
struct stdio_dev *inputdev = 0;
struct stdio_dev *outputdev = 0;
struct list_head *list = stdio_get_list(); // &devs.list;
struct list_head *pos;
struct stdio_dev *dev;
int flushpoint;
if (console_update_silent())
flushpoint = 0;
else
flushpoint = 1;
for (pos = (list)->next; prefetch(pos->next), pos != (list); pos = pos->next) {
dev = list_entry(pos, struct stdio_dev, list);
if ((dev->flags & 0x00000001) && (inputdev == 0)
inputdev = dev;
if ((dev->flags & 0x00000002) && (outputdev ==0)
outputdev = dev;
}
console_setfile(1, outputdev);
stdio_devices[1] = outputdev;
// 填充 gd->jt->putc = putc;
// 这个填充为什么不是用 outputdev 的成员填充,而是用 putc 直接填充
console_setfile(2, outputdev);
stdio_devices[1] = outputdev;
console_setfile(0, inputdev);
stdio_devices[0] = inputdev;
// 填充 gd->jt->getc
stdio_print_current_devices
// 打印 In Out Err
// 设置环境变量
for (i = 0; i < 3; i++) {
env_set(stdio_names[i], stdio_devices[i]->name);
}
gd->flags |= GD_FLG_DEVINIT;
// 打印之前在缓冲区的字符
print_pre_console_buffer(flushpoint);
console_init_f 完成后的printf流程
printf // lib/vsprintf.c
puts // common/console.c
pre_console_puts
serial_puts
console_init_r 完成后的printf流程(且CONFIG_CONSOLE_MUX is not set)
printf // lib/vsprintf.c
puts // common/console.c
fputs // common/console.c
console_puts // common/console.c
stdio_devices[file]->puts(stdio_devices[file], s);/ 即 stdio_serial_puts
serial_puts(s);
console_init_r 完成后的printf流程(且CONFIG_CONSOLE_MUX=y)
printf // lib/vsprintf.c
puts // common/console.c
fputs // common/console.c
console_puts // common/console.c
for_each_console_devices_which_has_member_puts dev->puts(dev, s);
stdio_serial_puts
stdio_lcd_puts
...
serial_puts
serial_puts
_serial_puts(gd->cur_serial_dev, str);
_serial_putc(dev, *str++);
struct dm_serial_ops *ops = serial_get_ops(dev);
ops->putc(dev, ch);/即s3c64xx_serial_putc
上一篇:OK6410A 开发板 (三) 18 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 env
下一篇:OK6410A 开发板 (三) 16 u-boot-2021.01 boot 解析 U-boot 镜像运行部分 irq
设计资源 培训 开发板 精华推荐
- 75W连续传导模式(CCM)降压LED驱动器
- #第七届立创电赛#usb功率计
- LTC6990HS6#TRMPBF 正交正弦波振荡器的典型应用。压控频率范围为 5Hz 至 20kHz,具有 1VP-P 恒定输出幅度
- 使用 Analog Devices 的 AD9683BCPZ-250 的参考设计
- LT6654BHLS8-2.5、16 位 ADC 电压基准的典型应用
- 基于SPC572L64E3 MCU的SPC572L-DISP套件
- 使用 MaxLinear, Inc 的 LP2950 的参考设计
- ZXGD3103EV1,评估板演示了同步 MOSFET 的驱动
- LT6656ACDC-2.048、2.048V ADC 电压基准和桥式激励电源的典型应用
- LT3990IMSE-5 1.8V 降压转换器的典型应用
- 看这里!发表个人原创就有机会获得E金币啦~~
- 揭秘正确选择探头的5大要素 (泰克原装探头促销,高贵不贵,199元起)
- 有奖直播:走进实验室之是德科技高端新品示波器UXR-B测评
- 下载《基于巨磁(GMR)的Allegro IC》白皮书,赢50元京东卡
- 直播已结束|浅谈Microchip的FPGA产品与智能嵌入式视觉解决方案
- 有奖问答|ADI应用之旅——电池管理及智慧储能篇
- 家电新风尚,PI开启您的家电新生活!下载产品资料答题赢好礼!
- 答题抽奖:Mentor Tessent Automotive相关测试解决方案(奖品池还剩不少奖品哟)
- NXP COG趣味有奖问答
- MPS 新年福利|注册即有机会赢取京东卡