- Experience in reading and understanding datasheets to produce driver code for a given device based on the information contained in its documentation

- A good understanding of microprocessor internals (mostly the registers).

- An excellent knowledge of what interrupts are and how they work in code

- An understanding of memory regions, and their uses (heap, stack, IVT, code).

- An understanding of the different kinds of memory (RAM, ROM, Flash, NVRAM), the differences between them and how they are read, written, accessed.

- A good understanding of DMA (Direct Memory Access), and how to implement it for systems which have DMA capability

Software :

- Experience with hexadecimal numbers, hexadecimal math and a very good understanding of Boolean logical operations

- Experience with multi-tasking systems and how to debug them

- Ability to use a debugger to perform at least simple operations such as setting breakpoints, single stepping mode, examining variable values, examining memory, examining registers - and understanding then when to enable and disable interrupts if performing single stepping using a debugger

- How to develop and debug code for peripherals such as UARTs, A/D & D/A converters, timers, PWM generation from a timer, real-time clocks, etc.

- How to develop and debug code for communications using RS-485 (and its variants), SPI, I2C, and parallel data ports.

Software design :

- Experience on embedded application design based on its requirements, example choosing between using a foreground loop with interrupts vs. using a multi-tasking kernel

- Developing code to run under an RTOS (Real Time Operating System), and how to use semaphores, mutexes, queues, inter-task communications

- How to develop and debug code with stacks, queues, linked-lists, and other common data constructs.