生成的工程中,可以在BSP中找到XVTC的驱动代码。
其中的xvtc.h是总的头文件,其中定义了各种参数,
xvtc_hw.h是硬件相关的定义,定义了各个寄存器的offset,各个bit位的mask,并给出了各个基础宏的alias宏别名,以及各个基础宏拟函数的encapsulation,宏拟函数的再封装,形成宏拟函数别名。
+++++++++++++++++++++++++++++++++++++++++++++++++++
xvtc.h解析。
1)XVTC_VMODE_*
定义了各种VMODE对应的参数值。
2)XVTC_EN_GENERATOR,XVTC_EN_DETECTOR
使能generator或者detector对应的参数值。
3)XVtc_Config
定义了RDB的结构体。(resource description block)
4)XVtc_Polarity
定义了PDB的结构体。(parameter description block)
5)XVtc_SourceSelect
定义了PDB的结构体。
6)XVtc_Signal
定义了PDB的结构体。
7)XVtc_HoriOffsets
定义了PDB的结构体。
8)XVtc_Timing
定义了PDB的结构体。
9)XVtc
定义了RCB的结构体。(resource description block)
10) XVtc_Reset
宏拟函数,封装了具体操作。
11)XVtc_SyncReset
宏拟函数,封装了具体操作。
12)XVtc_EnableSync
宏拟函数,封装了具体操作。
13)XVtc_RegUpdateEnable
宏拟函数,封装了具体操作。
14)XVtc_IntrEnable
宏拟函数,封装了具体操作。
15)XVtc_IntrClear
宏拟函数,封装了具体操作。
+++++++++++++++++++++++++++++++++++++++++++++++++++++
xvtc.c解析。
1)XVtc_EnableGenerator
使能generator。
这里使用了嵌入式中常用的技巧,就是bitmask。
如果是set bit,那么就使用自或赋值运算符,和mask进行自或运算,
CtrlRegValue |= XVTC_CTL_GE_MASK;
如果是clear bit,那么就使用自与赋值运算符,和mask的反码进行自与运算,注意反码要进行类型强转,
CtrlRegValue &= (u32)(~(XVTC_CTL_GE_MASK));
2)XVtc_SetPolarity
设置video timing中各个信号的极性值。
在SOD设计思想下,各个信号的极性值,被封装为一个PDB。本函数利用PDB中的数据,写入寄存器的对应bit。
if (PolarityPtr->ActiveVideoPol)
PolRegValue |= XVTC_POL_AVP_MASK;
3)XVtc_GetPolarity
获取video timing中各个信号的极性值。
在SOD设计思想下,各个信号的极性值,被封装为一个PDB。本函数读取寄存器值后,使用bitmask分离出各个bit的值,判断后,修改PDB中的各个成员变量。
if (PolRegValue & XVTC_POL_ACP_MASK)
PolarityPtr->ActiveChromaPol = 1;
4)XVtc_SetSource
设置video timing中各个信号的极性值源自于哪个寄存器。
如果设置为1,则源自于generator,如果是0,则源自于detector。
在SOD设计思想下,各个信号的极性源,被封装为一个PDB。本函数利用PDB中的数据,写入寄存器的对应bit。
5)XVtc_SetSkipLine
设置chroma信号是否跳行,跳行参数是一个单独的参数,不需要封装成PDB结构体。所以传递时,直接传值即可,不需要传址。
6)XVtc_GetSkipLine
获取chroma信号是否跳行,跳行参数是一个单独的参数,不需要封装成PDB结构体。但是需要将获取的值写入buffer,所以仍然需要传址,只不过,传址不是PDB的指针,而是单独的整形变量的指针。
7)XVtc_SetSkipPixel
设置chroma信号是否跳像素,跳像素参数是一个单独的参数,不需要封装成PDB结构体。所以传递时,直接传值即可,不需要传址。
8)XVtc_GetSkipPixel
获取chroma信号是否跳像素,跳像素参数是一个单独的参数,不需要封装成PDB结构体。但是需要将获取的值写入buffer,所以仍然需要传址,只不过,传址不是PDB的指针,而是单独的整形变量的指针。
9)XVtc_SetDelay
设置horidelay和vertdelay。
两个参数,是单独的整形变量,不需要封装成PDB结构体。所以传递时,直接传值即可。不需要传址。
这里使用了嵌入式中常用的技巧,就是bitsmask。
如果是create bitvector,就使用与运算符,使参数和bitsmask进行与运算。并赋值给中间临时变量。
RegValue = HoriDelay & XVTC_GGD_HDELAY_MASK;
这里还使用了嵌入式中常用的技巧,就是bitshift。
不同于mask的set或者clear方式,
bitshift是用宏指定移动的位数,使用左移操作符或者右移操作符,
通过shift left 或者shift right,将参数值,搬移到合适的window上,
然后再使用bitsmask,生成bitvector,
然后再使用自或赋值运算,将生成的bitvector,插入到中间变量中去。
RegValue |= (VertDelay << XVTC_GGD_VDELAY_SHIFT)
& XVTC_GGD_VDELAY_MASK;
10)XVtc_GetDelay
获取horidelay和vertdelay。
两个参数,是单独的整形变量,不需要封装成PDB,但是需要将获取的值写入buffer,所以仍然需要传址,只不过,传址不是PDB的指针,而是单独的整形变量的指针。
这里,仍然使用了bitsmask,用与运算create bitvector。
*HoriDelayPtr = RegValue & XVTC_GGD_HDELAY_MASK;
先使用bitsmask,用与运算来create bitvector,
得到bitvector后,使用了bitshift,将bitvector,搬移到合适的window上。
*VertDelayPtr = (RegValue & XVTC_GGD_VDELAY_MASK)
>> XVTC_GGD_VDELAY_SHIFT;
11)XVtc_SetFSync
设置fsync的位置,
12)XVtc_GetFSync
获取fsync的位置,
13)XVtc_SetGeneratorHoriOffset
设置以line number为单位的位置,即vblank和vsync,
这些参数被封装成为PDB,所以需要传址,
通过start position和end position的形式给出。
vtc内部维护计数器,在start的位置拉高信号,在end的位置拉低信号,
14)XVtc_GetGeneratorHoriOffset
获取vblank和vsync,以line number为单位的位置
这些参数被封装成为PDB,所以需要传址,
15)XVtc_SetGenerator
设置timing的size等参数,
16)XVtc_GetGenerator
获取timing的size等参数。
17)XVtc_ConvVideoMode2Timing
根据videomode 填充timing的PDB结构体的各项参数。
18)XVtc_ConvTiming2Signal
根据timing的PDB结构体中的各项参数,填充XVtc_Signal的PDB,XVtc_HoriOffsets的PDB,XVtc_Polarity的PDB。
19)XVtc_SetGeneratorTiming
根据根据timing的PDB结构体中的各项参数,首先转换成各种signal的PDB,然后,依次将各个signal的PDB中的参数,写入对应的REG中。
20)XVtc_SetGeneratorVideoMode
根据videomode,首先将mode转化成timing的PDB,然后,调用XVtc_SetGeneratorTiming,将各项参数,写入对应的REG中。
++++++++++++++++++++++++++++++++++++++++++++++++++
实际使用时,使用高层次的封装函数,通常就够用了。
例如:
XVtc_SetGeneratorVideoMode
或者
XVtc_SetGeneratorTiming
如果需要精细的定制timing,就需要手工修改timing的PDB中的各项参数,然后再写入REG。
除了设置参数,
还需要setsource,以及enable,以及regupdateenable.
下面以720p模式为例,分析timing的PDB。
首先学习几个重要的参数,
在signalcfg这个PDB中,有如下参数:
originmode----Set Frame Origin to Start of Active Video
Htotal----这是VTC的HCNT的计数器总数,例如为7,则HCNT计数从0到6,周而复始,
Hactivestart----当检测到HCNT为此值时,拉高active_video信号,同时拉低hblank,
Hfrontporchstart----当检测到HCNT为此值时,拉低active_video信号,同时拉高hblank,
Hsyncstart----当检测到HCNT为此值时,拉高hsync,
Hbackporchstart----当检测到HCNT为此值时,拉低hsync,
Vtotal----这是VTC的VCNT的计数器总数,例如为7,则VCNT计数从0到6,周而复始。
Vactivestart----当检测到VCNT为此值时,拉高内部信号Vactiveen,它和active_video在内部相与,此时,active_video可以输出.
Vchromastart----当检测到VCNT为此值时,拉高内部信号Vchromaen,它和active_chroma在内部相与,此时,active_chroma可以输出.
Vfrontporchstart----当检测到VCNT为此值时,拉低内部信号Vactiveen,同时拉高vblank,
Vsyncstart----当检测到VCNT为此值时,拉高vsync,
Vbackporchstart----当检测到VCNT为此值时,拉低vsync,
By default, the blanking signal rises at the same clock edge the last active video signal (of
a frame) falls and falls at the same clock edge the first active video signal (of a frame) rises.
Also by default, the vsync signals rises and falls at the same clock edge as a rising edge of
the 6th rising edge of the hblank signal.
所以,我们看到,Hblank的包络区域,和active_video的包络区域是相反的。
而且,我们看到,Vblank的上升沿对齐到Hblank的上升沿,Vblank的下降沿对齐到Hblank的下降沿。
也可以精调vblank的上升沿和下降沿位置,
如果要使vblank的上升沿不对齐于hblank的上升沿,例如,hblank在1280时上升,那么,设置vblank在1285上升,可以使vblank上升沿滞后5个clk,
如果要是vblank的下降沿不对齐于hblank的下降沿,例如,hblank在1650时下降,那么,设置vblank在1645下降,可以使vblank下降沿提前5个clk,
也可以精调vsync的上升沿和下降沿位置,
如果要使vsync的上升沿不对齐于hblank的上升沿,例如,设置vsync在0上升,可以使vsync上升沿对齐到active_video的上升沿,即hblank的下降沿,
如果要是vsync的下降沿不对齐于hblank的上升沿,例如,设置v在1275下降,可以使vsync下降沿提前于active_video的下降沿即hblank的上升沿,5个clk下降,
在timing这个PDB中,有如下参数:
HActiveVideo----一行的有效像素数
HFrontPorch----Hblank的前部门廊的像素数,
HSyncWidth----Hblank的Hsync的像素数,
HBackPorch----Hblank的后部门廊的像素数,
HSyncPolarity----Hsync的极性
VActiveVideo----一帧的有效像素行数
V0FrontPorch----Vblank的前部门廊行数,
V0SyncWidth----Vblank的Vsync的行数,
V0BackPorch----Vblank的后部门廊行数,
VSyncPolarity----Vsync的极性
调用API,可以将timing的格式转换成signalcfg的格式,
通常使用timing格式。
++++++++++++++++++++++++++++++++++++++++++++++++
补充:
嵌入式中常用的位操作。
对于一个32位的U32 的int,我们需要把它整理成bit segment。
这就需要用到嵌入式中的多种位操作技巧。
例如,bitmask,bitshift,等等。
对于一个U32的int,在没有进行位处理时,我们可以视为bitstring,
对于一个U32的int,如果只有某个感兴趣的有效区域为全1,其余的不感兴趣的无效区域为全0,那么我们称之为一个bitvector。
bitvector和bitstring的区别就在此,一个具有ROI,一个不具有ROI。
显然,bitmask就是一个U32,而它,就是一个bitvector。
我们使用bitmask或者bitsmask,
如果使用与操作符&,对bitstring进行处理后,就起到了get value of ROI 的作用。
如果使用或操作符|,对bitstring进行处理后,就起到了set value of ROI 的作用。
如果使用与操作符&,但是是使用的opposite mask,就起到了clear value of ROI的作用。
对于一个已经包含了ROI的bitvector,(通常是本步骤的运算结果),通常使用或操作符|,插入到另一个btivector中,(通常是中间临时变量),从而形成一个更新的中间结果。
这里,或操作符|,起到"拼位运算符"的作用。
包括CPU和内存2方面技术,是针对英特尔的EM64T技术CPU是一个扩展、可以兼容32位的64位处理器。目前只有配备800MHz 前端总线的英特尔至强处理器支持EM64T。因为现在操作系统和应用软件等还没有完全过渡到64位,所以...
1.直接计算代码:#include&lt;iostream&gt;#include&lt;algorithm&gt;#include&lt;cstring&gt;#include&lt;cstdio&gt;#include&lt;cmath&gt;#include&lt;queue&gt;#include&lt;vector&gt;#define LL long long
脚本执行外部程序的常用几种方式:# os.popen(path)# subprocess.run(cmd,shell=True)# subprocess.check_call(cmd,shell = True)# os.system(command)# win32api.ShellExecute(0, 'open', path, '', '', 0)os.popen(path) 和 os.syst...
出现这个问题是因为我们写了一个接口,全部的restful的annotation都写在了这个接口上,然后让提供服务的类实现这个接口。就导致了这个问题。其实想一想还是很容易理解的,我们可能写多个类实现这个接口,这样就会出现找不到到底哪个子类才是我们想要的实现的情况。请看stackoverflow上面的一篇讨论:http://stackoverflow.com/questions
/ 前言 / 在与虚拟机打交道中,我们会常常接触到镜像,除了我们常用vmdk镜像外,还有很多诸如vhd、qcow2、raw、vhdx、qcow、vdi、qed、zvhd或zvhd2等镜像,这次我们就来介绍一下,如果我们拿到的是一个qcow2类型的镜像那么我们如何将其转换为vmdk/ 工具 / ...
继承AuthorizationServerConfigurerAdapter方法的配置@[email protected] class Oauth2ServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; //加密 @Auto
var datetime = new Date(); var year=datetime.getFullYear();//获取完整的年份(4位,1970) var month=datetime.getMonth()+1;//获取月份(0-11,0代表1月,用的时候记得加上1) if(month<=9){ month="0"+m
https://github.com/ElemeFE/element/blob/d419e260d0fc1463ccbc4f5e45e129ec0e972255/src/utils/clickoutside.js下面的代码是element ui中的clickoutside.jsconst on = (function() { if (!Vue.prototype.$i...
jupyter 的使用一、启动程序执行命令:jupyter notebook注意以下几点:打开地址为当前bash的目录,默认的根目录浏览器地址为 http://localhost:8888/通过control -C终止jupyter程序几个基本操作:DD:删除当前cellM:转为markdown文档markdown文档下运行变为预览模式二、IPython的帮助文档1. 使用help()通过help命令来获得帮助文档help(len)Help on built-in f
在SylixOS 中退出中断和内核都会系统调度任务,任务调度底层切换上下文,底层实现参考链接在SyliOS默认优先级是0-255,数值越小优先级越高。在SylixOS 任务就绪队列是通过位图的方式去查找,如果当前优先级有任务则对应的位图位就会变成1。在查找到最后优先级后,从对应链表中取出任务控制块tcb,对比是否比当前任务优先级高,决定是否切换任务。在arm中支持硬件实现前导零计数,所以能...
可能是英文不好的原因,一直不能理解什么是speculative; 到底啥意思;这个设置的方法是在column family level设置speculative_retry = '99.0PERCENTILE';什么是retry呢?就是如果一个查询到了node1上,可是node1此刻非常慢,例如正在做GC. 那么就以为这这个node不能快速的返回数据。怎么办呢?继续等?Cassandra认...
在文章中都离不开标题,网页中的标题就是标题标签h标签,一共有1-6六个标签,其重要程度依次递减,文字大小也依次减小,标题标签的特点就是文字会加粗和变大,并且独占一行在文章中都离不开段落,网页中的段落就是段落标签p标签,其特点就是独占一行,段落之间存在间隙换行标签为br标签,就是让文字强制换行显示,其特点就是单标签,可以让文字强制换行在文章中,有时候会用一条横线来分割不同主题的内容,网页中的横线就是水平线标签hr,其特点就是单标签,在网页中显示一条横线在网页中,可以让文字有加粗、倾斜、删除线、下