搞懂以下問題,來理解USB
主機發送2字節時,小於端點的容量,怎么標志包的結束
內部自動完成,發送幾個數都可以。是底層自動完成的
主機發送513字節時,大於端點的容量,怎么分包?
txFifo空中斷中,將數據拷貝到FIFO,調整指針。
數據如何從stm32發給電腦:
app調用usbd_cdc_if.c中的CDC_Transmit_HS();
CDC_Transmit_HS調用usbd_cdc.c中的USBD_CDC_TransmitPacket();
USBD_CDC_TransmitPacket調用usbd_conf.c中的USBD_LL_Transmit();
USBD_LL_Transmit調用 stm32f4_hal_pcd.c中的HAL_PCD_EP_Transmit();
HAL_PCD_EP_Transmit調用stm32f4_ii_usb.c中的USB_EPStartXfer();
USB_EPStartXfer設置了發送數據大小,並使能IN端點; 要發送的數據時怎么讓USB外設知道的:
CDC_Transmit_HS調用usbd_cdc.c中的USBD_CDC_SetTxBuffer
USBD_CDC_SetTxBuffer中設置hcdc->TxBuffer,hcdc->TxLength
HAL_PCD_EP_Transmit中設置ep->xfer_buff,ep->xfer_len
stm32f4_ii_usb.c中的USB_EPStartXfer設置打開TX FIFO空中斷;
stm32f4xx_hal_pcd.c中的HAL_PCD_IRQHandler,IN端點中斷調用PCD_WriteEmptyTxFifo();
PCD_WriteEmptyTxFifo調用stm32f4_ii_usb.c中的USB_WritePacket,並調整buff指針和len;
USB_WritePacket將數據搬運到usb的fifo中
注意,數據傳輸完的總中斷:
programmed size(全部數據)傳輸完畢后,stm32f4_hal_pcd.c中的HAL_PCD_IRQHandler()中斷調用usbd_conf.c中的HAL_PCD_DataInStageCallback
HAL_PCD_DataInStageCallback調用usbd_core.c中的USBD_LL_DataInStage ,其中調用了pdev->pClass->DataIn()
實際usbd_cdc.c中的USBD_CDC_DataIn通過注冊已經綁定為pdev->pClass->USBD_CDC_DataIn;
USBD_CDC_DataIn中判斷長度如果時整數包長度,就發送一個0長度的包,否則不發送。
一次發送至此,結束。
綜上,stm32發給電腦,完全是主動方式,期間不需要電腦的參與。
數據如何從電腦發給stm32:
電腦發給stm32一個包;
stm32進入中斷的RXFIFO noEmpty中斷,其中GRXSTSP中指明是哪個out端點中斷
中斷的是out數據包,且個數不為0,調用stm32f4_ii_usb.c中的USB_ReadPacket();
USB_ReadPacket將FIFO數據讀入ep->xfer_buff,
usbd_cdc.c中的USBD_CDC_Init、和usbd_cdc_if.c中的USBD_CDC_ReceivePacket調用USBD_LL_PrepareReceive()已經設置了緩沖區指針,上一步相當於直接寫入用戶自定義數組中。
要接收的大小,一旦這個programmed大小傳輸完,就會進入out中斷XFRC,標志所有數據傳輸完畢,接着調用用戶程序,然后再次調用prepare,准備好下一次接收。
怎么理解數據都是由主機發送的?從機不能主動發送數據給從機,在主機沒發起的情況下?
修改VID,PID,即能識別為光譜儀
usbd_conf.c中包含bsp.h文件,設定中斷vect
uc/osiii不能夠設置斷點調試,解決方式:https://blog.csdn.net/qq_24276421/article/details/52461061
串口中斷的優先級需要調整,大於0
USB只能接收一次,
USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum,uint8_t *pdata)
端點0在內部處理
其它端點通過回調函數處理:pdev->pClass->DataIn(pdev, epnum);
在usb_conf中,這個函數調用的:void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
HAL_PCD_DataInStageCallback
在stm32f4xx_hal_pcd.c的,void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)中調用
HAL_PCD_IRQHandler_HS
在usb_conf.c的void HAL_PCD_IRQHandler_HS(void)中調用
HAL_PCD_IRQHandler_HS
BSP_IntVectSet(BSP_INT_ID_OTG_HS, HAL_PCD_IRQHandler_HS);
在osIII的中斷向量表映射至OTG_HS
DOEPTSIZx
PKTCNT是組成XFRSIZE需要多少數據包
XFRSIZE是傳輸的總數據,可以設置為max packet size of EP,這樣每個數據包都會XFRC中斷,可以進行處理;也可以設置大於max packet size,這樣core會自動把多個數據包存入memory,最后一個包進入XFRC中斷;XFRC中斷的條件:1,XFRSIZE=0;2,size<max packet size