Jason

embedded systems!

2025-06-09

@cliffle Did you ever get to the root of the STM32 WFI bug?

I personally found myself performing the following step to alleviate it: (1) I made the idle thread run in privileged mode*, (2) masked interrupts before wfi, and (3) inserted various memory barrier instructions before and after (only before is required so far as I can tell)

*I first tried to execute masked WFI from a svc instruction / syscall - not realizing that was not possible

2025-05-19

@cliffle I'm reluctant to consume too much of your time and attention. But if you feel curious enough and express continued interest, I'd be happy to share a somewhat redacted sketch of the system

Every question is mostly aimed at learning about your intent when you architected the OS. Design intent is everything

Your responses have been very helpful in guiding me / allowing me to make informed compromises in the name of speed, power use, ease of IRQ/driver <-> task communication, ease of test

2025-05-19

@cliffle In Hubris, have you ever run into a situation where you wanted a non-blocking SEND ipc call?

Looking at the source it looks as if the stock SEND ipc call might not handle (ie. fault the caller) the cases where the callee thread is not running or has a closed receive.

2025-05-15

@cliffle curious about your opinion on locating panic buffers in userspace program's userlib versus having a shared panic buffer in the kernel.

I suppose one is potentially a lot simpler and more flexible than the other.

Not super familiar with how the Jefe and the task dumper work - I assume the per program buffer is ideal for core dump based debugging. (I've been doing strictly UART based panic/hardfault messages up till this point)

2025-05-13

@cliffle The shape is: one shared UART sever, one shared Flash
server. (chip erase takes a long time, so does copying into uart DMA buffer, and I don't more complexity in servers)

+ A high priority real-time sensitive task, and a bunch of low priority tasks.

A workaround is to write "polling/redirecting" clients and servers.

I did that by hand for a while, and it wasn't great. (I decided that they would have to be autogenerated which would have been more complicated than the custom syscall)

2025-05-12

@cliffle I've got a syscall I added out of desperation - I dynamically change the priority of a certain high priority task to allow it to talk to a lower priority task. It then raises back up when it is done.*

I would like to get your feeling on whether or not this might break something in the kernel. (I know, it's difficult to say)

AFAICT, it seems to not violate too many assumptions if used carefully.

*(specifically: real time speed sensitive task talks to slow shared flash memory server.)

2025-05-09

@cliffle I see your commit that adds the ability to get the name of a task.

That is greatly appreciated.

I've got a custom syscall+notification that generates a string describing the last panic/hardfault. It allows my UART driver task to print information about faults.

I imagine this will make things easier to debug.

2025-05-05

@cliffle Part 3: forgot to mention that kernel ISRs do have acceptable latency.

It's the kernel -> usermode transitions / task switching / syscall transitions / etc. that seems to delay our high priority C library task more than we would like.

Stuff like GPIO and SPI often ends up getting put directly into threads like C library task for speed.

Nothing that can be done about IPC speed I think. We are running the CPU slow for power reasons. And are using Cortex-M0+ since it is cheap,

2025-05-05

@cliffle Part 2: Running at 16MHz on Cortex-M0+ 10yr battery life radio modem.

Have a "fun" external C library that doesn't like being interrupted/delayed by more than 1ms (16k CPU cycles) per second.

Find that single sys/IPC calls last >5k CPU cycles peak.

Interesting syscalls deal with sleep/wake

Idle thread needs to run a critical section in privileged mode for clock setup/teardown/wake/sleep

Also have to deal with timers/scheduling wakeup/getting the time/etc. due to CPU sleep/battery

2025-05-05

@cliffle Part 1: We are using Oxide Hubris+Humility (was hard to get running with a new micro due to old probe-rs + libraries yanked due to security issues, repos without Cargo.lock files that can't be built without tricking cargo)

Didn't know about extern. But I tried something similar by defining a fake peripheral. Keep running out of memory regions due to constraints described in part 2

Boring syscalls register pointers to buffers in task RAM for DMA drivers.

Interesting syscalls in part 2

2025-05-05

@cliffle Third question to get around 500 character reply limit.

It's hard to look up a task from the kernel/ISR handlers. I end up looping through the task table as looking for the task with a certain hard-coded priority in order to write driver/IRQ/etc. data into the desired task's memory

Was wondering if not having an ergonomic interface for grabbing tasks by some handle/name/constant/etc was an intentional design choice to limit misbehavior (doing things the wrong way) by users/developers?

2025-05-05

@cliffle Awesome! I was afraid to bother you.

I'm using Hubris for a battery powered product with real-time constraints. I find myself implementing fast drivers/ISRs in the kernel (app/../src/main.rs and also as custom syscalls) where I need to send a slices of data from the kernel to a task and vice-versa. I tried several approaches and ended up settling for sending notifications from the kernel and writing directly into task memory.

Was wondering if & how you intended this to be done?

2025-05-05

@cliffle In Hubris OS, it looks like 7 of the 8 memory protection regions are allocated to flash/ram/peripherals/etc. I am not sure what the 8th is used for.

is the 8th memory protection region dedicated to stack protection or something?

Client Info

Server: https://mastodon.social
Version: 2025.04
Repository: https://github.com/cyevgeniy/lmst