最近在用CH565開發(fā)實時傳輸(isochronous)USB3.0 UVC相機(jī)。發(fā)現(xiàn)必須允許DVP中斷被USBSS中斷打斷,才能保證相機(jī)的幀率(640*480 166 FPS @RAW8)正常。
//設(shè)置DVP中斷,0x80表示可以被打斷,
?//注意:USB3.0 ISO傳輸成功的關(guān)鍵所在
PFIC_SetPriority(DVP_IRQn, 0x80 | 13);
但是這也產(chǎn)生另外一個后果, 就是USBSS中斷和DVP中斷可能同時寫DMA內(nèi)存。例如:DVP接收完Image Sensor送來的一行圖像數(shù)據(jù),我把行首和行尾在DMA內(nèi)存中用字符串標(biāo)記,以方便USB抓包分析。
void DVP_Handler_USB30(void)
{....
???? uint8_t* pRecvBuff=pRecvSlot->ptrImageBegin + pRecvSlot->dataLength;
????//行首標(biāo)記:RW<行號>
????pRecvBuff[0]='R';
???? pRecvBuff[1]='W';
???? int rowCount = g_Usb30SSDvpDmaInfo.rowCount;
????//char digits[4];
????nt divisor = 1000;
????for(int i=0; i < 4; i++)
????{
????????g_dbgDigits[i] = 0x30 + rowCount/divisor;
????????owCount = rowCount % divisor;
????????divisor? = divisor / 10;
??????}
???????? pRecvBuff[2] = digits[0];
???????? pRecvBuff[3] = digits[1];
????? ? ?pRecvBuff[4] = digits[2];
???????? pRecvBuff[5] = digits[3];
????????int width = g_Usb30SSDvpDmaInfo.nImageWidth;
????????//行尾標(biāo)記:<行號>end
????pRecvBuff[width - 1]='d';
????pRecvBuff[width - 2]='n';
????pRecvBuff[width - 3]='e';
????pRecvBuff[width - 4] = digits[3];
????pRecvBuff[width - 5] = digits[2];
????pRecvBuff[width - 6] = digits[1];
????pRecvBuff[width - 7] = digits[0];
...
}
USBSS IN中斷搶了DVP中斷,在USBSS IN中斷中準(zhǔn)備UVC ISO PayloadHeader
void EP3_IN_Callback()
{...
????if(bHasPayloadeHeader)
????{
????PayloadHeader* PH = (PayloadHeader*)g_USB30DMAInfo.dvpData;
????//PH->bHeaderLength = sizeof(PayloadHeader);
????PH->bmHeaderInfo = g_Usb30SSDvpDmaInfo.bmHeaderInfo;
????PH->scrSourceClock.dwSourceClock = g_ClkCount;
????PH->scrSourceClock.wSOFTokenCounter = (USBSS->USB_ITP >> 3) & 0x3FF;
????//PH->alignPadByte = 0x00524448 | ((USBSS->USB_ITP%26 + 0x41) << 24);//"HDR#"
????PH->dwPresentationTime = g_ClkCount;//幀開始采集時刻
????}
...
}
通過USBCap抓包分析,發(fā)現(xiàn)一般正常的包如下
08a0? ?6b 7c 7d 67 6f 5d 64 6c 7c 70 75 66 65 6c 75 79? ?k|}go]dl|pufeluy
08b0? ?30 30 30 30 65 6e 64 52 57 30 30 30 31 aa 8f aa? ?0000endRW0001...
08c0? ?98 bb 92 b1 92 af 8d 98 98 c3 8a c3 9c bb 91 b8? ?................
但是也出現(xiàn)了如下詭異的現(xiàn)象
5da0? ?94 71 8c 78 aa 74 9f 6f 89 71 8e 81 99 6b 87 7a? ?.q.x.t.o.q...k.z
5db0? ?88 82 84 61 7a 76 7b 6a 78 6a 6d 6c 89 60 76 66? ?...azv{jxjml.`vf
5dc0? ?30 30 33 34 65 6e 64 c5 89 30 30 33 35 b7 92 c0? ?0034end..0035...
5dd0? ?90 bf 87 b5 8c bf a0 ad a6 cb 99 cd 93 b9 9d bf? ?................
6030? ?79 83 73 79 62 7d 75 7c 7f 7c 6f 78 61 74 68 6d? ?y.syb}u|.|oxathm
6040? ?6a 7d 71 76 6f 66 5f 84 ab 30 30 33 36 85 bd 76? ?j}qvof_..0036..v
6050? ?ba 7a b2 8f c3 93 de 8b c6 97 bb 93 c6 8f c9 7f? ?.z..............
發(fā)現(xiàn)標(biāo)記內(nèi)容與程序意圖不一致,剛開始懷疑是程序Bug, 將相機(jī)設(shè)置于曝光狀態(tài)即像素值都為0xFF方便查看,做了各種實驗發(fā)現(xiàn)關(guān)了中斷嵌套后問題消失。懷疑問題的根本原因是不是DMA內(nèi)存訪問出現(xiàn)了沖突。
請教一下: 1)USB3.0對DMA內(nèi)存讀的帶寬是5GBPS,DVP對DMA內(nèi)存寫的帶寬是60MB/s, 那么USB3.0和DVP對DMA內(nèi)存的讀寫時鐘顯然不一樣。RISC-V內(nèi)部DVP和USB3.0,是不是共用數(shù)據(jù)總線和地址總線的?如果是,如何解決時鐘頻率沖突的。
2)如果在中斷嵌套情形下, 中斷A在寫DMA然后中斷B打斷中斷A的寫入,中斷B也寫入一些東西到DMA內(nèi)存,然后中斷B退出,中斷A繼續(xù)寫入,這樣會不會導(dǎo)致DMA內(nèi)存的數(shù)據(jù)總線和地址總線時序紊亂呢?