实现系统调试信息打印接口
当系统出错时或者使用内核日志时会输出一些打印信息,这最终都是调用到bspLib.c中的bspDebugMsg 这个接口来实现的,所以我们在开发BSP时,第一个要做的工作就是实现这个接口。
一般的调试信息都是通过串口来输出的,所以我们需要实现全志R16平台上串口发送的函数。因为U-Boot在启动时使用串口0输出信息,所以我们这里只要实现串口0的发送函数即可,像串口的时钟、波特率设置等等U-Boot已经帮我们做好了,所以我们这里可以不用关心。另外需要说明的是,在本系列教程中并不会去详细地讲解外设驱动寄存器具体如何设置,我们这里关心的是BSP的框架和开发的整体流程,至于寄存器怎么设置请参考厂商提供的U-Boot或者Linux下的对应代码。
由于我们现在要实现串口驱动,所以可以在driver 目录下新建一个uart目录用来存放串口驱动文件:
其中uart.h会被bspLib.c文件使用,我们需要在uart.c中实现串口的轮询发送接口:
#define __SYLIXOS_KERNEL
#include <SylixOS.h>
#include <linux/compat.h>/*********************************************************************************************************基地址定义
*********************************************************************************************************/
#define UART0_BASE (0x01c28000)
/*********************************************************************************************************寄存器偏移
*********************************************************************************************************/
#define RBR 0x0
#define THR 0x0
#define USR 0x7CVOID uartPutChar (CHAR cChar)
{// 若 FIFO 不满就填入数据,否则等待while (!(readl(UART0_BASE + USR) & BIT(1)));writel(cChar, UART0_BASE + THR);
}VOID uartPutMsg (CPCHAR cpcMsg)
{CHAR cChar;if (!cpcMsg) {return;}while ((cChar = *cpcMsg) != '\0') {uartPutChar(cChar);cpcMsg++;}
}
最后在bspLib.c中的bspDebugMsg 接口中调用我们实现的串口轮询发送函数即可:
/*********************************************************************************************************
** 函数名称: bspDebugMsg
** 功能描述: 打印系统调试信息
** 输 入 : pcMsg 信息
** 输 出 : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
VOID bspDebugMsg (CPCHAR pcMsg)
{/** TODO: 通过 UART 打印系统调试信息*/uartPutMsg(pcMsg);
}
到此为止我们可以先编译出SylixOS内核镜像来启动了,如果串口上有打印就说明我们最起码能通过打印来调试了。编译BSP工程(当然需要提前先编译好base工程),在Release目录下找到bsp_allwinner_r16.bin 这个文件,这个就是SylixOS内核镜像,将其拷贝到SD卡上,将SD卡插入开发板上,上电通过以下命令启动SylixOS内核:
=> fatload mmc 0:1 40000000 bsp_allwinner_r16.bin
reading bsp_allwinner_r16.bin
3231464 bytes read in 175 ms (17.6 MiB/s)
=> go 40000000
我们就可以在串口上看到SylixOS启动过程中的日志打印:
## Starting application at 0x40000000 ...
longwing(TM) kernel initialize...
kernel low level initialize...
kernel heap build...
semaphore "heap_lock" has been create.
kernel heap has been create 0x40f08c18 (47149928 Bytes).
system heap build...
system heap has been create 0x0 (0 Bytes).
kernel interrupt vector initialize...
kernel high level initialize...
semaphore "sigfdsel_lock" has been create.
thread "t_idle0" has been initialized.
thread "t_idle0" has been start.
thread "t_itimer" has been initialized.
thread "t_itimer" has been start.
semaphore "job_sync" has been create.
thread "t_isrdefer" has been initialized.
thread "t_isrdefer" has been start.
semaphore "job_sync" has been create.
thread "t_except" has been create.
msgqueue "log_msg" has been create.
partition "printk_pool" has been create.
thread "t_log" has been initialized.
semaphore "ios_mutex" has been create.
semaphore "evtfdsel_lock" has been create.
semaphore "bmsgsel_lock" has been create.
semaphore "bmsgd_lock" has been create.
semaphore "semfdsel_lock" has been create.
semaphore "semfd_lock" has been create.
semaphore "tmrfdsel_lock" has been create.
semaphore "hstmrfdsel_lock" has been create.
semaphore "gpiofdsel_lock" has been create.
semaphore "blkio_lock" has been create.
semaphore "autom_lock" has been create.
semaphore "mount_lock" has been create.
semaphore "bus_listlock" has been create.
semaphore "blk_lock" has been create.
semaphore "power_lock" has been create.
semaphore "sel_wakeup" has been create.
thread "t_power" has been create.
semaphore "job_sync" has been create.
semaphore "hotplug_lock" has been create.
semaphore "sel_wakeup" has been create.
thread "t_hotplug" has been create.
semaphore "hpsel_lock" has been create.
semaphore "hotplug_lock" has been create.
system initialized.
semaphore "cpprt_lock" has been create.
semaphore "cond_signal" has been create.
c++ run time lib initialized.
kernel primary cpu usrStartup...
ARM(R) 920 none FPU pri-core initialization.
FPU initilaized.
__vmmVirtualCreate() bug: virtual switich page invalidate.
当然这时候系统是不可能完全启起来的,因为我们现在只是实现了调试信息输出而已。
另外在开发的过程中,可能需要带参数打印一些信息,这时候就不能使用bspDebugMsg 了,这个接口只能打印纯字符串,我们可以使用_PrintFormat 来打印变量值等等信息,用法类似于printf。
IMX6ULL相关的总结:
1,我们这里的打印参照的是正点原子的裸机的串口打印的程序
2,load拷贝数据的时候是放在80000000的地址处,按照的是芯片手册的逻辑。