- Understanding how to write purely event-based programs using e.g. epoll since that will avoid lots of complexity and potential problems compared to throwing threads at everything.
- Floating point representation and gotchas ("What Every Computer Scientist Should Know About Floating-Point").
- Unit-testing as part of designing interfaces to get low coupling, sane ergonomics, and forcing some thought to error handling instead of just working in the happy-path case.
- Interrupt- and thread-safety (races, mutexes, deadlocks, orderings etc.)
- Storing state in maintainable ways (i.e. not just dumping C-structs to disk).
- Understanding basic computer architecture concepts like virtual memory, caches, and pipelines.
- Know what can be achieved with OpenMP and GPU programming using OpenCL/CUDA etc.
- Write great commit messages (What is the problem being solved, why this way, etc.)
- Basics of database and distributed systems theory like ACID properties and Lamport timestamps.
- Using regular expressions instead of lots of a complicated set of if-statements.
- Understanding networks regarding error sources and latencies.
With that being said, your list of things to know are all things I have to know for my job (these are things almost all programmers should know, in fact) and I would not consider myself a low-level or systems programmer, just an application programmer.
This takes in the definition of a regular language as a set of regular expressions, and generates C code for finite state machine to parse the language. You can visualise the state machine in Graphviz to manually verify all paths, making it much easier to spot hidden corner cases, while being a lot quicker to code than a big pile of if statements.
The other points are solid, although I have to admit I have never used regular expressions on a microcontroller
And I would also add fuzz-testing to your list.
But then someone has a bright idea that e.g. a global cache to share some state between all threads would be a good optimization, or that threads need to be able to store some global settings, etc. and complexity related to threads start to creep in to your application.