summaryrefslogtreecommitdiff
path: root/src/class
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-08-11 17:07:23 +0700
committerhathach <[email protected]>2026-09-04 04:21:57 +0700
commit3baa7c8fbafd2cbccc5810626ebbfaa50c0ea4da (patch)
tree690704b3d82dff418ceeaf14e8d6f8ff41d16a2f /src/class
parent4161a1cf63c5ca935766d27bd32f7dd3948e881a (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.c11
-rw-r--r--src/class/msc/msc_device.c29
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