FIMD架构分析

转自:http://www.embedu.org/Column/Column431.htm

FIMD架构分析

作者:邹南,华清远见嵌入式学院讲师。

一、名称含义(FIMC& FIMD)

FIMC :
                Fully Interactive Mobile Camera (完全交互式移动摄像机)
        FIMD: 
                Fully Interactive Mobile Display (完全交互式移动显示设备)

二 、FIMD 体系分析

Lcd 的基本特性如下:

●    The conventional RGB interface 
        ●    The indirect-i80 interface 
        ●    ITU-R BT.601
        ●    ITU-R BT.656

每种接口支持 5 overlay image windows

●    win 0(base): local /(YCbCr,RGB without pallette)
        ●    Win 1(overlay 1): RGB (palette)
        ●    Win2(overlay 2) : RGB (palette)
        ●    Win 3(caption ) 标题层:RGB(1/2/4)with 16 level color LUT (16级1,2,4bits颜色对照表)
        ●    Win4 (cursor) 光标层: RGB(1/2) with 4 level color LUT (RGB 1,2bits 颜色对照表)

在测试过程中,我们只关注RGB接口,所以我们这里是考察RGB类型interface的时序。

LCD 一般需要三个时序信号:VSYNC、HSYNC 和VCLK。VSYNC 是垂直同步信号,在每进行一个帧(即一个屏)的扫描之前,该信号就有效一次,由该信号可以确定LCD 的场频,即每秒屏幕刷新的次数(单位Hz)。HSYNC 是水平同步信号,在每进行一行的扫描之前,该信号就有效一次,由该信号可以确定LCD 的行频,即每秒屏幕从左到右扫描一行的次数(单位Hz)。VCLK 是像素时钟信号,理说,对于一个已知尺寸(即水平显示尺寸HOZVAL 和垂直显示尺寸LINEVAL 已知)的LCD 屏,只要确定了VCLK 值,行频和场频就应该知道了。但这样还不行的,因为在每一帧时钟信号中,还会有一些与屏显示无关的时钟出现,这就给确定行频和场频带来了一定的复杂性。如在HSYNC 信号先后会有水平同步信号前肩(HFPD)和水平同步信号后肩(HBPD)出现,在VSYNC 信号先后会有垂直同步信号前肩(VFPD)和垂直同步信号后肩(VBPD)出现,在这些信号时序内,不会有有效像素信号出现,另外HSYNC 和VSYNC信号有效时,其电平要保持一定的时间,它们分别叫做水平同步信号脉宽HSPW 和垂直同步信号脉宽VSPW,这段时间也不能有像素信号。因此计算行频和场频时,一定要包括这些信号。HBPD、HFPD 和HSPW 的单位是一个VCLK 的时间,而VSPW、VFPD 和VBPD 的单位是扫描一行所用的时间。

说明下:其中的HSPW ,HBPD,HFPD,VSPW,VSPD,VFPD都是可编程的。

再来看下lcd时钟源:

整个FIMD可选用两路时钟源,一路是HCLK1,即D1_BUS,第二路是SCLK_LCD,它可由MPLL分流,也可由EPLL分流。具体需要配置时钟相关的寄存器。这里笔者推荐使用SCLK_LCD这一路,且由MPLL过来的时钟源。(Lcd max clock is 66Mhz),在测试中我们使用的是9Mhz;

如下是FIMC通用接口以及功能。

整个lcd control可以分为 data enter , data process ,data display 三个部分,每个环节都有自己的技术特点,data enter 分为两路,一路是内置dma , 一路是本地fifo。

前者是通过axi master从内存中的某一片area直接引用进来,可以看成是种映射,也可以是把内存关联好后,开启dma。让它自行数据获取。再来说说后者,后者是一种fimd/c框架的特点,它是fimc 到fimc的本地通信手段,它避开了AXI总线。直接通道数据存取,使得性能更强劲。

再来看看,data process部分,data process部分具体罗列如下

1、windows blending (alpha euqation)

<1> Alpha Blending Function

简单解释下这两个线性方程,B' 是一个色值函数,它由A的色值分量与B的色值分量线性叠加而成。此处,A的色值来自win(n+1),B的色值来自win(n), a,b则是线性因子。我们只需要考虑a,b的值,就可以得到我们想要的结果,同理alphaB' 是一个B'色值的伴随灰度值函数,专业点说,就是一组alpha通道。

