Skip to content

Commit 5ef8097

Browse files
committed
zephyr: work: Support showing work in Segger SystemView
If `CONFIG_SEGGER_SYSVIEW` is enabled, add a few calls to the workqueue scheduling to record these as task switches. There is still a problem with the task names showing up, but this does generally show scheduled work as separate tasks in System View. The main issues where this lacks is that if the Zephyr scheduler schedules something else, and then returns to the work queue, that will be shown as being done on the work queue thread instead of the particular work. Signed-off-by: David Brown <[email protected]>
1 parent 25355e8 commit 5ef8097

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

zephyr-sys/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ fn main() -> Result<()> {
8888
.allowlist_function("sys_.*")
8989
.allowlist_function("z_log.*")
9090
.allowlist_function("bt_.*")
91+
.allowlist_function("SEGGER.*")
9192
.allowlist_item("E.*")
9293
.allowlist_item("K_.*")
9394
.allowlist_item("ZR_.*")

zephyr/src/work/futures.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,23 @@ impl<F: Future> WorkData<F> {
384384
unsafe {
385385
// SAFETY: The above Arc allocates the worker. The code here is careful to not move it.
386386
k_work_poll_init(this.work.get(), Some(Self::handler));
387+
388+
// If we have a name, send it to Segger.
389+
#[cfg(CONFIG_SEGGER_SYSTEMVIEW)]
390+
{
391+
let ww = &(&*this.work.get()).work;
392+
if let Some(name) = name {
393+
let info = crate::raw::SEGGER_SYSVIEW_TASKINFO {
394+
TaskID: this.work.get() as ::core::ffi::c_ulong,
395+
sName: name.as_ptr(),
396+
Prio: 1,
397+
StackBase: 0,
398+
StackSize: 32,
399+
};
400+
crate::raw::SEGGER_SYSVIEW_OnTaskCreate(this.work.get() as ::core::ffi::c_ulong);
401+
crate::raw::SEGGER_SYSVIEW_SendTaskInfo(&info);
402+
}
403+
}
387404
}
388405

389406
this
@@ -458,8 +475,16 @@ impl<F: Future> WorkData<F> {
458475
// SAFETY: poll requires the pointer to be pinned, in case that is needed. We rely on the
459476
// Boxing of the pointer, and that our code does not move the future.
460477
let future = unsafe { Pin::new_unchecked(&mut this_ref.future) };
478+
#[cfg(CONFIG_SEGGER_SYSTEMVIEW)]
479+
unsafe {
480+
crate::raw::SEGGER_SYSVIEW_OnTaskStartExec(work as u32);
481+
}
461482
match future.poll(&mut this_ref.info.context) {
462483
Poll::Pending => {
484+
#[cfg(CONFIG_SEGGER_SYSTEMVIEW)]
485+
unsafe {
486+
crate::raw::SEGGER_SYSVIEW_OnTaskStopExec();
487+
}
463488
// With pending, use the timeout and events to schedule ourselves to do more work.
464489
// TODO: If we want to support a real Waker, this would need to detect that, and
465490
// schedule a possible wake on this no wake case.
@@ -473,6 +498,11 @@ impl<F: Future> WorkData<F> {
473498
Self::submit(this).expect("Unable to schedule work");
474499
}
475500
Poll::Ready(answer) => {
501+
#[cfg(CONFIG_SEGGER_SYSTEMVIEW)]
502+
unsafe {
503+
crate::raw::SEGGER_SYSVIEW_OnTaskStopExec();
504+
}
505+
// TODO: Delete the task as well.
476506
// If the spawning task is still interested in the answer, provide it.
477507
if let Some(store) = this.answer.upgrade() {
478508
store.place(answer);

0 commit comments

Comments
 (0)