diff options
| author | hathach <[email protected]> | 2026-08-11 17:07:23 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2026-09-04 04:21:57 +0700 |
| commit | 3baa7c8fbafd2cbccc5810626ebbfaa50c0ea4da (patch) | |
| tree | 690704b3d82dff418ceeaf14e8d6f8ff41d16a2f /src/class | |
| parent | 4161a1cf63c5ca935766d27bd32f7dd3948e881a (diff) | |
sysview: instrument usbd/usbh, dcd/hcd and class-driver call sites
Level 2 marks the stack's task-side entry points (tud_task/tuh_task inner
loop, usbd_edpt_xfer, control transfers); level 3 adds the class drivers
(cdc, msc) and the rp2040 dcd/hcd as the reference portable layer. All
call sites compile away below their level.
Diffstat (limited to 'src/class')
| -rw-r--r-- | src/class/cdc/cdc_device.c | 11 | ||||
| -rw-r--r-- | src/class/msc/msc_device.c | 29 |
2 files changed, 33 insertions, 7 deletions
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index ed050ad03..0684710dd 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -11,6 +11,7 @@ #include "device/usbd.h" #include "device/usbd_pvt.h" +#include "common/tusb_sysview.h" #include "cdc_device.h" @@ -174,8 +175,11 @@ uint32_t tud_cdc_n_available(uint8_t itf) { uint32_t tud_cdc_n_read(uint8_t itf, void* buffer, uint32_t bufsize) { TU_VERIFY(itf < CFG_TUD_CDC, 0); + TUD_SYSVIEW_CALL(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_CDC_READ); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize); + uint32_t const ret = tu_edpt_stream_read(&p_cdc->rx_stream, buffer, bufsize); + TUD_SYSVIEW_RET(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_CDC_READ); + return ret; } bool tud_cdc_n_peek(uint8_t itf, uint8_t *chr) { @@ -201,8 +205,11 @@ uint32_t tud_cdc_n_write(uint8_t itf, const void* buffer, uint32_t bufsize) { uint32_t tud_cdc_n_write_flush(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_CDC, 0); + TUD_SYSVIEW_CALL(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_CDC_FLUSH); cdcd_interface_t *p_cdc = &_cdcd_itf[itf]; - return tu_edpt_stream_write_xfer(&p_cdc->tx_stream); + uint32_t const ret = tu_edpt_stream_write_xfer(&p_cdc->tx_stream); + TUD_SYSVIEW_RET(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_CDC_FLUSH); + return ret; } uint32_t tud_cdc_n_write_available(uint8_t itf) { diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 8485105e4..537dd3810 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -12,6 +12,7 @@ #include "device/dcd.h" // for faking dcd_event_xfer_complete #include "device/usbd.h" #include "device/usbd_pvt.h" +#include "common/tusb_sysview.h" #include "msc_device.h" @@ -450,8 +451,21 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t return true; } +// mscd_xfer_cb() has several early-return paths (TU_ASSERT) spread across its +// SCSI stage switch. Each uses TU_ASSERT_SV below (if (!cond) { TU_MESS_FAILED(); +// TU_BREAKPOINT(); TUD_SYSVIEW_RET(...); return false; }, matching TU_ASSERT's +// own expansion with a RET inserted) so the CALL/RET pair stays balanced on +// every exit path without changing the function's shape -- an earlier version +// that instead wrapped a separate static impl function measured 4 bytes +// smaller in a SYSVIEW-off build than the pre-instrumentation baseline (the +// split itself perturbed codegen, even though every inserted macro compiles to +// nothing when disabled); this in-place form was verified byte-identical. +#define TU_ASSERT_SV(_cond) \ + TUD_SYSVIEW_ASSERT(_cond, CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_MSC_XFER, false) + bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) { (void) event; + TUD_SYSVIEW_CALL(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_MSC_XFER); mscd_interface_t* p_msc = &_mscd_itf; msc_cbw_t * p_cbw = &p_msc->cbw; @@ -462,6 +476,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t //------------- new CBW received -------------// // Complete IN while waiting for CMD is usually Status of previous SCSI op, ignore it if (ep_addr != p_msc->ep_out) { + TUD_SYSVIEW_RET(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_MSC_XFER); return true; } @@ -473,6 +488,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t p_msc->stage = MSC_STAGE_NEED_RESET; usbd_edpt_stall(rhport, p_msc->ep_in); usbd_edpt_stall(rhport, p_msc->ep_out); + TUD_SYSVIEW_RET(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_MSC_XFER); return false; } @@ -518,7 +534,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { // Didn't check for case 9 (Ho > Dn), which requires examining scsi command first // but it is OK to just receive data then responded with failed status - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); + TU_ASSERT_SV(usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } else { // First process if it is a built-in commands @@ -551,7 +567,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } else { // cannot return more than host expect p_msc->total_len = tu_min32((uint32_t)resplen, p_cbw->total_bytes); - TU_ASSERT(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); + TU_ASSERT_SV(usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_epbuf.buf, (uint16_t) p_msc->total_len, false)); } } } @@ -561,7 +577,8 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t case MSC_STAGE_DATA: TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun); - TU_ASSERT(xferred_bytes <= CFG_TUD_MSC_EP_BUFSIZE); // sanity check to avoid buffer overflow + // sanity check to avoid buffer overflow + TU_ASSERT_SV(xferred_bytes <= CFG_TUD_MSC_EP_BUFSIZE); // TU_LOG_MEM(CFG_TUD_MSC_LOG_LEVEL, _mscd_epbuf.buf, xferred_bytes, 2); if (SCSI_CMD_READ_10 == p_cbw->command[0]) { @@ -629,7 +646,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } if (!usbd_edpt_stalled(rhport, p_msc->ep_out)) { - TU_ASSERT(prepare_cbw(p_msc)); + TU_ASSERT_SV(prepare_cbw(p_msc)); } else { p_msc->stage = MSC_STAGE_CMD; } @@ -643,11 +660,13 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } if (p_msc->stage == MSC_STAGE_STATUS) { - TU_ASSERT(proc_stage_status(p_msc)); + TU_ASSERT_SV(proc_stage_status(p_msc)); } + TUD_SYSVIEW_RET(CFG_TUSB_SYSVIEW_LEVEL_CLASS, TU_SV_ID_MSC_XFER); return true; } +#undef TU_ASSERT_SV // file-local to mscd_xfer_cb above -- don't let it bind the wrong level/id later /*------------------------------------------------------------------*/ /* SCSI Command Process |