它的构成与前一个方程是同构的。 p,q也是线性因子,这样4个因子决定了两个窗口的最终叠加色值以及伴随alpha的值。(注意,a,b,p,q是只能可选值,从图中可以看出这一点。)

在FIMD中,只需要配置WINn blending equation control register,并将具体的因子配好后,就可以实现了,注意5个窗口需要同时配置方程。

在来重点考察下alphaB灰度值,它是一个8bits的值,从0-255分别代表了不同的灰度级。从方程中可以看出,如果一个alpha值与一个色值相乘后,就会得到一个该色值的分量,这样两个窗口的叠加就靠不同的灰度来确定。换句话说,如果要使得win1-win4窗体整体透明,那必须要使得win1-win4的灰度级最高,则使得alpha value为0,并且色值方程配置pn=0,qn=0,an=alphaA,bn=(1-alphaA),其中n={1,2,3,4}即可实现window 0显示,而其他窗口透明。

2、virtual display

作用:虚拟显示就是所谓的局部显示,显示一张尺寸超过lcd显示屏的图片。

现在来说下虚拟现实的方式,其实虚拟显示主要就是靠在一次帧中得偏移计算得到,我们知道,在framebuffer中存放的就是要显示的数据,假如现在我们显示的是一张16bits(R:5:G6:B5)bpp, non-pallette的位图。那一个pixel就占用了两个bytes,并且Lcd显示屏的标准输出像素是480*272,这样每一帧实际内存占用大小就是480*272*2个字节。但是如果图片的本身大小假设是960*544,那它的内存占用大小则是960*544*2,也就是说,我们只要能计算出想要开始显示的位置,那就可以输出我们想要的效果:

Offset = framebuffer_start_address+x * 2 + y * 480 * 2;

但是一定判断是否跃出framebuffer的最大长度以及输出的帧的有效位置,如果超过了,那么很可能会图片扭曲。注意,s5pc100的最大虚拟显示分辨率可达16M.

3、CSC(color space convertor)

这是一个图形格式转换的接口,它提供了一个从本地fifo拿到的YCrCb格式的数据转换成RGB格式的功能。

三、 program module flow

<1>配置 video main control(n,0-2) register 这类寄存器基本控制了整个control的时钟属性,扫描方式,输出格式的选择,VIDEO output的输出使能,获取当前帧使能。
        <2>配置 video time control(n,0-2) register,该类寄存器配置了lcd显示屏的物理极性,时序间隔,输出尺寸。
        <3>配置 window (n,0-4) control register ,数据输入路径选择,交换数据长度。Burstlen,BPPmode的配置等。
        <4>配置alpha equation blending factor以及 window alpha_n control register,配置混合方程因子,以及配置alpha通道的值。
        <5>配置windows (n,0-4) postion control register ,窗体位置信息。包括OSD infomation。
        <6>绑定framebuffer地址。
        <7>window(n,0-4),输出使能。

按照这7步,只要时钟是正确范围内的配置,一般是有图像输出的。

四:总结FIMD

在整个移植裸机的过程中,发现了一些问题以及解决方案,先罗列如下:

1、上电后,lcd屏幕全为白色,表示工作就位。
        2、测试时候,如果出现蓝色背景,并且会有一个周期的缓慢刷新过程,则表示VIDEO MAIN的寄存器配置有问题。
        3、如果LCD仅仅是绿色背景,有可能也带有一些浮纹,则表示BPPMODE没有选择正确。
        4、图片扭曲,则说明OSD_HSIZE /OSD_WSIZE没有设置正确,或者horizontal/lineval没有配置正确。因为它的时序发生混乱了。需要调整正确才能正常显示图片。

