Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/debug_stream_overlay.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Enable debug-stream protocol
CONFIG_SOF_DEBUG_STREAM_SLOT=y
# Enable text message sending with ds_msg()
CONFIG_SOF_DEBUG_STREAM_TEXT_MSG=y
# Add thread_info-client for debug stream
CONFIG_SOF_DEBUG_STREAM_THREAD_INFO=y
# Zephyr option for storing human readable thread names
Expand Down
2 changes: 2 additions & 0 deletions src/debug/debug_stream/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_SLOT sof debug_stream_slot.c)

add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_THREAD_INFO sof debug_stream_thread_info.c)

add_local_sources_ifdef(CONFIG_SOF_DEBUG_STREAM_TEXT_MSG sof debug_stream_text_msg.c)
12 changes: 11 additions & 1 deletion src/debug/debug_stream/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ config SOF_DEBUG_STREAM_SLOT
information from SOF system that are streamed from SOF DSP
to the host side for decoding and presentation. This option
enables transferring the records from DSP to host over a
debug window slot.
debug window slot. To extract the debugstream see
tools/debug_stream/debug_stream.py.

if SOF_DEBUG_STREAM_SLOT

Expand Down Expand Up @@ -44,4 +45,13 @@ config SOF_DEBUG_STREAM_THREAD_INFO_INTERVAL
Decides how often thread info runs and checks execution cycle
statistics and stack usage.

config SOF_DEBUG_STREAM_TEXT_MSG
bool "Enable text message sending through Debug-Stream"
help
Enable debug message sending over debug stream. To use this
feature one only needs to enable debug stream with this
config option and print the debug messages with
ds_msg(). See include/user/debug_stream_text_msg.h for
prototype.

endif
37 changes: 37 additions & 0 deletions src/debug/debug_stream/debug_stream_text_msg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2024 Intel Corporation.

#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#include <soc.h>
#include <adsp_debug_window.h>
#include <sof/common.h>

#include <user/debug_stream_text_msg.h>

void ds_msg(const char *format, ...)
{
va_list args;
struct {
struct debug_stream_text_msg msg;
char text[128];
} __packed buf = { 0 };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, how does Python parse C structures - it probably assumes "normal" (default) packing, i.e. as if no __packed attribute was specified. Can you tell Python that the structure is packed?

Copy link
Contributor Author

@jsarha jsarha Dec 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, "_pack_ = 1" in Class(ctypes.Structure) does it. But in this context it does not really matter as the "struct debug_stream_text_msg" size is 32-bit aligned and what remains after that is all cosidered utf-8 encoded string.

ssize_t len;

va_start(args, format);
len = vsnprintf(buf.text, sizeof(buf.text), format, args);
va_end(args);

if (len < 0)
return;
len = MIN(len, sizeof(buf.text));

buf.msg.hdr.id = DEBUG_STREAM_RECORD_ID_TEXT_MSG;
buf.msg.hdr.size_words = SOF_DIV_ROUND_UP(sizeof(buf.msg) + len,
sizeof(buf.msg.hdr.data[0]));
debug_stream_slot_send_record(&buf.msg.hdr);
}
EXPORT_SYMBOL(ds_msg);

1 change: 1 addition & 0 deletions src/include/user/debug_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ struct debug_stream_record {
/* Debug Stream record identifiers */
#define DEBUG_STREAM_RECORD_ID_UNINITIALIZED 0 /* invalid record marker */
#define DEBUG_STREAM_RECORD_ID_THREAD_INFO 1 /* Thread info record */
#define DEBUG_STREAM_RECORD_ID_TEXT_MSG 2 /* Text message */

#endif /* __SOC_DEBUG_STREAM_H__ */
25 changes: 25 additions & 0 deletions src/include/user/debug_stream_text_msg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2024 Intel Corporation.
*/

#ifndef __SOC_DEBUG_STREAM_TEXT_MSG_H__
#define __SOC_DEBUG_STREAM_TEXT_MSG_H__

#include <user/debug_stream_slot.h>

/*
* Debug Stream text message.
*/
struct debug_stream_text_msg {
struct debug_stream_record hdr;
char msg[];
} __packed;

/*
* To send debug messages over debug stream. Enable
* CONFIG_SOF_DEBUG_STREAM_TEXT_MSG to enable this function.
*/
void ds_msg(const char *format, ...);

#endif /* __SOC_DEBUG_STREAM_TEXT_MSG_H__ */
28 changes: 26 additions & 2 deletions tools/debug_stream/debug_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class DebugStreamRecord(ctypes.Structure):
("size_words", ctypes.c_uint),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in commit: sd_msg->ds_msg

]


class CPUInfo(ctypes.Structure):
"""
Thread Info record header
Expand All @@ -73,6 +72,17 @@ class ThreadInfo(ctypes.Structure):
]


class TextMsg(ctypes.Structure):
"""
Text Msg record header
"""

_pack_ = 1
_fields_ = [
("hdr", DebugStreamRecord),
]


WSIZE = ctypes.sizeof(ctypes.c_uint)


Expand All @@ -83,6 +93,7 @@ class RecordPrinter:

RECORD_ID_UNINITIALIZED = 0
RECORD_ID_THREAD_INFO = 1
RECORD_ID_TEXT_MSG = 2

def print_record(self, record, cpu):
"""prints debug-stream record"""
Expand All @@ -92,7 +103,9 @@ def print_record(self, record, cpu):
)
if recp.contents.id == self.RECORD_ID_THREAD_INFO:
return self.print_thread_info(record, cpu)
logging.warning("cpu %u: Unsupported recodrd type %u", cpu, recp.contents.id)
if recp.contents.id == self.RECORD_ID_TEXT_MSG:
return self.print_text_msg(record, cpu)
logging.warning("cpu %u: Unsupported record type %u", cpu, recp.contents.id)
return True

def print_thread_info(self, record, cpu):
Expand Down Expand Up @@ -141,6 +154,17 @@ def print_thread_info(self, record, cpu):
)
return True

def print_text_msg(self, record, cpu):
"""prints text-msg record"""
if len(record) - ctypes.sizeof(TextMsg) < 0:
logging.info("Buffer end reached, parsing failed")
return False
buffer = (
ctypes.c_ubyte * (len(record) - ctypes.sizeof(TextMsg))
).from_address(ctypes.addressof(record) + ctypes.sizeof(TextMsg))
msg = bytearray(buffer).decode("utf-8")
print("CPU %u: %s" % (cpu, msg))
return True

class DebugStreamSectionDescriptor(ctypes.Structure):
"""
Expand Down
Loading