What we are doing here is getting a "big picture" view of the USB code. I have often done this for other projects, and I would say that it is almost essential when you are dealing with thousands of lines of code.
wc *.c *.h 473 1505 12401 usbd_cdc_vcp.c 238 668 7064 usbd_desc.c 37 99 1078 usbd_cdc_vcp.h 51 218 2250 usbd_conf.h 48 163 2076 usbd_desc.h 847 2653 24869 totalHere we have only 847 lines of code and 2 C files.
There are also 3 header files, but they aren't particularly interesting and I won't have anything to say about them.
VCPBytesAvailable () VCPGetBytes () -- outside world call to get data VCP_SetUSBTxBlocking () VCP_DataTx () -- outside world call to send dataVCPBytesAvailable() is wrapped in an inline function usbBytesAvailable(). This is never used. This is clearly a way of "renaming" this VCP specific function to something more generic.
Similarly, VCP_SetUSBTxBlocking () is wrapped in a pair of inline functions:
inline void usbEnableBlockingTx(void) { VCP_SetUSBTxBlocking(1); } inline void usbDisableBlockingTx(void) { VCP_SetUSBTxBlocking(0); }neither is called in the current code.
So this file contains the top level routines to read and write USB data once the VCP is enumerated and set up. Both of these would be excellent starting points for detailed study.
this file also contains several (5) static (private) routines that are exposed to the outside world via a "fops" structure. These 5 routines are:
Init, DeInit, Ctrl, DataTx, DataRxI will note before I move on that the code in this file makes relatively few calls to code in other files, but largely works by manipulating data structures. Even DataTx makes no calls, so other code must monitor data structures and notice when data has been posted to be sent.
One call is made to usbd_cdc_PrepareRx() in library/usbd_cdc_core.c
USBD_DEVICE USR_desc = { USBD_USR_DeviceDescriptor, USBD_USR_LangIDStrDescriptor, USBD_USR_ManufacturerStrDescriptor, USBD_USR_ProductStrDescriptor, USBD_USR_SerialStrDescriptor, USBD_USR_ConfigStrDescriptor, USBD_USR_InterfaceStrDescriptor, };These functions aren't declared static, but they really should be.
wc *.c *.h 718 2508 24405 usbd_cdc_core.c 418 968 10129 usbd_core.c 162 436 4216 usbd_ioreq.c 790 1637 18691 usbd_req.c 159 386 3245 usbd_usr.c 72 168 2725 usbd_cdc_core.h 45 87 1236 usbd_core.h 82 211 3620 usbd_def.h 44 98 1581 usbd_ioreq.h 31 90 1139 usbd_req.h 56 105 1643 usbd_usr.h 2577 6694 72630 total2577 lines of code in 5 C files and 6 header files. The header files are all tiny (but interesting)
It has a bunch of functions, here nicely declared static, that are grouped together in the following callback structure:
USBD_Class_cb_TypeDef USBD_CDC_cb = { usbd_cdc_Init, usbd_cdc_DeInit, usbd_cdc_Setup, usbd_cdc_EP0_RxReady, usbd_cdc_DataIn, usbd_cdc_DataOut, usbd_cdc_SOF, USBD_cdc_GetCfgDesc, };Then we have just one function:
usbd_cdc_PrepareRx () - called from vcp/usbd_cdc_vcp.c
USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb = { USBD_DataOutStage, USBD_DataInStage, USBD_SetupStage, USBD_SOF, USBD_Reset, USBD_Suspend, USBD_Resume, USBD_IsoINIncomplete, USBD_IsoOUTIncomplete, };Then:
USBD_Init () - we call this to initialize the driver USBD_DeInit () -- never called USBD_DeInitFull () -- could be called during usbPowerOff() USBD_SetCfg () -- called by usbd_req.c USBD_ClrCfg () -- never called
USBD_CtlSendData () -- called by usbd_cdc_core.c and usbd_req.c USBD_CtlContinueSendData () -- called by usbd_core.c USBD_CtlPrepareRx () -- called by usbd_cdc_core.c USBD_CtlContinueRx () -- called by usbd_core.c USBD_CtlSendStatus () -- called by usbd_core.c and usbd_req.c USBD_CtlReceiveStatus () -- called by usbd_core.c USBD_GetRxCount () -- never calledNotice that CtlSendData "sends data on the ctl pipe" -- which suggests that CDC/VCP does use more than one endpoint, with an extra one devoted to ctl information
USBD_StdDevReq () - called by usbd_core.c duing setup (enumeration) USBD_StdItfReq () - called by usbd_core.c duing setup (enumeration) USBD_StdEPReq () - called by usbd_core.c duing setup (enumeration) USBD_ParseSetupRequest () - called by usbd_core.c duing setup (enumeration) USBD_CtlError () -- many calls (all from library) to handle low level error USBD_GetString () -- convert ascii to unicode - many calls from vcp/usbd_desc.c USBD_GetLen () - once call from library/usbd_req.c
SBD_Usr_cb_TypeDef USR_cb = { USBD_USR_Init, USBD_USR_DeviceReset, USBD_USR_DeviceConfigured, USBD_USR_DeviceSuspended, USBD_USR_DeviceResumed, USBD_USR_DeviceConnected, USBD_USR_DeviceDisconnected, };The above ought to be static, but aren't -- so I made it so. It has these important one line functions:
uint8_t usb_isConfigured(void) { return (usbd_status&USB_CONFIGURED); } uint8_t usb_getStatus(void) { return usbd_status; }
Tom's Computer Info / tom@mmto.org