<think>好的,我现在需要分析smartmontools的源码架构,了解它的设计和实现方式。首先,我应该了解一下smartmontools是什么。根据之前的知识,smartmontools是一个用于监控硬盘健康状态的工具,支持SMART(Self-Monitoring, Analysis and Reporting Technology)技术。它包含两个主要工具:smartctl和smartd。前者是命令行工具,用于检查和配置硬盘的SMART功能;后者是守护进程,用于定期监控硬盘状态。 接下来,我需要找到它的源码结构。用户提到的引用中并没有直接关于smartmontools的内容,但有一些关于其他项目如Greenplum、PostgreSQL和OpenWrt的编译和配置方法,这可能对理解源码结构有帮助。例如,引用[2]提到了使用make命令和交叉编译工具链,这可能意味着smartmontools也使用类似的构建系统。另外,引用[3]提到编辑头文件来适配不同数据库,可能smartmontools也需要根据不同平台或设备进行调整。 首先,我应该查找smartmontools的官方源码仓库,可能在GitHub或其他开源平台上。假设源码托管在GitHub上,可以访问其仓库查看目录结构。通常,C/C++项目的源码结构会有src目录存放源代码,doc存放文档,tests存放测试用例,configure或Makefile用于构建。 接着,我需要分析其主要模块。根据功能,smartmontools需要与硬件交互,所以会有设备驱动层的代码,处理不同接口(如SATA、SCSI、NVMe)的通信。还可能有一个核心库,封装通用的SMART解析逻辑,供smartctl和smartd调用。守护进程smartd可能使用事件循环或定时任务来定期检查硬盘状态,并记录日志或发送通知。 另外,跨平台支持也是关键,因为smartmontools需要运行在多种操作系统上,如Linux、Windows、macOS等。这可能通过条件编译或抽象层实现,类似引用[4]中PostgreSQL支持多种CPU架构的做法。例如,在代码中通过预处理器指令区分不同平台的功能实现。 构建系统方面,引用[2]提到了make和交叉编译,可能smartmontools也使用Autotools(configure脚本和Makefile)或CMake来管理构建过程。需要查看项目中的configure.ac或CMakeLists.txt文件,了解如何配置和编译不同目标。 测试和调试部分,项目可能包含单元测试或集成测试,确保代码的稳定性。引用[5]提到使用GitHub Actions进行持续集成,可能smartmontools也有类似的自动化测试流程,确保不同平台下的编译和功能正常。 在分析过程中,可能会遇到需要处理不同设备兼容性的问题,比如不同厂商的硬盘可能有不同的SMART属性定义。代码中可能需要通过设备类型检测和相应的解析模块来处理这些差异,这类似于引用[3]中提到的根据不同数据库配置头文件的做法。 总结来说,分析smartmontools的源码架构需要从目录结构、模块划分、平台适配、构建系统、设备通信和测试框架等方面入手,结合已有的项目结构和类似开源项目的经验,逐步拆解其设计思路和实现方式。</think>### smartmontools 源码架构分析与设计实现 #### 一、源码结构概览 smartmontools 的源码采用**模块化分层设计**,主要目录结构如下: ``` smartmontools/ ├── autoconf/ # 自动配置脚本 ├── db/ # 设备数据库(厂商/型号特定参数) ├── doc/ # 文档(man手册、技术规范) ├── drivedb.h # 编译时生成的设备数据库头文件 ├── os_*/ # 平台特定实现(Linux/Windows/FreeBSD等) ├── smartctl/ # 命令行工具核心代码 ├── smartd/ # 守护进程代码 └── utility/ # 通用工具库(日志系统、字符串处理等) ``` 这种结构与 Greenplum 的模块化设计类似[^1],但更聚焦于设备交互层。 #### 二、核心模块设计 1. **设备抽象层(Device Abstraction Layer)** - 支持多种接口协议: ```c // os_linux.cpp class ata_device : public smart_device { bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out); } class scsi_device : public smart_device { bool scsi_pass_through(scsi_cmnd_io *io); } ``` 通过虚函数实现多态,类似 PostgreSQL 的多架构支持设计[^4]。 2. **SMART 数据解析引擎** - 使用`drivedb.h`数据库匹配设备特征: ```c // atacmds.cpp const smart_device_entry *find_device_entry( const smart_devidlist &devidlist, const char *model, const char *firmware) ``` 类似 TPC-H 工具的设备配置机制[^3]。 #### 三、跨平台实现 采用条件编译支持不同OS: ```c // os_linux.cpp #if defined(__linux__) int smartd_get_powermode(const char *dev) { // 通过/sys文件系统获取电源状态 } #endif // os_win32.cpp #if defined(_WIN32) int smartd_get_powermode(const char *dev) { // 调用DeviceIoControl API } #endif ``` 类似 OpenWrt 的自定义编译架构方法[^5]。 #### 四、构建系统 使用 GNU Autotools 构建: ```bash # 生成configure脚本 autoreconf -i # 交叉编译示例(参考引用[2]) ./configure --build=x86_64-pc-linux-gnu --host=arm-linux-gnueabihf make CROSS_COMPILE=arm-linux-gnueabihf- ``` #### 五、关键设计模式 1. **工厂模式**:通过`smart_device::autodetect()`自动创建设备对象 2. **观察者模式**:smartd 定时轮询设备状态变化 3. **策略模式**:不同设备类型(ATA/SCSI/NVMe)实现独立协议处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值