SkyEye建模框架介绍
SkyEye模型与硬件开发板,图1-1-1是一块普通的硬件开发板,上面有一些比较常见的设备,包括复杂的CPU、USB口、网口、SD卡控制器等,以及简单的蜂鸣器,键盘等设备。我们试想这样一个问题,真实硬件显而易见,包括所有外设的内存地址、寄存器等信息都可以通过硬件手册得知。那么如何用软件的形式(理论上也就是数据)把它直观的表达成我们日常可以理解的东西呢?
SkyEye通过json文件来对真实硬件开发板进行描述,可以理解为一个json文件对应于一块真实的硬件开发板。大体结构我们参照图1-1-2来进行讲解:
图1-1-2 SkyEye中的json框图
xx名称:开发人员根据实际需要自定义,可为任意值;
每一个设备由base表示其属于什么类型,有四种取值:mach表示该对象为一块板子 cpu表示该对象对CPU核,device表示该对象为一个设备 linker表示该对象为连接器,也就是说SkyEye表示的硬件开发板上所有的设备包括外设,CPU,整块开发板,连接线等均由上述四个类型之一来表示。
class的值表示该设备有哪一类来实例化。上一篇文章中讲到所有独立外设都是一个dll,SkyEye加载外设时通过动态调用dll的方式加载到SkyEye。可理解为一个class对应于一个动态dll。这里的e300_core,ram,leon2_uart,image等都是通过SkyEye建模生成的具有一定规范名称的dll,因此class对象后面的值必须是已经通过建模实现的模型。
剩余image里面的size对象以及串口中的skyeye_uart_intf对象,前者目前暂时理解为image这一设备的一个属性,具体用法我们后面介绍;skyeye_uart_inft先简单理解为一根连线,串口需要通过这根连线连接到终端”uart_term_0”上。
关于这一些知识点我们之后再补充。
总的来说就是通过json文件把整块硬件开发板以数据格式的形式表示出来,其中地址总线中有一个对象为memory_space,该对象后面的值表示地址总线上连接有多少设备,这些设备对应硬件开发板中的外设,以及设备的地址映射关系。其中图1-1-2中uart_0后跟的0x30000000表示串口在内存中的地址,0x20表示其所占的长度。实际配置时根据自身需要来对这些值进行设置。该图简单连接了一块RAM以及用于显示输出的虚拟串口。
接着需要对memory_space中连接的这些设备进行一个补充说明:
比如RAM占多少地址空间长度;如果是需要发送中断的设备,比如网卡、定时器等,还需要设置其中断号是多少。这些便是上面提到的属性。
也就是说不同的设备有它自带的不同属性,需要在建模时进行设定。
- 既然需要发送中断,网卡和中断之间如何建立联系?SkyEye提供接口的概念来解决这一问题,我们还是用一张图来对两个或者多个不同设备之间的数据通信进行说明:
例如图1-1-3中,某时刻网卡需要发送中断,首先通过之前提到的接口,将中断信息发送给中断控制器IPIC,中断控制器接收到数据后,再将中断处理的请求发送给CPU,最后CPU响应并处理设备发起的中断。
接口的概念这里先简单理解即可,总结起来就是由于每个模块在实现时相互独立,通过接口可以实现独立模块之间的相互连接并进行数据传输。具体怎么实现在之后的实际编写建模过程再进行说明。
SkyEye模型与设备寄存器
开发板由CPU、外设、各种总线等一堆元器件组成。但实际我们使用时仅仅关心外设如何使用;而外设其底层也就是通过操作不同的寄存器来完成不同的功能。因此SkyEye建模说到底最关心的还是底层寄存器的如何运转。
下图是MPC8378官方手册中关于GPIO的所有寄存器:
如某一时刻需要从GPIO的某一管脚读取数据,首先需要在驱动中设置GPIO方向寄存器为输出,然后再经过中断等其他操作从该管脚读取数据。设置GPIO方向为输出,相当于往该寄存器中某一个管脚位写“1”。写入1的这个过程可以被SkyEye的模型所获取,模型再根据写入的值实现相应的逻辑。之后驱动再发起读操作读取数据,该过程与写操作类似。整个过程可以参考图1-2-2:
SkyEye建模工具介绍
SkyEye使用建模工具来创建前面提到的各种外设模型。
工作空间可以理解为建模所需的环境,例如在visual studio下编程可能会有一些我们不需要关心的文件,但实际工程编译时需要用到这些文件。工作空间的作用类似这些文件,使得开发人员不需要考虑环境的问题,只需要关心具体的模型实现。
创建工作空间
SkyEye提供两种方法创建工作空间,一种是在GUI界面中选择;另外SkyEye还提供命令行进行创建,指令为workspace-create + [工作空间名称]。图2-1-1和图2-1-2分别是创建工作空间的GUI表示和命令行表示。
注意:创建工作空间之后需要重启命令行工具,使新创建的工作空间生效。
下面对工作空间中包含的一些文件和文件夹做一些说明:
更新工作空间
更新工作空间的指令为workspace-update + [目录],还可以通过图2-1-1中的切换工作目录。
我们用一个实际例子说明更新工作空间的作用,假设现在有两个工作空间,一个是MPC8378,另一个是TIC6713。且当前工作空间为MPC8378,如果在当前工作空间下运行包含TIC6713外设的二进制程序,SkyEye会提示无法找到和TIC6713外设相关的class。class我们上面提到过,每一个外设都是需要一个class来实例化。这个时候就需要通过更新工作空间的操作将工作空间替换到TIC6713所在的工作空间目录。其作用可参考图2-2-1:
创建设备
创建设备的命令为workspace-create-devoce + [设备名]。
创建完成后会在工作空间的module文件夹下生成三个文件,分别是:
设备名.c 设备名.h 设备名_moudle.c
.c文件中为所有需要实现的逻辑代码。
.h中为包括寄存器的定义在内的所有变量、宏定义、结构体等内容。
_module.c为SkyEye加载该模块的入口函数,不需要开发人员进行修改。
开发人员只需要考虑如何在.c文件中实现模型的逻辑代码即可,在实现完成后在工作空间根目录下执行make,代码会自动编译并生成动态dll文件。