common: Support reading profiling data via USB debug.

Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
This commit is contained in:
iabdalkader 2025-08-17 13:36:36 +02:00
parent e5cdccc72e
commit 872735212f
2 changed files with 99 additions and 16 deletions

View File

@ -57,7 +57,6 @@ extern uint32_t usb_cdc_buf_len();
extern uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len); extern uint32_t usb_cdc_get_buf(uint8_t *buf, uint32_t len);
extern void usb_cdc_reset_buffers(void); extern void usb_cdc_reset_buffers(void);
void usbdbg_init() { void usbdbg_init() {
cmd = USBDBG_NONE; cmd = USBDBG_NONE;
script_ready = false; script_ready = false;
@ -67,6 +66,9 @@ void usbdbg_init() {
#if OMV_TUSBDBG_ENABLE #if OMV_TUSBDBG_ENABLE
tinyusb_debug_init(); tinyusb_debug_init();
#endif #endif
#if OMV_PROFILER_ENABLE
omv_profiler_init();
#endif
} }
bool usbdbg_script_ready() { bool usbdbg_script_ready() {
@ -166,7 +168,7 @@ void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback) {
// Return 0 if FB is locked or not ready. // Return 0 if FB is locked or not ready.
uint32_t buffer[3] = { 0 }; uint32_t buffer[3] = { 0 };
// Try to lock FB. If header size == 0 frame is not ready // Try to lock FB. If header size == 0 frame is not ready
if (mutex_try_lock_fair(&JPEG_FB()->lock, MUTEX_TID_IDE)) { if (mutex_try_lock(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
// If header size == 0 frame is not ready // If header size == 0 frame is not ready
if (JPEG_FB()->size == 0) { if (JPEG_FB()->size == 0) {
// unlock FB // unlock FB
@ -231,15 +233,23 @@ void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback) {
// Set script running flag // Set script running flag
if (script_running) { if (script_running) {
buffer[0] |= USBDBG_STATE_FLAGS_SCRIPT; buffer[0] |= USBDBG_FLAG_SCRIPT_RUNNING;
} }
// Set text buf valid flag. // Set text buf valid flag.
uint32_t tx_buf_len = usb_cdc_buf_len(); uint32_t tx_buf_len = usb_cdc_buf_len();
if (tx_buf_len) { if (tx_buf_len) {
buffer[0] |= USBDBG_STATE_FLAGS_TEXT; buffer[0] |= USBDBG_FLAG_TEXTBUF_NOTEMPTY;
} }
// Set code profiling flags
#if OMV_PROFILER_ENABLE
buffer[0] |= USBDBG_FLAG_PROFILE_ENABLED;
#if __PMU_PRESENT
buffer[0] |= USBDBG_FLAG_PROFILE_HAS_PMU;
#endif // __PMU_PRESENT
#endif // OMV_PROFILER_ENABLE
// Limit the frames sent over USB to 20Hz. // Limit the frames sent over USB to 20Hz.
if (check_timeout_ms(last_update_ms, 50) && if (check_timeout_ms(last_update_ms, 50) &&
mutex_try_lock_fair(&JPEG_FB()->lock, MUTEX_TID_IDE)) { mutex_try_lock_fair(&JPEG_FB()->lock, MUTEX_TID_IDE)) {
@ -249,7 +259,7 @@ void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback) {
mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE); mutex_unlock(&JPEG_FB()->lock, MUTEX_TID_IDE);
} else { } else {
// Set valid frame flag. // Set valid frame flag.
buffer[0] |= USBDBG_STATE_FLAGS_FRAME; buffer[0] |= USBDBG_FLAG_FRAMEBUF_LOCKED;
// Set frame width, height and size/bpp // Set frame width, height and size/bpp
buffer[1] = JPEG_FB()->w; buffer[1] = JPEG_FB()->w;
@ -272,6 +282,40 @@ void usbdbg_data_in(uint32_t size, usbdbg_write_callback_t write_callback) {
break; break;
} }
case USBDBG_PROFILE_SIZE: {
// Return 0 if the profiling data is locked.
uint32_t buffer[3] = { 0 };
#if OMV_PROFILER_ENABLE
if (mutex_try_lock(omv_profiler_lock(), MUTEX_TID_IDE)) {
size_t count = 0;
(void) omv_profiler_get_data(&count);
buffer[0] = count;
buffer[1] = sizeof(omv_profiler_data_t);
buffer[2] = __PMU_NUM_EVENTCNT;
}
#endif
cmd = USBDBG_NONE;
write_callback(&buffer, sizeof(buffer));
break;
}
#if OMV_PROFILER_ENABLE
case USBDBG_PROFILE_DUMP:
if (xfer_offs < xfer_size) {
size_t count = 0;
char *data = omv_profiler_get_data(&count);
write_callback(data + xfer_offs, size);
xfer_offs += size;
if (xfer_offs == xfer_size) {
cmd = USBDBG_NONE;
mutex_unlock(omv_profiler_lock(), MUTEX_TID_IDE);
}
}
break;
#endif
default: /* error */ default: /* error */
break; break;
} }
@ -310,6 +354,26 @@ void usbdbg_data_out(uint32_t size, usbdbg_read_callback_t read_callback) {
} }
break; break;
case USBDBG_PROFILE_MODE: {
uint32_t buffer[1];
read_callback(&buffer, sizeof(buffer));
#if OMV_PROFILER_ENABLE
omv_profiler_set_mode(buffer[0]);
#endif
cmd = USBDBG_NONE;
break;
}
case USBDBG_PROFILE_EVENT: {
uint32_t buffer[2];
read_callback(&buffer, sizeof(buffer));
#if OMV_PROFILER_ENABLE
omv_profiler_set_event(buffer[0], buffer[1]);
#endif
cmd = USBDBG_NONE;
break;
}
default: /* error */ default: /* error */
break; break;
} }
@ -327,17 +391,29 @@ void usbdbg_control(void *buffer, uint8_t request, uint32_t size) {
case USBDBG_TX_BUF_LEN: case USBDBG_TX_BUF_LEN:
case USBDBG_SENSOR_ID: case USBDBG_SENSOR_ID:
case USBDBG_GET_STATE: case USBDBG_GET_STATE:
xfer_offs = 0; case USBDBG_PROFILE_SIZE:
xfer_size = size; case USBDBG_PROFILE_DUMP:
break; case USBDBG_PROFILE_MODE:
case USBDBG_PROFILE_EVENT:
case USBDBG_SCRIPT_RUNNING:
vstr_reset(&script_buf);
case USBDBG_SCRIPT_EXEC: case USBDBG_SCRIPT_EXEC:
xfer_offs = 0; xfer_offs = 0;
xfer_size = size; xfer_size = size;
break; break;
case USBDBG_PROFILE_RESET: {
#if OMV_PROFILER_ENABLE
omv_profiler_reset();
#endif
cmd = USBDBG_NONE;
break;
}
case USBDBG_SCRIPT_RUNNING:
vstr_reset(&script_buf);
xfer_offs = 0;
xfer_size = size;
break;
case USBDBG_SCRIPT_STOP: case USBDBG_SCRIPT_STOP:
if (script_running) { if (script_running) {
// Reset CDC buffers. // Reset CDC buffers.

View File

@ -61,13 +61,20 @@ enum usbdbg_cmd {
USBDBG_TX_BUF = 0x8F, USBDBG_TX_BUF = 0x8F,
USBDBG_SENSOR_ID = 0x90, USBDBG_SENSOR_ID = 0x90,
USBDBG_GET_STATE = 0x93, USBDBG_GET_STATE = 0x93,
USBDBG_PROFILE_SIZE = 0x94,
USBDBG_PROFILE_DUMP = 0x95,
USBDBG_PROFILE_MODE = 0x16,
USBDBG_PROFILE_EVENT = 0x17,
USBDBG_PROFILE_RESET = 0x18,
}; };
enum usbdbg_state_flags { typedef enum {
USBDBG_STATE_FLAGS_SCRIPT = (1 << 0), USBDBG_FLAG_SCRIPT_RUNNING = (1 << 0),
USBDBG_STATE_FLAGS_TEXT = (1 << 1), USBDBG_FLAG_TEXTBUF_NOTEMPTY = (1 << 1),
USBDBG_STATE_FLAGS_FRAME = (1 << 2), USBDBG_FLAG_FRAMEBUF_LOCKED = (1 << 2),
}; USBDBG_FLAG_PROFILE_ENABLED = (1 << 3),
USBDBG_FLAG_PROFILE_HAS_PMU = (1 << 4),
} usbdbg_flags_t;
typedef uint32_t (*usbdbg_read_callback_t) (void *buf, uint32_t len); typedef uint32_t (*usbdbg_read_callback_t) (void *buf, uint32_t len);
typedef uint32_t (*usbdbg_write_callback_t) (const void *buf, uint32_t len); typedef uint32_t (*usbdbg_write_callback_t) (const void *buf, uint32_t len);