请帮忙指点小弟一下,有如下某段程序:
1 EVMDM642_vDisParamsChan.segId = EXTERNALHEAP;
gio类驱动中fvid模块中指定将用来分配视频帧缓冲区的存储段ID设置为EXTERNALHEAP
由dsp/bios中mem模块分配可知EXTERNALHEAP是外部存储器中的堆,地址为0x80000000,但是具体的y,cr,cb缓冲器地址怎么确定?在.map中,以及cmd文件中都没有定义。程序中也没有
我看资料上说IOM_Packet这个结构体中有edma传送的目的地址,图像buffer的大小和地址应该是在程序中说明的,大小应该是在EVMDM642_vDisParamsChan,EVMDM642_vCapParamsChan定义,在但是我在程序中没有看见给IOM_Packet地址傅值?不知是否用IOM_Packet来定义edma传输的目的地址和大小?源地址为fifo地址
2 在dischan或者capchan通道配置中有一项为:Alignment:Buffer的字节对齐
此处为128字节对齐,即buffer的开始地址为128的倍数,这个是怎么意思?
1.,但是具体的y,cr,cb缓冲器地址怎么确定?
FVID_Frame *capFrameBuf;
FVID_alloc(capChanCh1, &capFrameBuf); 其中capChanCh1是FVID句柄。
capFrameBuf->frame.iFrm.y1就是Y存储区的地址
capFrameBuf->frame.iFrm.cb1/cr1是cb cr的地址,这些成员定义可以在FVID。H中找到。
但这个地址与“VP口缓冲地址”是两回事,VP口的数据超过FIFO的域值后触发EDMA将数据传输到上面指定存储区域。
“但是我在程序中没有看见给IOM_Packet地址傅值?不知是否用IOM_Packet来定义edma传输的目的地址和大小?”
这个在capChanCh1 = FVID_create(。。。)和FVID_control(。。。)中完成的。
2 这个是为了提高CACHE的命中率,因为L2D的行大小是128字节,一行数据在应用程序里是经常要连续获取的,如果是128对齐的话,这行的第一个像素miss导致一行被读入L2D,后面的127个都会命中. 大概就是这个意思,CACHE的文档里也推荐这个做。
回答不准确的话,希望大家一起讨论。
首先十分感谢您的回答,不过还有些不明白,再次请教 呵呵
对于第一个问题,y,cr,cb的缓冲器具体地址确定?
FVID_Frame *capFrameBuf;
FVID_alloc(capChanCh1, &capFrameBuf); 其中capChanCh1是FVID句柄。
capFrameBuf->frame.iFrm.y1就是Y存储区的地址
capFrameBuf->frame.iFrm.cb1/cr1是cb cr的地址,这些成员定义可以在FVID。H中找到。
这个没错,不过fvid.h中定义的好像是图像格式吧,里面有一个联合体,定义了比如说隔行(iframe)或者逐行(pframe)的形式等,应该没有定义capFrameBuf的地址吧,capFrameBuf为指向某种图像格式的结构体指针,结构体里面有y,c等组成某种格式图像,capFrameBuf->frame.iFram.y1是否是隔行扫描情况下的亮度值呀?
capChan = FVID_create("/VP0CAPTURE/A/0", IOM_INPUT, &status, (Ptr)&EVMDM642_vCapParamsChan, NULL);
FVID_control(disChan, VPORT_CMD_EDC_BASE + EDC_CONFIG, (Ptr)&EVMDM642_vDisParamsSAA7105);
FVID_control(capChan, VPORT_CMD_EDC_BASE + EDC_CONFIG, (Ptr)&EVMDM642_vCapParamsSAA7115);
FVID_control(disChan, VPORT_CMD_START, NULL);
FVID_control(capChan, VPORT_CMD_START, NULL);
从fvid_creat与fvid_control中怎么看出给IOM_Packet edma传输的目的地址和大小?
"y,cr,cb的缓冲器具体地址确定?"
具体地址是不确定的,是动态分配的。
希望你能找到下面这段代码(位于DDK的SRC的VIDEO文件夹的vportdis.c里)。
static Int _configEDMA(Ptr chanp, VPORTDIS_Params *params)
{ 。。。。(略)
for(i = 0; i < chan->numFrms; i ++) {
if((curAddr = MEM_alloc(params->segId,chan->bufSz,
params->alignment)) == MEM_ILLEGAL){
for(j = 0; j < i ; j ++) {
MEM_free(params->segId, chan->viops[j].frame.iFrm.y1,
chan->bufSz);
}
/* memory allocation fails */
return IOM_EALLOC;
}
。。。。
for(i = 0; i < edmaChans; i ++) {
Int optFld1 = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_YES,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_NONE,
EDMA_OPT_TCINT_NO,
EDMA_OPT_TCC_OF(0),
EDMA_OPT_TCCM_OF(0),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
);
Int optFld2a = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_YES,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_NONE,
(i == 0 ? EDMA_OPT_TCINT_YES:EDMA_OPT_TCINT_NO),
EDMA_OPT_TCC_OF(i == 0 ? chan->tcc[0] & 0x0f : 0),
EDMA_OPT_TCCM_OF(i == 0 ? chan->tcc[0] >> 4 : 0),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
);
Int optFld2b = EDMA_OPT_RMK(
params->edmaPri,
EDMA_OPT_ESIZE_32BIT,
EDMA_OPT_2DS_YES,
EDMA_OPT_SUM_INC,
EDMA_OPT_2DD_NO,
EDMA_OPT_DUM_NONE,
(i == 0 ? EDMA_OPT_TCINT_YES:EDMA_OPT_TCINT_NO),
EDMA_OPT_TCC_OF(i == 0 ? chan->tcc[1] & 0x0f : 0),
EDMA_OPT_TCCM_OF(i == 0 ? chan->tcc[1] >> 4 : 0),
EDMA_OPT_ATCINT_NO,
EDMA_OPT_ATCC_DEFAULT,
EDMA_OPT_PDTS_DISABLE,
EDMA_OPT_PDTD_DISABLE,
EDMA_OPT_LINK_YES,
EDMA_OPT_FS_NO
);
。。。。。。。。。。
}
你感兴趣的东西都在DDK的这个video驱动代码里。
实在是太感谢了,我明天看看这些代码。
但是我看有些别的视频采集的例子,它们的缓冲器地址都确定的,比如说某个采集程序有如下一段:
Uint32 capYbuffer = 0x80000000;
Uint32 capCbbuffer = 0x800675c0;
Uint32 capCrbuffer = 0x8009b0a0;
Uint32 disYbuffer = 0x80100000;
Uint32 disCbbuffer = 0x801675c0;
Uint32 disCrbuffer = 0x8019b0a0;
两者一般区别在哪?一般我们都直接处理亮度信号,对于那种随机分配的是不是用capFrameBuf->frame.iFrm.y1就行啦,比如说一张cif格式的,320X240(忘记了),这个亮度信号320X240的矩阵怎么取出来?
另外的如果我想用ping-pong缓冲器这种结构,两对ping-pong buffer一般都分配到sdram中吗?这样的buffer地址也是随机分配还是另外有分配办法?
"两者一般区别在哪?" 两者没有实质的区别,你自己指定EDMA的目的地址(capture)当然也可以。只是FVID的这种方式更加灵活,移植能力强,因为代码里没有绝对地址。
“一般我们都直接处理亮度信号,对于那种随机分配的是不是用capFrameBuf->frame.iFrm.y1就行啦” 是的 图象获取后一般是PAL 或NTSC格式,要自己编写CIF转换代码,还有种方法就是利用VP口自带的水平采样,读场数据实现垂直采样(这个我自己没实现,需要配置好VP口参数)。
两对ping-pong buffer一般都分配到sdram中吗?这样的buffer地址也是随机分配还是另外有分配办法? 我习惯把ping-pong放到片内RAM里,这样不用考虑一致性问题,至于使用MEM_alloc分配还是自己申明数组看个人爱好。
谢谢
看了看那vportdis.c那个程序,大体知道了y,cr,cb的buffer是在segld中随机分配,这样的话是不是不能用view-image这个命令来查看图像拉?
另外,当fifo达到阈值时,触发硬件中断,在中断服务程序中启用一个EDMA通道将数据从FIFO中读出。如果要设置采集完一帧后产生edma中断怎样设置?,需要设置bios吗?下面一段话我从网页上看到的有些不明白
“EDMA中断设置:在中断服务表(IST)中添加EDMA_intDispatcher(),作为EDMA中断服务取指包(ISTP),然后使用EDMA_intHook()将两个亮度底场EDMA的传输结束代码与中断服务程序建立连接。
设置64个EDMA通道共享一个中断号,中断发生时,EDMA_intDispatcher()首先检测CIER和CIPR寄存器中的被置位的位,然后再调用由EDMA_intHook()连接的中断服务程序。中断发生后,通过传输结束代码进行区分当前中断是哪个EDMA通道触发的”
不明白主要是关于中断服务表等许多问题,关于中断设置的问题需要看ti的哪个资料呀?
如果要设置采集完一帧后产生edma中断怎样设置? 开中断,配置好EDMA参数。
两种方法:(1)使用BIOS的中断调度,这样直接指定EDMA中断服务函数,在中断服务函数里调用API确定是哪个通道的中断。 (2)不使用BIOS,这样需要自己维护中断向量表,就哪个ver.asm,在里面改下就好了。
这方面看几个CCS自带的example就会了。