Embedded System Interview Questions (4)

Aug 2, 2021


Here is some basic Linux knowledge followed by some generic questions.


  • Linux commands

There are some very useful ones and check man for usage.

  • What are different types of shell and why bash?

Bourne shell (sh), C shell (csh), TC shell (tcsh), Korn shell (ksh), Bourne Again SHell (bash)

Bash provides all the interactive features of the C shell (csh) and the Korn shell (ksh). Its programming language is compatible with the Bourne shell (sh).

  • POSIX API. How are Pthreads different from RTOS threads?

The Portable Operating System Interface (POSIX) is a family of standards specified by the IEEE Computer Society for maintaining compatibility between operating systems.

RTOS is complete mini OS kernel for embedded systems with priority-based task scheduler as opposed to Pthread which is mainly a POSIX compliant thread library which has functions to create tasks, join tasks, delete tasks, and synchronize the tasks.

  • Questions from your project. How did you connect that particular sensor to the board? Any protocol? Clock frequency of the used controller? pinouts of the sensors?

  • Why did you choose that controller for your project and why not the other one?

  • How will you debug a program?

  • What to do if your software in the MCU hangs?

  • Use of JTAG?

  • In-System Programming?

  • How do you use Oscilloscope, Logic Analyzer, Spectrum Analyzer, CAN analyzer?

  • Difference between a BIOS and UEFI boot process?

UEFI stands for Unified Extensible Firmware Interface. It does the same job as a BIOS, but with one basic difference: it stores all data about initialization and startup in a *.efi file, instead of storing it on the firmware.

  • Difference between a PC Boot and Smartphone boot?

On x86 BIOS based platforms, the BIOS reads the master boot record from the boot device defined in CMOS, then loads the stage 1 bootloader from the MBR, which loads the stage 2 bootloader code (depends on bootloader type). The bootloader then loads the OS kernel into ram from the disk, and begins executing it.

For x86 UEFI based platforms, the UEFI reads the system partition contents from the boot device defined in NVRAM, then loads the boot image found. On UEFI systems, this may either be your OS’s kernel itself, or an intermediate stage 2 bootloader, depending on the OS in question. The bootloader then loads the OS kernel into ram from the disk, and begins executing it.

On ARM platforms, typically it executes the bootloader (commonly U-Boot) from a well-defined position on the flash (location varies by manufacturer and is controlled by the SoC rom), which loads and executes the kernel image, which is more or less always stored raw on the flash device.

  • Writing portable code in C.

See below for a common practice.

  • How do you make inline assembly code in C?

See below for an example. You can also add keyword "volatile" between asm and the left parenthesis to prevent compiler from removing it during optimization.

  • Explain how shared memory works? (A good candidate will know details like why pointers are stored as offsets and how to protect memory regions using semaphores)

When using shared memory, each process may mmap the shared region into a different area of its respective address space. This means that when storing pointers within the shared region, you need to store them as offsets of the start of the shared region. Otherwise, the pointer will only be valid for one process.

When using shared memory, processes map the same area of memory into their address space. This allows for fast inter-process communication because the data is immediately available to any other process using the same shared memory. If your application has multiple processes contending for the same shared-memory resource, you must coordinate access. Semaphores provide an easy means of regulating access to a memory object and determining if the memory resource is available.

  • What happens on a system call? (A good answer will include a description of processor interrupts and how the hardware handles them, scheduling decisions, marshaling parameters, etc. For embedded programmers a question dealing with concurrent operations can be substituted)

When a user program invokes a system call, a system call instruction is executed, which causes the processor to begin executing the system call handler in the kernel protection domain.

This system call handler performs the following actions: (1) Sets the ut_error field in the uthread structure to 0. (2) Switches to a kernel stack associated with the calling thread. (3) Calls the function that implements the requested system call.

The system loader maintains a table of the functions that are used for each system call. After the function implementing the system call has performed the requested action, control returns to the system call handler. If the ut_error field in the uthread structure has a non-zero value, the value is copied to the application's thread-specific errno variable. If a signal is pending, signal processing take place, which can result in an application's signal handler being invoked. If no signals are pending, the system call handler restores the state of the calling thread, which is resumed in the user protection domain.

  • How would you read in a string of unknown length without risking buffer overflow?

One idea is to binary search the length.