1、LiteOS调测功能
异常接管:作为一种调测手段,可以在串口上输出异常发生时的日志,包括异常类型、寄存器信息、栈回溯信息(可以得到函数调用过程)、异常时正在执行的任务信息(如任务名、任务号、栈大小)、所有未退出的任务信息(包括任务名、任务号、栈大小、状态等)、内存信息等。用户可以根据寄存器内容,追溯函数间的调用关系,再辅以任务信息和内存信息,定位分析问题。
异常接管只能在串口上即时输出日志,当日志过多时用户可能无法看到完整的日志内容。为解决这个问题,LiteOS提供了“临终遗言”功能,可以将日志保存在NOR flash(非易失闪存)中,同时用户也可以注册自己的日志读写函数。系统复位重启后,在串口命令行中输入相应的命令,已记录的日志就会被打印出来。
考虑到有些异常情况下,可能不会触发上面的系统异常处理流程,比如系统运行卡顿,LiteOS提供了查看CPU占用率的功能。LiteOS的CPU占用率,采用任务记录的方式。在任务切换时,记录任务启动时间和切出时间;任务切出或者退出时间,系统还会累加整个任务的占用时间。CPU占用率分为系统CPU占用率和任务CPU占用率两种。
-
系统CPU占用率 = 系统中除空闲任务外其他任务运行总时间 / 系统运行总时间。
系统CPU占用率用于表示系统一段时间内的闲忙程度,也表示CPU的负载情况。
-
任务CPU占用率 = 任务运行总时间 / 系统运行总时间。
任务CPU占用率用于表示单个任务在一段时间内的闲忙程度。
LiteOS的调测百宝箱,针对踩内存、内存泄漏、野指针释放等问题,提供了一系列的内存调测能力;针对互斥锁死锁问题,提供了死锁检测能力。除此之外,还有对任务、中断、队列、信号量、软件定时器等各种事件的跟踪调测功能。
2、LiteOS在STM32上的运行
LiteOS操作系统的启动是从main函数开始的。而ARM Cortex-M芯片从上电到执行main函数,中间经过了Reset_Handler等函数。
los_startup_gcc.s是启动引导文件,从Reset_Handler开始到执行main函数,主要工作就是准备C代码的运行环境,具体包括:
-
设置栈指针SP
-
初始化中断向量
-
初始化data段
-
初始化bss段
-
初始化系统时钟
-
跳转到 C 代码函数main
链接脚本根据应用需要,设置堆栈大小和栈地址,并控制每个段的存放位置。对于中断向量和data段,既要放到flash中,也需要放到RAM中,并通过链接脚本的AT关键字把flash的地址设定为load地址。
los_startup_gcc.s启动引导文件中除了定义Reset_Handler函数,还定义了其他中断异常处理函数Default_Handler,并为Default_Handler的每个异常处理程序提供弱别名。所谓弱别名,即具有相同名称的任何函数都将覆盖此处的函数。这样做可以防止用户使能了中断却没有设置中断处理程序时造成的崩溃。Default_Handler函数只是进入一个无限循环以保留系统状态供调试器检查。
Lite OS的main函数,main函数主要负责LiteOS的初始化工作。
完成内核的初始化后,调用OsStart()开始任务调度,自此LiteOS开始正常工作。
整个启动流程从板子复位上电开始,调用汇编代码Reset_Handler进入启动引导文件,完成C代码运行环境的准备工作后跳转到main函数中。在main中完成硬件初始化和LiteOS内核的初始化,并通过汇编跳转到执行第一个最高优先级的任务命令的地址上,从而开始LiteOS的运行。
3、LiteOS在STM32上的启动
从板子复位上电开始,调用汇编代码Reset_Handler进入启动引导文件,完成C代码运行环境的准备工作、最后跳转到main函数。在main函数中完成硬件初始化和LiteOS内核的初始化,并通过汇编跳转到执行第一个最高优先级的任务命令的地址上,从而开始LiteOS的运行。
4、Qemu模拟器
5、LiteOS Studio图形化调测
6、LiteOS Studio的镜像分析工具
7、LiteOS调测器
ARM的汇编指令执行分三步:取值(fetch)、译指(decode)、执行(excute),按照流水线的方式执行,即当运行指令节拍m时,pc会指向n+2汇编指令地址进行取指令操作,同时会将n+1处汇编指令翻译成对应机器码,并执行指令n。
ARM为了维护栈中的数据设计了两个寄存器,分别为fp寄存器(framepointer,帧指针寄存器)和sp寄存器(stack pointer,堆栈寄存器)