SlideShare a Scribd company logo
1 of 130
Q) What is the difference between C and embedded C?
The C standard doesn’t care about embedded, but vendors of embedded systems usually provide standalone implementations with
whatever amount of libraries they’re willing to provide.
C is a widely-used general-purpose high-level programming language mainly intended for system programming. On the other side,
Embedded C is an extension to the C programming language that provides support for developing efficient programs for embedded
devices. It is not a part of the C language.
Following are the comparison chart for traditional C language and Embedded C:
C Language Embedded C Language
C is a widely-used general-purpose high-level
programming language.
It is used for cross-development purposes
C is a high-level programming language. It maintains by
the C standard committee. The C standard doesn’t care
about embedded.
Embedded C is an extension to the C programming language
that provides support for developing efficient programs for
embedded devices.
C is independent of hardware and its underlying
architecture.
Embedded C is dependent on the hardware architecture.
C is mainly used for developing desktop applications.
Mainly intended for system programming.
Embedded C is used in embedded systems for
microcontroller-based applications.
Q) What is the volatile keyword?
The volatile keyword is a type qualifier that prevents the objects from compiler optimization. According to C standard, an object that
has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. You can
also say that the value of the volatile-qualified object can be changed at any time without any action being taken by the code. If an
object is qualified by the volatile qualifier, the compiler reloads the value from memory each time it is accessed by the program that
means it prevents from cache a variable into a register. Reading the value from memory is the only way to check the unpredictable
change of the value.
Q) What is the use of volatile keyword?
The volatile keyword is mainly used where we directly deal with GPIO, interrupt or flag Register. It is also used with a global
variable or buffer which shared between the threads.
Q) What is the difference between the const and volatile qualifiers in C?
The const keyword is compiler-enforced and says that the program could not change the value of the object that means it makes the
object nonmodifiable type. Let us see an example,
const int a = 0;
If we will try to modify the value of “a”, we will get the compiler error because “a” is qualified with const keyword that prevents to
change the value of the”a” (integer variable).
Another side, volatile prevents any compiler optimization and says that the value of the object can be changed by something that is
beyond the control of the program and so that compiler will not make any assumption about the object. Let see an example,
volatile int a;
When the compiler sees the above declaration then it avoids to make any assumption regarding the “a” and in every iteration read the
value from the address which is assigned to the “a”.
Q) Can a variable be both constant and volatile in C?
Yes, we can use both constant and volatile together. One of the great use of volatile and const keyword together is at the time
of accessing the GPIO registers. In the case of GPIO, its value will be changed by the ‘external factors’ (if a switch or any output
device is attached with GPIO), if it is configured as an input. In that situation, volatile plays an important role and ensures that the
compiler always read the value from the GPIO address and avoid to make any assumption.
After using the volatile keyword, you will get the proper value whenever you are accessing the ports but still here is one more
problem because the pointer is not const type so it might be your program change the pointing address of the pointer. So we have to
create a constant pointer with a volatile keyword.
Syntax of declaration,
int volatile * const PortRegister;
How to read the above declaration,
Q) Can we have a volatile pointer?
Yes, we can create a volatile pointer in C language.
// piData is a volatile pointer to an integer.
int * volatile piData;
Q) The Proper place to use the volatile keyword?
A volatile is an important qualifier in C programming. Here I am pointing some places where we need to use the volatile keyword.
 Accessing the memory-mapped peripherals register or hardware status register.
#define COM_STATUS_BIT 0x00000006
uint32_t const volatile * const pStatusReg = (uint32_t*)0x00020000;
unit32_t GetRecvData()
{
unit32_t RecvData;
//Code to receive data
while (((*pStatusReg) & COM_STATUS_BIT) == 0)
{
// Wait until flag does not set
//Received data in RecvData
}
return RecvData;
}
 Sharing the global variables or buffers between the multiple threads.
 Accessing the global variables in an interrupt routine or signal handler.
volatile int giFlag = 0;
ISR(void)
{
giFlag = 1;
}
int main(void)
{
while (!giFlag)
{
//do some work
}
return 0;
}
Q) What is ISR?
An ISR refers to the Interrupt Service Routines. These are procedures stored at specific memory addresses which are called when a
certain type of interrupt occurs. The Cortex-M processors family has the NVIC that manages the execution of the interrupt.
Q) Can we pass any parameter and return a value from the ISR?
An ISR returns nothing and not allow to pass any parameter. An ISR is called when a hardware or software event occurs, it is not
called by the code, so that’s the reason no parameters are passed into an ISR.
In the above line, we have already read that the ISR is not called by the code, so there is no calling code to read the returned values of
the ISR. It is the reason that an ISR is not returned any value.
Q) What is interrupt latency?
Basically, interrupt latency is the number of clock cycles that are taken by the processor to respond to an interrupt request. This clock
cycle number is count between the assertions of the interrupt request and the first instruction of the interrupt handler.
Interrupt Latency on the Cortex-M processor family
The Cortex-M processors have very low interrupt latency. In the below table, I have mentioned, Interrupt latency of Cortex-M
processors with zero wait state memory systems.
Processors Cycles with zero wait state memory
Cortex-M0 16
Cortex-M0+ 15
Cortex-M3 12
Cortex-M4 12
Cortex-M7 12
Q) How do you measure interrupt latency?
With the help of the oscilloscope, we can measure the interrupt latency. You need to take the following steps.
 First takes two GPIOs.
 Configure one GPIO to generate the interrupt and second for the toggling (if you want you can attach an LED).
 Monitor the PIN (using the oscilloscope or analyzer) which you have configured to generate the interrupt.
 Also, monitor (using the oscilloscope or analyzer) the second pin which is toggled at the beginning of the interrupt
service routine.
 When you will generate the interrupt then the signal of both GPIOs will change.
The interval between the two signals (interrupt latency) may be easily read from the instrument.
Q) How to reduce interrupt latency?
The interrupt latency depends on many factors, some factors I am mentioning in the below statements.
 Platform and interrupt controller.
 CPU clock speed.
 Timer frequency
 Cache configuration.
 Application program.
So using the proper selection of platforms and processors we can easily reduce the interrupt latency. We can also reduce the interrupt
latency by making the ISR shorter and avoid to calling a function within the ISR.
Q) Is it safe to call printf() inside Interrupt Service Routine (ISR)?
It is not a good idea to call the printf() insider the ISR. The printf function is not reentrant, thread-safe.
Q) Can we put a breakpoint inside ISR?
Putting a breakpoint inside ISR is not a good idea.
Yes - in an emulator.
Otherwise, no. It's difficult to pull off, and a bad idea in any case. ISRs are (usually) supposed to work with the hardware, and
hardware can easily behave very differently when you leave a gap of half a second between each instruction. Set up some sort of
logging system instead.
ISRs also ungracefully "steal" the CPU from other processes, so many operating systems recommend keeping your ISRs extremely
short and doing only what is strictly necessary (such as dealing with any urgent hardware stuff, and scheduling a task that will deal
with the event properly). So in theory, ISRs should be so simple that they don't need to be debugged.
If it's hardware behavior that's the problem, use some sort of logging instead, as I've suggested. If the hardware doesn't really mind
long gaps of time between instructions, then you could just write most of the driver in user space - and you can use a debugger on
that!
Q) Explain the interrupt execution sequence?
An interrupt is an event that alters the sequence in which the processor executes instructions. An interrupt might be planned
(specifically requested by the currently running program) or unplanned (caused by an event that might or might not be related to the
currently running program).
Q) What is the difference between an uninitialized pointer and a null pointer?
Answer:
An uninitialized pointer is a pointer that points unknown memory location. The behavior of the uninitialized pointer is undefined. If
you try to dereference the uninitialized pointer code behavior will undefine.
According to C standard, an integer constant expression with the value 0, or such an expression cast to type void *, is called a null
pointer constant. The behavior of the uninitialized pointer is defined. When you try to dereference the null pointer then your code will
crash.
Q) What are the causes of Interrupt Latency?
 The first delay is typically caused by hardware: The interrupt request signal needs to be synchronized to the CPU
clock. Depending on the synchronization logic, up to 3 CPU cycles may expire before the interrupt request has
reached the CPU core.
 The CPU will typically complete the current instruction, which may take several cycles. On most systems, divide,
push-multiple or memory-copy instructions are the most time-consuming instructions to execute. On top of the
cycles required by the CPU, additional cycles are often required for memory accesses. In an ARM7 system, the
instruction STMDB SP!,{R0-R11, LR} typically is the worst-case instruction, storing 13 registers of 32-bits each to
the stack, and takes 15 clock cycles to complete.
 The memory system may require additional cycles for wait states.
 After completion of the current instruction, the CPU performs a mode switch or pushes registers on the stack
(typically PC and flag registers). Modern CPUs such as ARM generally perform a mode switch, which takes fewer
CPU cycles than saving registers.
 Pipeline fill: Most modern CPUs are pipelined. Execution of an instruction happens in various stages of the
pipeline. An instruction is executed when it has reached its final stage of the pipeline. Since the mode switch has
flushed the pipeline, a few extra cycles are required to refill the pipeline.
Q) Can we use any function inside ISR?
Yes, you can call a function within the ISR but it is not recommended because it can increase the interrupt latency and decrease the
performance of the system. If you want to call a nested function within the ISR, you need to read the datasheet of your
microcontroller because some vendors have a limit to how many calls can be nested.
One important point needs to remember the function that is called from the ISR should be re-entrant. If the called function is not re-
entrant, it could create issues.
For example,
If the function is not reentrant and supposes that it is called by another part of the code besides the ISR. So the problem will be
invoked when if the ISR calls the same function which is already invoked outside of the ISR?
Q) What is a nested interrupt?
In a nested interrupt system, an interrupt is allowed any time and anywhere even an ISR is executed. But, only the highest priority
ISR will be executed immediately. The second-highest priority ISR will be executed after the highest one is completed.
The rules of a nested interrupt system are:
 All interrupts must be prioritized.
 After initialization, any interrupts are allowed to occur anytime and anywhere.
 If a low-priority ISR is interrupted by a high-priority interrupt, the high-priority ISR is executed.
 If a high-priority ISR is interrupted by a low-priority interrupt, the high-priority ISR continues executing.
 The same priority ISRs must be executed by time order
If you want to learn STM32 from scratch, you should follow this course “Mastering Microcontroller with Embedded Driver
Development“. The course contains video lectures of 18.5-hours length covering all topics like, Microcontroller & Peripheral Driver
Development for STM32 GPIO, I2C, SPI, USART using Embedded C.
Q) What is NVIC in ARM Cortex?
The Nested Vector Interrupt Controller (NVIC) in the Cortex-M processor family is an example of an interrupt controller with
extremely flexible interrupt priority management. It enables programmable priority levels, automatic nested interrupt support, along
with support for multiple interrupt masking, whilst still being very easy to use by the programmer.
The Cortex-M3 and Cortex-M4 processors the NVIC supports up to 240 interrupt inputs, with 8 up to 256 programmable priority
levels
Q) Can we change the interrupt priority level of the Cortex-M processor family?
Yes. We can change the priority levels of the interrupts by changing the corresponding bit in the Interrupt Priority (IP) register as
shown in the following figure. A low priority interrupt can only be interrupted by the high priority interrupt, but not interrupted by
another low priority interrupt.
Q) Explain Interrupts tail-chaining – ARM?
Tail-chaining is the back-to-back processing of exceptions without the overhead of state saving and restoration between interrupts.
That means handling the pending interrupts without repeating the stacking. The processor tail-chains if a pending interrupt has higher
priority than all stacked exceptions. For more detail, you can read Cortex-Manual.
Q) Why is the “C” language mostly preferred over assembly language?
C helps programmers focus on the structure of the code rather than the low-level demands of the CPU. They can organize code into
components, such as functions and files and they have ways of managing the complexity of a project; without thinking about the
nitty-gritty of issues such as how function calls work.
Since C is a portable language, code can be organized into general-purpose libraries that can be used on any platform, often with no
modification. It is a great weapon against ‘reinventing the wheel.
Q) What is the start-up code?
A start-up code is called before the main function, it creates a basic platform for the application. It is a small block of code that is
written in assembly language.
There are the following parts of the start-up code.
 Declaration of the Stack area.
 Declaration of the Heap area.
 Vector table.
 Reset handler code.
 Other exception handler codes.
Q) What are the start-up code steps?
Start-up code for C programs usually consists of the following actions, performed in the order described:
 Disable all interrupts.
 Copy any initialized data from ROM to RAM.
 Zero the uninitialized data area.
 Allocate space for and initialize the stack.
 Initialize the processor’s stack pointer.
 Create and initialize the heap.
 Enable interrupts.
 Call main.
Q) Infinite loops often arise in embedded systems. How do you code an infinite loop in C?
In embedded systems, infinite loops are generally used. If I talked about a small program to control a led through the switch, in that
scenario an infinite loop will be required if we are not going through the interrupt.
There are different ways to create an infinite loop, here I am mentioning some methods.
Method 1:
while(1)
{
// task
}
Method 2:
for(;;)
{
// task
}
Method 3:
Loop:
goto Loop;
Q) How to access the fixed memory location in embedded C?
Let us see an example code to understand this concept. This question is one of the best questions of the embedded C interview
question.
Suppose in an application, you need to access a fixed memory address. So you need to follow the below steps, these are high-level
steps.
//Memory address, you want to access
#define RW_FLAG 0x1FFF7800
//Pointer to access the Memory address
volatile uint32_t *flagAddress = NULL;
//variable to stored the read value
uint32_t readData = 0;
//Assign addres to the pointer
flagAddress = (volatile uint32_t *)RW_FLAG;
//Read value from memory
* flagAddress = 12; // Write
//Write value to the memory
readData = * flagAddress;
Q) Difference between RISC and CISC processor?
The RISC (reduced instruction set computer) and CISC (Complex instruction set computer) are the processors ISA (instruction set
architecture).
There are the following difference between both architecture:
RISC CISC
Acronym It stands for ‘Reduced Instruction Set
Computer’.
It stands for ‘Complex Instruction Set
Computer’.
Definition The RISC processors have a smaller
set of instructions with few
addressing nodes.
The CISC processors have a larger set
of instructions with many addressing
nodes.
Memory unit It has no memory unit and uses a
separate hardware to implement
instructions.
It has a memory unit to implement
complex instructions.
Program It has a hard-wired unit of
programming.
It has a micro-programming unit.
Design It is a complex complier design. It is an easy complier design.
Calculations The calculations are faster and
precise.
The calculations are slow and precise.
Decoding Decoding of instructions is simple. Decoding of instructions is complex.
Time Execution time is very less. Execution time is very high.
External memory It does not require external memory
for calculations.
It requires external memory for
calculations.
Pipelining Pipelining does function correctly. Pipelining does not function correctly.
Stalling Stalling is mostly reduced in
processors.
The processors often stall.
Code expansion Code expansion can be a problem. Code expansion is not a problem.
Disc space The space is saved. The space is wasted.
Applications Used in high-end applications such as
video processing,
telecommunications and image
processing.
Used in low-end applications such as
security systems, home automations,
etc.
Q) What is the stack overflow?
If your program tries to access beyond the limit of the available stack memory then stack overflow occurs. In other words, you can
say that a stack overflow occurs if the call stack pointer exceeds the stack boundary.
If stack overflow occurs, the program can crash or you can say that segmentation fault that is the result of the stack overflow.
Q) What is the cause of the stack overflow?
In the embedded application we have a little amount of stack memory as compare to the desktop application. So we have to work on
embedded application very carefully either we can face the stack overflow issues that can be a cause of the application crash.
Here, I have mentioned some causes of unwanted use of the stack.
 Improper use of the recursive function.
 Passing to many arguments in the function.
 Passing a structure directly into a function.
 Nested function calls.
 Creating a huge size local array.
Q) What is the difference between the I2c and SPI communication Protocols?
In the embedded system, I2C and SPI both play an important role. Both communication protocols are the example of synchronous
communication but still, both have some important differences.
The important difference between the I2C and SPI communication protocol.
 I2C supports half-duplex while SPI is full-duplex communication.
 I2C requires only two-wire for communication while SPI requires three or four-wire for communication (depends on
requirement).
 I2C is slower as compared to the SPI communication.
 I2C draws more power than SPI.
 I2C is less susceptible to noise than SPI.
 I2C is cheaper to implement than the SPI communication protocol.
 I2C work on wire and logic and it has a pull-up resistor while there is no requirement of a pull-up resistor in case of
the SPI.
 In I2C communication we get the acknowledgment bit after each byte, it is not supported by the SPI
communication protocol.
 I2C ensures that data sent is received by the slave device while SPI does not verify that data is received correctly.
 I2C supports multi-master communication while multi-master communication is not supported by the SPI.
 One great difference between I2C and SPI is that I2C supports multiple devices on the same bus without any
additional select lines (work based on device address) while SPI requires additional signal (slave select lines) lines
to manage multiple devices on the same bus.
 I2C supports arbitration while SPI does not support the arbitration.
 I2C support the clock stretching while SPI does not support the clock stretching.
 I2C can be locked up by one device that fails to release the communication bus.
 I2C has some extra overhead due to start and stop bits.
 I2C is better for long-distance while SPI is better for the short distance.
 In the last I2C developed by NXP while SPI by Motorola.
Q) What is the difference between Asynchronous and Synchronous Communication?
There are the following differences between asynchronous and synchronous communication.
Asynchronous Communication Synchronous Communication
There is no common clock signal between the sender and
receivers.
Communication is done by a shared clock.
Sends 1 byte or character at a time. Sends data in the form of blocks or frames.
Slow as compare to synchronous communication. Fast as compare to asynchronous communication.
Overhead due to start and stop bit. Less overhead.
Ability to communicate long distance. Less as compared to asynchronous communication.
A start and stop bit used for data synchronization. A shared clock is used for data synchronization.
Economical Costly
RS232, RS485 I2C, SPI.
Q) What is the difference between RS232 and RS485?
The RS232 and RS485 is an old serial interface. Both serial interfaces are the standard for data communication. This question is also
very important and generally ask by an interviewer.
Some important difference between the RS232 and RS485
Parameter RS232 RS485
Line configuration Single –ended differential
Numbers of devices 1 transmitter 1 receiver 32 transmitters 32 receivers
Mode of operation Simplex or full duplex Simplex or half duplex
Maximum cable length 50 feet 4000 feet
Maximum data rate 20 Kbits/s 10 Mbits/s
signaling unbalanced balanced
Typical logic levels +-5 ~ +-15V +-1.5 ~ +-6V
Minimum receiver input impedance 3 ~ 7 K-ohm 12 K-ohm
Receiver sensitivity +-3V +-200mV
Q) What is the difference between Bit Rate and Baud Rate?
Bit Rate Baud Rate
Bit rate is the number of bits per second. Baud rate is the number of signal units per second.
It determines the number of bits traveled per second. It determines how many times the state of a signal is
changing.
Cannot determine the bandwidth. It can determine how much bandwidth is required to send
the signal.
This term generally used to describe the processor
efficiency.
This term generally used to describe the data transmission
over the channel.
Bit rate = baud rate x the number of bits per signal unit Baud rate = bit rate / the number of bits per signal unit
Q) What is segmentation fault in C?
A segmentation fault is a common problem that causes programs to crash. A core file (core dumped file) also associated with a
segmentation fault that is used by the developer to finding the root cause of the crashing (segmentation fault).
Generally, the segmentation fault occurs when a program tried to access a memory location that is not allowed to access or tried to
access a memory location in a way that is not allowed (tried to access read-only memory).
Q) What are the common causes of segmentation fault in C?
There are many reasons for the segmentation fault, here I am listing some common causes of the segmentation fault.
 Dereferencing NULL pointers.
 Tried to write read-only memory (such as code segment).
 Trying to access a nonexistent memory address (outside process’s address space).
 Trying to access memory the program does not have rights to (such as kernel structures in process context).
 Sometimes dereferencing or assigning to an uninitialized pointer (because might point an invalid memory) can be
the cause of the segmentation fault.
 Dereferencing the freed memory (after calling the free function) can also be caused by the segmentation fault.
 A stack overflow is also caused by the segmentation fault.
 A buffer overflow (try to access the array beyond the boundary) is also a cause of the segmentation fault.
Q) What is the difference between Segmentation fault and Bus error?
In the case of segmentation fault, SIGSEGV (11) signal is generated. Generally, a segmentation fault occurs when the program tries
to access the memory to which it doesn’t have access to.
In below I have mentioned some scenarios where SIGSEGV signal is generated.
 When trying to de-referencing a NULL pointer.
 Trying to access memory which is already de-allocated (trying to use dangling pointers).
 Using uninitialized pointer(wild pointer).
 Trying to access memory that the program doesn’t own (eg. trying to access an array element out of array bounds).
In case of a BUS error, SIGBUS (10) signal is generated. The Bus error issue occurs when a program tries to access an invalid
memory or unaligned memory. The bus error comes rarely as compared to the segmentation fault.
In below I have mentioned some scenarios where SIGBUS signal is generated.
 Non-existent address.
 Unaligned access.
 Paging errors
Q) Size of the integer depends on what?
The C standard is explained that the minimum size of the integer should be 16 bits. Some programing language is explained that the
size of the integer is implementation-dependent but portable programs shouldn’t depend on it.
Primarily the size of integer depends on the type of the compiler which has written by compiler writer for the underlying processor.
You can see compilers merrily changing the size of integer according to convenience and underlying architectures. So it is my
recommendation to use the C99 integer data types ( uin8_t, uin16_t, uin32_t ..) in place of standard int.
Q) Are integers signed or unsigned?
According to the C standard, an integer data type is by default signed. So if you create an integer variable, it can store both positive
and negative values.
For more details on signed and unsigned integers, check out:
A closer look at signed and unsigned integers in C
Q) What is a difference between unsigned int and signed int in C?
The signed and unsigned integer type has the same storage (according to the standard at least 16 bits) and alignment but still, there is
a lot of difference them, in bellows lines, I am describing some difference between the signed and unsigned integer.
 A signed integer can store the positive and negative value both but beside it unsigned integer can only store the
positive value.
 The range of nonnegative values of a signed integer type is a sub-range of the corresponding unsigned integer
type.
For example,
Assuming the size of the integer is 2 bytes.
signed int -32768 to +32767
unsigned int 0 to 65535
 When computing the unsigned integer, it never gets overflow because if the computation result is greater than the
largest value of the unsigned integer type, it is reduced modulo the number that is one greater than the largest
value that can be represented by the resulting type.
For example,
Computational Result % (Largest value of the unsigned integer+1)
 The overflow of the signed integer type is undefined.
 If Data is signed type negative value, the right shifting operation of Data is implementation-dependent but for the
unsigned type, it would be Data/ 2pos.
 If Data is signed type negative value, the left shifting operation of Data shows the undefined behavior but for the
unsigned type, it would be Data x 2pos.
Q) What is the difference between a macro and a function?
Q) What is the difference between typedef & Macros?
Let’s see the short description of the typedef and macro to understand the difference between them.
typedef:
The C language provides a very important keyword typedef for defining a new name for existing types. The typedef is the compiler
directive mainly use with user-defined data types (structure, union or enum) to reduce their complexity and increase code readability
and portability.
Syntax,
typedef type NewTypeName;
Let’s take an example,
typedef unsigned int UnsignedInt;
Now UnsignedInt is a new type and using it, we can create a variable of unsigned int. So in the below example, Mydata is unsigned
int variable.
UnsignedInt Mydata;
Note: A typedef creates synonyms or a new name for existing types it does not create new types.
Macro:
A macro is a pre-processor directive and it replaces the value before compiling the code. One of the major problems with the macro is
that there is no type checking. Generally, the macro is used to create the alias, in C language. A macro is also used as a file guard in C
and C++.
Syntax,
#define MACRO_NAME MACRO_VALUE
Let’s take an example,
#define VALUE 10
Now VALUE becomes 10 in your program. You can use the VALUE in place of the 10.
For more details, you can see below-mentioned articles,
 Macro in C.
 typedef vs #define in C.
 typedef in C.
Q) What do you mean by enumeration in C?
An enum in C is a user-defined data type. It consists set of named constant integers. Using the enum keyword, we can declare an
enumeration type by using the enumeration tag (optional) and a list of named integer.
Basically, we used the enum to increase the code readability and with enum easy to debug the code as compared to symbolic constant
(macro). The most important property of enum is that it follows the scope rule and the compiler automatically assigns the value to its
member constant.
Note: A variable of enumeration type stores one of the values of the enumeration list defined by that type.
Syntax of enum,
enum Enumeration_Tag { Enumeration_List };
The Enumeration_Tag specifies the enumeration type name.
The Enumeration_List is a comma-separated list of named constant.
Example,
enum FLASH_ERROR { DEFRAGMENT_ERROR, BUS_ERROR};
For more details, you can see below-mentioned articles,
 Macro in C.
 enum in C.
 typedef vs #define in C.
Q) What is the difference between const and macro?
 The const keyword is handled by the compiler, in another hand, a macro is handled by the preprocessor directive.
 const is a qualifier that is modified the behavior of the identifier but macro is preprocessor directive.
 There is type checking is occurred with const keyword but does not occur with #define.
 const is scoped by C block, #define applies to a file.
 const can be passed as a parameter (as a pointer) to the function. In the case of call by reference, it prevents to
modify the passed object value.
Q) How to set, clear, toggle and checking a single bit in C?
Note: Here I assume that bit of register starts with 0th position, it means the 2nd position is actually 3rd bits.
D7 D6 D5 D4 D3 D2 D1 D0
Setting N-th Bit
Setting an N-th bit means that if the N-th bit is 0, then set it to 1 and if it is 1 then leave it unchanged. In C, bitwise OR operator (|)
use to set a bit of integral data type. As we know that | (Bitwise OR operator) evaluates a new integral value in which each bit
position is 1 only when operand’s (integer type) has a 1 in that position.
In simple words, you can say that “Bitwise OR ” of two bits is always one if any one of them is one.
That means,
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
Algorithm to set the bits:
Number | = (1UL << nth Position);
Clearing a Bit
Clearing a bit means that if N-th bit is 1, then clear it to 0 and if it is 0 then leave it unchanged. Bitwise AND operator (&) use to
clear a bit of integral data type. “AND” of two bits is always zero if any one of them is zero.
That means,
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
Algorithm to clear the bit:
To clear the nth bit, first, you need to invert the string of bits then AND it with the number.
Number &= ~(1UL << nth Position);
Checking a Bit
To check the nth bit, shift the ‘1’ nth position toward the left and then “AND” it with the number.
An algorithm to check the bit
Bit = Number & (1UL << nth);
Toggling a Bit
Toggling a bit means that if the N-th bit is 1, then change it to 0 and if it is 0 then change it to 1. Bitwise XOR (^) operator use to
toggle the bit of an integral data type. To toggle the nth bit shift the ‘1’ nth position toward the left and “XOR” it.
That means,
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
An algorithm to toggle the bits
Number ^= (1UL << nth Position);
Q) What will be the output of the below C program?
#include <stdio.h>
int main()
{
char var = 10;
void *ptr = &var;
printf("%d %d",*(char*)ptr,++(*(char*)ptr));
return 0;
}
Output: undefined
Explanation: Due to the sequence point the output vary on a different platform.
Q) Write a program swap two numbers without using the third variable?
Let’s assume a, b two numbers, there are a lot of methods two swap two numbers without using the third variable.
Method 1( (Using Arithmetic Operators):
#include <stdio.h>
int main()
{
int a = 10, b = 5;
// algo to swap 'a' and 'b'
a = a + b; // a becomes 15
b = a - b; // b becomes 10
a = a - b; // fonally a becomes 5
printf("After Swapping the value of: a = %d, b = %dnn", a, b);
return 0;
}
Method 2 (Using Bitwise XOR Operator):
#include <stdio.h>
int main()
{
int a = 10, b = 5;
// algo to swap 'a' and 'b'
a = a ^ b; // a becomes (a ^ b)
b = a ^ b; // b = (a ^ b ^ b), b becomes a
a = a ^ b; // a = (a ^ b ^ a), a becomes b
printf("After Swapping the value of: a = %d, b = %dnn", a, b);
return 0;
}
Q) What will be the output of the below C program?
#include <stdio.h>
#define ATICLEWORLD 0x01
#define AUTHOR 0x02
int main()
{
unsigned char test = 0x00;
test|=ATICLEWORLD;
test|=AUTHOR;
if(test & ATICLEWORLD)
{
printf("I am an Aticleworld");
}
if( test & AUTHOR)
{
printf(" Author");
}
return 0;
}
Output: I am an Aticleworld Author
Explanation:When we are OR-ing the test( unsigned char variable) with 0x01 and 0x02. The value of test will be 0x03 (because
initially test value is 0x00). When we perform the And-ing operatotion on test with 0x01 and 0x02 then expresstion will return non-
zero value, for example (0x00000011 & 0x00000001 => 0x00000010).
Q) What is meant by structure padding?
In the case of structure or union, the compiler inserts some extra bytes between the members of structure or union for the alignment,
these extra unused bytes are called padding bytes and this technique is called padding.
Padding has increased the performance of the processor at the penalty of memory. In structure or union data members aligned as per
the size of the highest bytes member to prevent the penalty of performance.
Note: Alignment of data types mandated by the processor architecture, not by language.
You can see the below Articles,
 Brief Introduction of structure padding in C.
 Top 11 structure padding interview questions in C.
Q) What is the endianness?
The endianness is the order of bytes to store data in memory and it also describes the order of byte transmission over a digital link. In
the memory data store in which order depends on the endianness of the system, if the system is big-endian then the MSB byte store
first (means at lower address) and if the system is little-endian then LSB byte store first (means at lower address).
Some examples of the little-endian and big-endian system.
Q) What is big-endian and little-endian?
Suppose 32 bits Data is 0x11223344.
Big-endian
The most significant byte of data stored at the lowest memory address.
Little-endian
The least significant byte of data stored at the lowest memory address.
Note: Some processor has the ability to switch one endianness to other endianness using the software means it can perform like both
big-endian or little-endian at a time. This processor is known as the Bi-endian, here are some architecture (ARM version 3 and
above, Alpha, SPARC) who provide the switchable endianness feature.
Q) Write a C program to check the endianness of the system.
Method 1:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void)
{
uint32_t u32RawData;
uint8_t *pu8CheckData;
u32RawData = 0x11223344; //Assign data
pu8CheckData = (uint8_t *)&u32RawData; //Type cast
if (*pu8CheckData == 0x44) //check the value of lower address
{
printf("little-Endian");
}
else if (*pu8CheckData == 0x11) //check the value of lower address
{
printf("big-Endian");
}
return 0;
}
Method 2:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
typedef union
{
uint32_t u32RawData; // integer variable
uint8_t au8DataBuff[4]; //array of character
} RawData;
int main(void)
{
RawData uCheckEndianess;
uCheckEndianess.u32RawData = 0x11223344; //assign the value
if (uCheckEndianess.au8DataBuff[0] == 0x44) //check the array first index value
{
printf("little-endian");
}
else if (uCheckEndianess.au8DataBuff[0] == 0x11) //check the array first index value
{
printf("big-endian");
}
return 0;
}
Q) How to Convert little-endian to big-endian vice versa in C?
We can convert little-endian to big-endian or vice versa using the C programs. So let us see few ways to convert one endian to
another.
#include <stdio.h>
#include <inttypes.h>
//Function to change one endian to another
uint32_t ChangeEndianness(uint32_t u32Value)
{
uint32_t u32Result = 0;
u32Result |= (u32Value & 0x000000FF) << 24;
u32Result |= (u32Value & 0x0000FF00) << 8;
u32Result |= (u32Value & 0x00FF0000) >> 8;
u32Result |= (u32Value & 0xFF000000) >> 24;
return u32Result;
}
int main()
{
uint32_t u32CheckData = 0x11223344;
uint32_t u32ResultData =0;
//swap the data
u32ResultData = ChangeEndianness(u32CheckData);
//converted data
printf("0x%xn",u32ResultData);
return 0;
}
Output:
0x44332211
Q) What is static memory allocation and dynamic memory allocation?
According to C standard, there are four storage duration, static, thread (C11), automatic, and allocated. The storage duration
determines the lifetime of the object.
The static memory allocation:
Static Allocation means, an object has an external or internal linkage or declared with static storage-class. It’s initialized only once,
before program startup and its lifetime is throughout the execution of the program. A global and static variable is an example of static
memory allocation.
The dynamic memory allocation:
In C language, there are a lot of library functions (malloc, calloc, or realloc,..) which are used to allocate memory dynamically. One
of the problems with dynamically allocated memory is that it is not destroyed by the compiler itself that means it is the
responsibility of the user to deallocate the allocated memory.
When we allocate the memory using the memory management function, they return a pointer to the allocated memory block and the
returned pointer is pointing to the beginning address of the memory block. If there is no space available, these functions return a null
pointer.
Q) What is the memory leak in C?
A memory leak is a common and dangerous problem. It is a type of resource leak. In C language, a memory leak occurs when you
allocate a block of memory using the memory management function and forget to release it.
int main ()
{
char * pBuffer = malloc(sizeof(char) * 20);
/* Do some work */
return 0; /*Not freeing the allocated memory*/
}
Note: once you allocate a memory than allocated memory does not allocate to another program or process until it gets free.
Q) What is the output of the below C code?
#include <stdio.h>
int main(void)
{
int var;
for(var = -3 ; var <sizeof(int) ; var++)
{
printf("Hello Aticleworldn");
}
return 0;
}
Output:
Nothing will print.
Explanation: In the above C code, We are trying to compare a signed int variable “var” with size_t, which is defined as an unsigned
long int (sizeof operator return size_t). Here integer promotion occurs and the compiler will convert signed int -3 to unsigned long int
and resultant value would very large as compare to int size. So the for loop condition will be false and there won’t be any iteration.
Q) What is the output of the below C code?
#include <stdio.h>
int main()
{
int pos = 14;
float data = 15.2;
printf("%*f",pos,data);
return 0;
}
Output:
print 15.200000 with 6 spaces.
Explanation: The output will be ______15.20000, where _ has been used to represent space here. The program will print a floating-
point number with a width of at least 14 and since no precision has been specified, it will take the default precision of 6 decimal point
for format specifier “f”.
The symbol * can be used with a format specifier to replace the width or precision. Here it has been used to replace the width. The
general format for %f can be seen as %(width). (precision)f. When * is used to specify width or precision. Let see a C code for the
same.
#include <stdio.h>
int main()
{
int pos = 14;
float data = 15.2;
printf("%*.*f",pos,2,data);
return 0;
}
Output:
print 15.20 with spaces.
Q) What is the difference between malloc and calloc?
A malloc and calloc are memory management functions. They are used to allocate memory dynamically. Basically, there is no actual
difference between calloc and malloc except that the memory that is allocated by calloc is initialized with 0.
In C language,calloc function initialize the all allocated space bits with zero but malloc does not initialize the allocated memory.
These both function also has a difference regarding their number of arguments, malloc takes one argument but calloc takes two.
Q) What is the purpose of realloc( )?
The realloc function is used to resize the allocated block of memory. It takes two arguments first one is a pointer to previously
allocated memory and the second one is the newly requested size.
The calloc function first deallocates the old object and allocates again with the newly specified size. If the new size is lesser to the old
size, the contents of the newly allocated memory will be the same as prior but if any bytes in the newly created object goes beyond
the old size, the values of the exceeded size will be indeterminate.
Syntax:
void *realloc(void *ptr, size_t size);
Let’s see an example to understand the working of realloc in C language.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *pcBuffer = NULL;
/* Initial memory allocation */
pcBuffer = malloc(8);
//make sure piBuffer is valid or not
if (pcBuffer == NULL)
{
// allocation failed, exit from the program
fprintf(stderr, "Out of memory!n");
exit(1);
}
strcpy(pcBuffer, "aticle");
printf("pcBuffer = %sn", pcBuffer);
/* Reallocating memory */
pcBuffer = realloc(pcBuffer, 15);
if (pcBuffer == NULL)
{
// allocation failed, exit from the program
fprintf(stderr, "Out of memory!n");
exit(1);
}
strcat(pcBuffer, "world");
printf("pcBuffer = %sn", pcBuffer);
//free the allocated memory
free(pcBuffer);
return 0;
}
Output:
pcBuffer = aticle
pcBuffer = aticleworld
Note: It should be used for dynamically allocated memory but if a pointer is a null pointer, realloc behaves like the malloc function.
Q) What is the return value of malloc (0)?
If the size of the requested space is zero, the behavior will be implementation-defined. The return value of the malloc could be a null
pointer or it shows the behavior of that size is some nonzero value. It is suggested by the standard to not use the pointer to access an
object that is returned by the malloc while the size is zero.
Q) What is dynamic memory fragmentation?
The memory management function is guaranteed that if memory is allocated, then it would be suitably aligned to any object which
has the fundamental alignment. The fundamental alignment is less than or equal to the largest alignment that’s supported by the
implementation without an alignment specification.
One of the major problems with dynamic memory allocation is fragmentation, basically, fragmentation occurred when the user
does not use the memory efficiently. There are two types of fragmentation, external fragmentation, and internal fragmentation.
The external fragmentation is due to the small free blocks of memory (small memory hole) that is available on the free list but the
program not able to use it. There are different types of free list allocation algorithms that used the free memory block efficiently.
To understand the external fragmentation, consider a scenario where a program has 3 contiguous blocks of memory and the user frees
the middle block of memory. In that scenario, you will not get a memory, if the required block of memory is larger than a single
block of memory (but smaller or equal to the aggregate of the block of memory).
The internal fragmentation is wasted of memory that is allocated for rounding up the allocated memory and in bookkeeping
(infrastructure), the bookkeeping is used to keep the information of the allocated memory.
Whenever we called the malloc function then it reserves some extra bytes (depend on implementation and system) for bookkeeping.
This extra byte is reserved for each call of malloc and becomes a cause of the internal fragmentation.
For example,
See the below code, the programmer may think that the system will be allocated 8 *100 (800) bytes of memory but due to
bookkeeping (if 8 bytes) system will be allocated 8*100 extra bytes. This is an internal fragmentation, where 50% of the heap waste.
char *acBuffer[100];
int main()
{
int iLoop = 0;
while(iLoop < 100)
{
acBuffer[iLoop ] = malloc(8);
++iLoop;
}
}
Q) How is the free work in C?
When we call the memory management functions (malloc, calloc or realloc) then these functions keep extra bytes for bookkeeping.
Whenever we call the free function and pass the pointer that is pointing to allocated memory, the free function gets the bookkeeping
information and release the allocated memory. Anyhow if you or your program change the value of the pointer that is pointing to the
allocated address, the calling of the free function gives the undefined result.
____ The allocated block ____
/ 
+--------+--------------------+
| Header | Your data area ... |
+--------+--------------------+
^
|
+-- Returned Address
Let us see a program to understand the above concept. The behavior of the below program is not defined.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *pcBuffer = NULL;
//Allocate the memory
pcBuffer = malloc(sizeof(char) * 16);
//make sure piBuffer is valid or not
if (pcBuffer == NULL)
{
// allocation failed, exit from the program
fprintf(stderr, "Out of memory!n");
exit(1);
}
//Increment the pointer
pcBuffer++;
//Call free function to release the allocated memory
free(pcBuffer);
return 0;
}
OutPut: Undefined Result
Q) What is a Function Pointer?
A function pointer is similar to the other pointers but the only difference is that it points to a function instead of a variable. In
another word, we can say that a function pointer is a type of pointer that store the address of a function and these pointed function can
be invoked by function pointer in a program whenever required.
Q) How to declare a pointer to a function in C?
The syntax for declaring function pointer is very straightforward. It seems difficult in beginning but once you are familiar with
function pointer then it becomes easy.
The declaration of a pointer to a function is similar to the declaration of a function. That means the function pointer also requires a
return type, declaration name, and argument list. One thing that you need to remember here is, whenever you declare the function
pointer in the program then the declaration name is preceded by the * (Asterisk) symbol and enclosed in parenthesis.
For example,
void ( *fpData )( int );
For a better understanding, let’s take an example to describe the declaration of a function pointer in the C program.
e.g,
void ( *pfDisplayMessage) (const char *);
In the above expression, pfDisplayMessage is a pointer to a function taking one argument, const char *, and returns void.
When we declare a pointer to function in c then there is a lot of importance of the bracket. If in the above example, I remove the
bracket, then the meaning of the above expression will be change and it becomes void *pfDisplayMessage (const char *). It is a
declaration of a function that takes the const character pointer as arguments and returns a void pointer.
Q) Where can the function pointers be used?
There are a lot of places, where the function pointers can be used. Generally, function pointers are used in the implementation of the
callback function, finite state machine and to provide the feature of polymorphism in C language …etc.
Q) Write a program to check an integer is a power of 2?
Here, I am writing a small algorithm to check the power of 2. If a number is a power of 2, function return 1.
int CheckPowerOftwo (unsigned int x)
{
return ((x != 0) && !(x & (x - 1)));
}
Q) What is the output of the below code?
#include <stdio.h>
int main()
{
int x = -15;
x = x << 1;
printf("%dn", x);
}
Output:
undefined behavior.
Q) What is the output of the below code?
#include <stdio.h>
int main()
{
int x = -30;
x = x >> 1;
printf("%dn", x);
}
Output:
implementation-defined.
Q) Write a program to count set bits in an integer?
unsigned int NumberSetBits(unsigned int n)
{
unsigned int CountSetBits= 0;
while (n)
{
CountSetBits += n & 1;
n >>= 1;
}
return CountSetBits;
}
Q) What is void or generic pointers in C?
A void pointer in c is called a generic pointer, it has no associated data type. It can store the address of any type of object and it can
be type-casted to any type. According to C standard, the pointer to void shall have the same representation and alignment
requirements as a pointer to a character type. A void pointer declaration is similar to the normal pointer, but the difference is that
instead of data types we use the void keyword.
Syntax:
void * Pointer_Name;
Q) What is the advantage of a void pointer in C?
There are following advantages of a void pointer in c.
 Using the void pointer we can create a generic function that can take arguments of any data type.
The memcpy and memmove library function are the best examples of the generic function, using these functions
we can copy the data from the source to destination.
 We know that void pointer can be converted to another data type that is the reason malloc, calloc or realloc
library function return void *. Due to the void * these functions are used to allocate memory to any data type.
 Using the void * we can create a generic linked list. For more information see this link: How to create generic Link
List.
Q) What are dangling pointers?
Generally, daggling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers.
It creates the problem because the pointer is still pointing the memory that is not available. When the user tries to dereference the
daggling pointers than it shows the undefined behavior and can be the cause of the segmentation fault.
For example,
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *piData = NULL;
//creating integer of size 10.
piData = malloc(sizeof(int)* 10);
//make sure piBuffer is valid or not
if (piData == NULL)
{
// allocation failed, exit from the program
fprintf(stderr, "Out of memory!n");
exit(1);
}
//free the allocated memory
free(piData);
//piData is dangling pointer
*piData = 10;
printf("%d",*piData);
return 0;
}
OutPut: Undefined Result
In simple words, we can say that a dangling pointer is a pointer that is not pointing to valid memory. So if we access these pointers
then the behaviour of the program will undefine.
Q) What is the wild pointer?
A pointer that is not initialized properly before its first use is known as the wild pointer. Uninitialized pointer’s behavior is totally
undefined because it may point some arbitrary location that can be the cause of the program crash, that’s is the reason it is called a
wild pointer.
In other words, we can say every pointer in programming languages that are not initialized either by the compiler or programmer
begins as a wild pointer.
Note: Generally, compilers warn about the wild pointer.
Syntax,
int *piData; //piData is wild pointer.
Q) What is a NULL pointer?
According to C standard, an integer constant expression with the value 0, or such an expression cast to type void *, is called a null
pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer.
Syntax,
int *piData = NULL; // piData is a null pointer
Q) What are the post-increment and decrement operators?
When we use a post-increment (++) operator on an operand then the result is the value of the operand and after getting the result, the
value of the operand is incremented by 1. The working of the post-decrement (–) operator is similar to the post-increment
operator but the difference is that the value of the operand is decremented by 1.
Note: incrementation and decrementation by 1 are the types specified.
Q) Which one is better: Pre-increment or Post increment?
Nowadays compiler is enough smart, they optimize the code as per the requirements. The post and pre-increment both have their own
importance we need to use them as per the requirements.
If you are reading a flash memory byte by bytes through the character pointer then here you have to use the post-increment, either
you will skip the first byte of the data. Because we already know that in the case of pre-increment pointing address will be increment
first and after that, you will read the value.
Let’s take an example of the better understanding,
In the below example code, I am creating a character array and using the character pointer I want to read the value of the array. But
what will happen if I used a pre-increment operator? The answer to this question is that ‘A’ will be skipped and B will be printed.
#include <stdio.h>
int main(void)
{
char acData[5] = {'A','B','C','D','E'};
char *pcData = NULL;
pcData = acData;
printf("%c ",*++pcData);
return 0;
}
But in place of pre-increment if we use post-increment then the problem is getting solved and you will get A as the output.
#include <stdio.h>
int main(void)
{
char acData[5] = {'A','B','C','D','E'};
char *pcData = NULL;
pcData = acData;
printf("%c ",*pcData++);
return 0;
}
Besides that, when we need a loop or just only need to increment the operand then pre-increment is far better than post-increment
because in case of post increment compiler may have created a copy of old data which takes extra time. This is not 100% true because
nowadays the compiler is so smart and they are optimizing the code in a way that makes no difference between pre and post-
increment. So it is my advice, if post-increment is not necessary then you have to use the pre-increment.
Note: Generally post-increment is used with array subscript and pointers to read the data, otherwise if not necessary then use pre in
place of post-increment. Some compiler also mentioned that to avoid to use post-increment in looping condition.
iLoop = 0.
while (a[iLoop ++] != 0)
{
// Body statements
}
Q) Are the expressions *ptr ++ and ++*ptr same ?
Both expressions are different. Let’s see a sample code to understand the difference between both expressions.
#include <stdio.h>
int main(void)
{
int aiData[5] = {100,200,300,400,500};
int *piData = aiData;
++*piData;
printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData);
return 0;
}
Output: 101 , 200 , 101
Explanation:
In the above example, two operators are involved and both have the same precedence with a right to left associativity. So the above
expression ++*p is equivalent to ++ (*p). In another word, we can say it is pre-increment of value and output is 101, 200, 101.
#include <stdio.h>
int main(void)
{
int aiData[5] = {100,200,30,40,50};
int *piData = aiData;
*++piData;
printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData);
return 0;
}
Output: 100, 200, 200
Explanation:
In the above example, two operators are involved and both have the same precedence with the right to left associativity. So the above
expression *++p is equivalent to *(++p). In another word you can say it is pre-increment of address and output is 100, 200,200.
Q) What does the keyword const mean?
A const is only a qualifier, it changes the behavior of a variable and makes it read-only type. When we want to make an object read-
only type, then we have to declare it as const.
Syntax,
const DataType Identifier = Value;
e.g.
const int iData = 0
At the time of declaration, const qualifier only gives the direction to the compiler that the value of declaring objects could not be
changed. In simple words, const means not modifiable (cannot assign any value to the object at the runtime).
Q) How will you protect a pointer by some accidental modification with the pointer address?
With the help of the “const” keyword, we can avoid accidental modification of the pointer address.
Q) When should we use const in a C program?
There are the following places where we need to use the const keyword in the programs.
 In case of call by reference, if you don’t want to change the value of the passed variable. E.g.,
int PrintData ( const char *pcMessage);
 In some places, const is better than macro because const is handled by the compiler and has a type checking.
 In the case of the I/O and memory-mapped register, const is used with the volatile qualifier for efficient access. for
eg,
const volatile uint32_t *DEVICE_STATUS = (uint32_t *) 0x80102040;
 When you don’t want to change the value of an initialized variable.
Q) What is the meaning of the below declarations?
1. const int a;
2. int const a;
3. const int *a;
4. int * const a;
5. int const * a const;
1. The “a” is a constant integer.
2. Similar to first, “a” is a constant integer.
3. Here “a” is a pointer to a const integer, the value of the integer is not modifiable, but the pointer is not modifiable.
4. Here “a” is a const pointer to an integer, the value of the pointed integer is modifiable, but the pointer is not
modifiable.
5. Here “a” is a const pointer to a const integer that means the value of pointed integer and pointer both are not
modifiable.
Q) Differentiate between a constant pointer and pointer to a constant?
Constant pointer:
A constant pointer is a pointer whose value (pointed address) is not modifiable. If you will try to modify the pointer value, you will
get the compiler error.
A constant pointer is declared as follows :
Data_Type * const Pointer_Name;
Let’s see the below example code when you will compile the below code to get the compiler error.
#include<stdio.h>
int main(void)
{
int var1 = 10, var2 = 20;
//Initialize the pointer
int *const ptr = &var1;
//Try to modify the pointer value
ptr = &var2;
printf("%dn", *ptr);
return 0;
}
Output: compiler error.
Pointer to a constant:
In this scenario the value of the pointed address is constant that means we can not change the value of the address that is pointed by
the pointer.
A constant pointer is declared as follows :
Data_Type const* Pointer_Name;
Let’s take a small code to illustrate a pointer to a constant:
#include<stdio.h>
int main(void)
{
int var1 = 100;
// pointer to constant integer
const int* ptr = &var1;
//try to modify the value of pointed address
*ptr = 10;
printf("%dn", *ptr);
return 0;
}
Output: compiler error.
Q) How to use a variable in a source file that is defined in another source file?
Using the “extern” keyword we can access a variable from one source file to another.
Q) What are the uses of the keyword static?
In C language, the static keyword has a lot of importance. If we have used the static keyword with a variable or function, then only
internal or none linkage is worked. I have described some simple use of a static keyword.
 A static variable only initializes once, so a variable declared static within the body of a function maintains its prior
value between function invocations.
 A global variable with a static keyword has internal linkage, so it only accesses within the translation unit (.c). It is
not accessible by another translation unit. The static keyword protects your variable to access from another
translation unit.
 By default in C language, the linkage of the function is external that it means it is accessible by the same or
another translation unit. With the help of the static keyword, we can make the scope of the function local, it only
accesses by the translation unit within it is declared.
Q) What is the difference between global and static global variables?
Global and static global variables have different linkages. It is the reason global variables can be accessed outside of the file but the
static global variable only accesses within the file in which it is declared.
A static global variable ===>>> internal linkage.
A non-static global variable ===>>> external linkage.
Q) Differentiate between an internal static and external static variable?
In C language, the external static variable has the internal linkage and the internal static variable has no linkage. It is the reason they
have a different scope but both will alive throughout the program.
A external static variable ===>>> internal linkage.
A internal static variable ===>>> none .
Q) Can static variables be declared in a header file?
Yes, we can declare the static variables in a header file.
Static variables can be declared in the header files or any other source file. But in the header files, they can only be initialized once
while in the source files, they can be initialized any number of times
Q) What is the difference between declaration and definition of a variable?
Declaration of a variable in C
A variable declaration only provides sureness to the compiler at the compile time that variable exists with the given type and name,
so that compiler proceeds for further compilation without needing all detail of this variable. When we declare a variable in C
language, we only give the information to the compiler, but there is no memory reserve for it. It is only a reference, through which we
only assure the compiler that this variable may be defined within the function or outside of the function.
Note: We can declare a variable multiple times but defined only once.
eg,
extern int data;
extern int foo(int, int);
int fun(int, char); // extern can be omitted for function declarations
Definition of variable in C
The definition is action to allocate storage to the variable. In another word, we can say that variable definition is the way to say the
compiler where and how much to create the storage for the variable generally definition and declaration occur at the same time but
not almost.
eg,
int data;
int foo(int, int) { }
Note: When you define a variable then there is no need to declare it but vice versa is not applicable.
Q) What is the difference between pass by value by reference in c and pass by reference in c?
Pass By Value:
 In this method, the value of the variable is passed. Changes made to formal will not affect the actual parameters.
 Different memory locations will be created for both variables.
 Here there will be a temporary variable created in the function stack which does not affect the original variable.
Pass By Reference :
 In Pass by reference, an address of the variable is passed to a function.
 Whatever changes made to the formal parameter will affect the value of actual parameters(a variable whose
address is passed).
 Both formal and actual parameters shared the same memory location.
 it is useful when you required to returns more than 1 value.
Q) What is a reentrant function?
In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then
safely be called again (“re-entered”) before its previous invocations complete execution. The interruption could be caused by an
internal action such as a jump or call, or by an external action such as an interrupt or signal. Once the reentered invocation completes,
the previous invocations will resume correct execution.
Q) What is the inline function?
An inline keyword is a compiler directive that only suggests the compiler substitute the function’s body at the calling the place. It is
an optimization technique used by the compilers to reduce the overhead of function calls.
for example,
static inline void Swap(int *a, int *b)
{
int tmp= *a;
*a= *b;
*b = tmp;
}
Q) What is the advantage and disadvantage of the inline function?
There are a few important advantages and disadvantages of the inline function.
Advantages:
1) It saves the function calling overhead.
2) It also saves the overhead of variables push/pop on the stack, while function calling.
3) It also saves the overhead of return call from a function.
4) It increases the locality of reference by utilizing the instruction cache.
5) After inlining compiler can also apply intraprocedural optimization if specified. This is the most important one, in this way
compiler can now focus on dead code elimination, can give more stress on branch prediction, induction variable elimination, etc..
Disadvantages:
1) May increase function size so that it may not fit in the cache, causing lots of cache miss.
2) After the inlining function, if variables numbers that are going to use register increases then they may create overhead on register
variable resource utilization.
3) It may cause compilation overhead as if somebody changes code inside an inline function then all calling locations will also be
compiled.
4) If used in the header file, it will make your header file size large and may also make it unreadable.
5) If somebody used too many inline functions resultant in a larger code size then it may cause thrashing in memory. More and
number of page faults bringing down your program performance.
6) It’s not useful for an embedded system where a large binary size is not preferred at all due to memory size constraints.
Q) What is virtual memory?
Virtual memory is part of memory management techniques and it creates an illusion that the system has a sufficient amount of
memory. In other words, you can say that virtual memory is a layer of indirection.
Q) How can you protect a character pointer by some accidental modification with the
pointer address?
Using the const keyword we can protect a character pointer by some accidental modification with the pointer address. Eg, const
char *ptr; here we can not change the value of the address pointed by ptr by using ptr.
Q) Consider the two statements and find the difference between them?
struct sStudentInfo
{
char Name[12];
int Age;
float Weight;
int RollNumber;
};
#define STUDENT_INFO struct sStudentInfo*
typedef struct sStudentInfo* studentInfo;
statement 1
STUDENT_INFO p1, p2;
statement 2
studentInfo q1, q2;
Both statements looking the same but actually, both are different from each other.
Statement 1 will be expanded to struct sStudentInfo * p1, p2. It means that p1 is a pointer to struct sStudentInfo but p2 is a variable of
struct sStudentInfo.
In statement 2, both q1 and q2 will be a pointer to struct sStudentInfo.
Q) Can structures be passed to the functions by value?
Yes, but it is not a good programming practice because if the structure is big maybe got StackOverflow if you have a very limited
amount of stack.
Q) What are the limitations of I2C interface?
 Half-duplex communication, so data is transmitted only in one direction (because of the single data bus) at a time.
 Since the bus is shared by many devices, debugging an I2C bus (detecting which device is misbehaving) for
issues is pretty difficult.
 The I2C bus is shared by multiple slave devices if anyone of these slaves misbehaves (pull either SCL or SDA low
for an indefinite time) the bus will be stalled. No further communication will take place.
 I2C uses resistive pull-up for its bus. Limiting the bus speed.
 Bus speed is directly dependent on the bus capacitance, meaning longer I2C bus traces will limit the bus speed.
Q) What is the Featured of CAN Protocol?
There are few features of can protocol.
 Simple and flexible in Configuration.
 CAN is a Message-Based Protocol.
 Message prioritization feature through identifier selection.
 CAN offer Multi-master Communication.
 Error Detection and Fault Confinement feature.
 Retransmission of the corrupted message automatically when the bus is idle.
Q) What is priority inversion?
Priority inversion is a problem, not a solution. Priority inversion is a situation where a high-priority task is blocked on a low-priority
task using a protected shared resource. During this blockage, a medium-priority task (that does not need the shared resource) can
finish its work before the high-priority task.
Q) What is priority inheritance?
In priority inheritance, a low-priority task is automatically assigned the priority of a higher priority task when it blocks on the mutex.
The low-priority task is re-assigned its original priority when it releases the mutex.
Q) Significance of watchdog timer in Embedded Systems?
Using the watchdog timer you can reset your device. It is a useful tool in helping your system recover from transient failures.
Q) What Is Concatenation Operator in Embedded C?
Token Pasting Operator (##) is sometimes called a merging or combining operator. It is used to merge two valid tokens, it is the
reason we called it token concatenation. See the below example code,
#include <stdio.h>
#define MERGE(token1, token2) token1##token2
int main()
{
int var1 = 10;
int var2 = 20;
int var3 = 30;
printf("%dn", MERGE(var, 1));
printf("%dn", MERGE(var, 2));
printf("%dn", MERGE(var, 3));
return 0;
}
Output: 10 ,20,30
1) What is Embedded C? / What do you understand by Embedded C language?
Embedded C is a set of language extensions for the C programming language specified by the C Standards Committee. It is generally
used to address commonality issues that exist between C extensions for different embedded systems. Embedded C programming
typically requires nonstandard extensions to the C language to support enhanced microprocessor features such as fixed-point
arithmetic, multiple distinct memory banks, and basic I/O operations.
2) What do you understand by the embedded system?
An embedded system is a microprocessor-based computer hardware system and software designed to perform a specific function.
An embedded system is either an independent system or acts as a part of a large system.
3) What are the key differences between C and Embedded C?
C is a general-purpose, high-level programming language used to design any desktop-based applications. On the other hand,
Embedded C is an extension of the C language, and it is used to develop micro-controller based applications. Here, Embedded refers
to the hosting computer or microcontroller and not the programming language. Let's see the key differences between C and
Embedded C in the following table.
Differences between C and Embedded C:
C language Embedded C
C is a general-purpose programming language used to design any
desktop-based applications.
Embedded C is nothing but an extension C programming language, and it is used to develop
micro-controller based applications.
C is a type of high-level programming language. Embedded C is an extension of the C programming language.
C programming language is the hardware-independent language. Embedded C is a completely hardware-dependent language.
C is a simple language, and it is easy to read and modify. Embedded C is comparatively tough, and it is not easy to read and modify the Embedded C
language.
The compilers of the C programming language are OS-dependent. The compilers of Embedded C are OS independent.
In the C programming language, the standard compilers are used to
compile and execute the program.
In Embedded C language, a specific compiler that can generate particular hardware/micro-
controller based output is used to compile the code.
Some popular compilers used to execute a C language program
are:
GCC (GNU Compiler collection)
Borland Turbo C
Intel C++
Some popular compilers used to execute an Embedded C language program are:
Keil compiler
BiPOM ELECTRONIC
Green Hill software
C programming language has a free format of program coding. In Embedded C language, formatting depends upon the type of microprocessor used in the
application.
Bug fixing is easy in a C language program. Bug fixing is complicated in an Embedded C language program.
C language also supports other various programming languages
during application.
Embedded C language supports only the required processor of the application and not the
programming languages.
C programming language must require an operating system. Embedded C may or may not require an operating system.
In the C programming language, we can give input to the program
while it is running.
In Embedded C language, we can give only the pre-defined inputs to the running program.
The C programming language supports normal optimization. Embedded C supports the high level of optimization.
4) Is embedded C a programming language?
Embedded C is not a core programming language. It is an extension of C programming language that is used to develop micro-
controller based applications. The extensions introduced in Embedded C language from normal C programming language are the I/O
Hardware Addressing, fixed-point arithmetic operations, accessing address spaces, etc.
5) What are the main advantages of Embedded C?
Embedded C is the extension of the C programming language. Let's see the key advantages of Embedded C:
Key advantages of Embedded C:
o The coding speed of Embedded C is high, and it is simple and easy to understand.
o It doesn't require any hardware changes such as extra memory or space for storage as it performs the same task all the time.
o It is dedicated to its specific task and performs only one task at one time.
o It is mainly used in modern automatic applications. Embedded applications are very suitable for industrial purposes.
6) What are the main disadvantages of Embedded C?
Disadvantages of Embedded C:
C programming language generally uses the resources of a desktop
PC like memory, OS, etc.
Embedded C language has to use with the limited resources, such as RAM, ROM, I/Os on an
embedded processor.
Some examples of the C Program applications:
Logical programs
System software programs etc.
Some examples of the Embedded C Program applications:
DVD
TV
Digital camera etc.
o Embedded C performs only one task at a time, so it is not preferred when we have to perform multiple tasks simultaneously.
o Embedded C only supports the hardware system. So, if you have to change the program, then you must have to change the
hardware.
o Embedded C also has some scalability issues, so; it cannot be easily scaled up as scope change or demand.
o It has some limitations, such as limited memory or computer compatibility.
7) What is the volatile keyword in Embedded C, and what is its usage?
In Embedded C, the volatile keyword is a type qualifier that prevents the objects from compiler optimization. According to the C
standard, we can modify the volatile-qualified type object in ways unknown to the implementation. In other words, we can say that
the value of the volatile-qualified object can be changed at any time without making any changes in the code. If the volatile qualifier
qualifies an object, the compiler will reload the value from memory each time the program accesses it. Reading the value from memory
is the only way to check the unpredictable change of the value.
The volatile keyword is mainly used when we have to deal with GPIO, interrupt or flag Register directly. It is also used with a global
variable or buffer shared between the threads.
8) What is the segmentation fault error in C? What are some common causes for the segmentation
fault error?
Segmentation fault error is a runtime error, which may occur due to some causes when a program runs.
Following is a list of some common causes for the segmentation fault error in C:
o Usages of the dereferenced pointer: If we use a pointer that may not have a valid address/memory location to point, it may
create a segmentation fault error.
o A program may return a segmentation fault error if you try to access a read-only memory area.
o Segmentation fault error may also occur when you try to free memory (using a pointer), which is already freed.
o The occurrence of segmentation fault error is the reason to generate stack overflow error in C.
9) What is the full form of ISR in Embedded C?
In Embedded C, ISR stands for Interrupt Service Routines. These are the procedures stored at specific memory addresses and called
when a certain type of interrupt occurs.
10) What is a stack overflow error in C?
In C language, the stack overflow error may occur if the program tries to access the memory beyond its available maximum limit. For
example, the stack overflow error may occur if a pointer exceeds the stack limitations (boundaries).
When the stack overflow error occurs, the program terminates and does not execute further instructions. So, we must be very careful
while using the pointer and limit boundaries.
11) Is it possible to pass any parameter and return a value from the ISR?
No. It is not possible to pass any parameter and return a value from the ISR. The ISR returns nothing and does not allow passing any
parameter. An ISR is called when a hardware or software event occurs, and the code does not call it. That's why no parameters are
passed into an ISR. As the code does not call ISR, there is no calling code to read the returned values of the ISR. That's why an ISR
does not return any value.
12) What do you understand by interrupt latency?
Interrupt Latency is the number of clock cycles the processor takes to respond to an interrupt request. This clock cycle number is
count between the interrupt request's assertions and the interrupt handler's first instruction.
Interrupt Latency on the Cortex-M processor family:
Cortex-M processors have very low interrupt latency. The following table shows the Interrupt latency of Cortex-M processors with
zero wait state memory systems.
Processors Cycles with zero wait state memory
Cortex-M0 16
Cortex-M0+ 15
Cortex-M3 12
Cortex-M4 12
Cortex-M7 12
13) How can you measure the interrupt latency in Embedded C?
In Embedded C, we can measure the interrupt latency with the help of the oscilloscope. Follow the steps given below:
o Take two GPIOs first. Configure one GPIO to generate the interrupt and the second for the toggling (you can attach an LED
also).
o Use the oscilloscope or analyzer to monitor the PIN, which is already configured to generate the interrupt.
o Now, monitor the second pin, which is toggled at the beginning of the interrupt service routine by using the oscilloscope or
analyzer.
o When you generate the interrupt, the signal of both GPIOs will change.
o Now, you can easily read the instrument's interval between the two signals (interrupt latency).
14) How can you reduce the interrupt latency?
There are several ways to reduce the interrupt latency in Embedded C. The interrupt latency depends on many factors. Following is a
list of some factors:
o Platform and interrupt controller
o CPU clock speed
o Timer frequency
o Cache configuration
o Application program etc.
So, we can easily reduce the interrupt latency by using the proper selection of platform and processor. We can also reduce the
interrupt latency by making the ISR shorter and avoid to calling a function within the ISR.
15) What is a static variable in C? Why do we use a static variable in C?
Static variables have the property of preserving their value even after they are out of their scope. It means we can initialize static
variables only once. Its scope is local, but it lives until the end of the program. The compiler persists with the variable till the end of
the program. We can define static variables inside or outside the function. The default value of static variables is zero. The static
variables are alive till the execution of the program.
Syntax for the static variables in C language:
1. static datatype variable_name = value;
A static variable is generally used to count something. For example, the function openBakAccount() calls whenever a new account
opens in the bank. Then, to count the total number of opened accounts, we can declare a static variable in the function and increase
it on each function call.
16) What are some interesting facts about static variables in C?
Following is a list of some interesting facts about static variables in C:
o There are two types of static variables, static int variable and static auto variable. A static int variable remains in memory while
the program is running and a normal or auto variable is destroyed when a function call declared is over. For example, we can
use a static int variable to count the number of times a function is called, but we cannot use an auto variable for this purpose.
o Static variables are allocated memory in the data segment, not the stack segment.
o The default value for static variables is 0. Like global variables, they are initialized as 0 if not initialized explicitly.
o In C language, we can initialize the static variables using only constant literals.
o Static global variables and functions are also possible in C++. They are mainly used to limit the scope of a variable or function
to a file.
o We should not declare static variables inside the structure because the C compiler requires the entire structure elements to be
placed together.
17) How can you use a variable in a source file defined in another source file?
We can use the "extern" keyboard to declare a variable that allows accessing the variable in another file. This is how we can use a
variable in a source file defined in another source file.
18) How can you protect a character pointer by some accidental modification with the pointer
address?
We can use the constant character pointer (const char*) to protect a character pointer by accidentally modifying the pointer address.
It prevents unnecessary modifications with the pointer address in the string.
19) What are the main differences between CISC and RISC?
There are many differences between the RISC and CISC. Some of them are as follows:
RISC CISC
RISC stands for Reduced Instruction Set Computer. CISC stands for Complex Instruction Set Computer.
RISC does not consist of a memory unit. CISC consists of a memory unit.
RISC is a relatively faster processor than CISC in terms of calculations. CISC is a comparatively slower processor than RISC in terms of calculatio
RISC is used to ensure the simple decoding of operations. CISC doesn't ensure simple decoding of operations.
The execution time is RISC is low. The execution time is CISC is high.
20) What do you understand by a function pointer?
A function pointer is a pointer that points to a function instead of a variable. That's why a function pointer is completely different
from the class of other pointers. A function pointer stores the address of a particular function so that the concerned program can
avail of it through function invoking.
21) Can a variable be both constant and volatile in C?
Yes, a variable can be both constant and volatile in C. we can use constant and volatile both variables together. The volatile and const
variable together is used at the time of accessing the GPIO registers. In this case, its value is changed by the 'external factors' if a
switch or any output device is attached with GPIO. In this situation, the volatile variable is important because it ensures that the
compiler always read the value from the GPIO address and avoids making any assumption.
22) What is a dangling pointer in embedded C?
A dangling pointer is a pointer that points to a memory location that has been already free-ed by the application and is no longer in
use. Sometimes, the programmers fail to initialize the pointer with a valid address; these types of initialized pointers are known as
dangling pointers. Dangling pointers occur at the time of the object's destruction when the object is deleted or de-allocated from
memory without modifying the pointer's value. If you try to dereference a dangling pointer, it will potentially lead to a runtime error.
23) What is the size of a character, integer, integer pointer, and character pointer in C?
The size of the character is 1 byte, the size of the integer is 4 bytes, the size of the integer pointer, and the character pointer is 8 bytes
on a 64-bit machine and 4 bytes on a 32-bit machine.
24) What are some Real-Time applications of Embedded Processors?
Some real-time applications of Embedded Processors are:
o Dishwashers
o Automatic passengers’ cars
o Mobile Phones
o Television
o Medical equipment, etc.
25) What are some examples of the embedded systems to use in Aerospace Applications?
Some examples of the embedded systems to use in Aerospace Applications are:
o Flight control systems
o Autopilot mode
o A passenger in-flight embedded system
o Engine controllers
o Landing and takeoff controller etc.
26) How many bits that the Embedded Software supports?
The Embedded Software supports 8, 16 or 32 bit embedded processors.
27) What do you understand by a NULL pointer? What is its usage?
NULL is a macro defined in C. The Null pointer is a pointer that does not point to any valid location. The NULL pointer is defined when
we want to ensure that the pointer does not point to any valid location and not to use that pointer to change anything. Without using
a null pointer, we can't verify whether this pointer points to any valid location or not.
28) Are Countdown to zero loops better than Count_up_loops?
Yes, Countdown to zero loops are better than Count_up_loops because, at loop termination, comparison to zero can be optimized by
the compiler. Most of the processors have instructions for comparing to zero. So they don't need to load the loop variable and the
maximum value; subtract them and then compare them to zero. That is why count down to zero loops are better.
29) What are some examples of Embedded systems in automotive applications?
Following are some examples of Embedded systems in automotive applications:
o Traffic control systems
o Braking systems
o steer-by-wire systems
o Cruise control applications
o Airbag release systems
o Engine management units etc.
30) What are some examples of domestic appliances that use an Embedded System?
Following is a list of some examples of domestic appliances that use Embedded Systems:
o Smart Televisions
o Washing machines
o Microwave ovens
o Dishwashers
o Garage door controllers
o Video recorders and
o Security systems etc.
31) What do you understand by the term structure padding in Embedded C?
Structure padding is a concept used in the C programming language. It is used to add one or more empty bytes between the memory
addresses to align the data in the memory. The compiler automatically does it to ensure that all its members are byte aligned.
32) What are some examples of Medical Equipments that uses the concept of Embedded Systems?
Following are some examples of Medical Equipments that uses the concept of Embedded Systems:
o Anesthesia monitoring systems
o ECG monitors
o MRI Scanners
o Drug delivery systems
o Ultrasound equipment etc.
33) Which Defense Systems use the concept of Embedded Systems?
Following are some examples of Defense Systems that use the concept of Embedded Systems:
o Radio systems
o Radar systems
o Missile guidance systems
o Fighter aircraft flight control system
o Target guidance systems etc.
34) What do you understand by Machine Code?
Machine Code is the language of the computer rather than the programmer. A computer only accepts the instructions in the form of
machine code or object code. When a programmer interprets the code, it is complex and error-prone. Whether in languages such as
C, C++, and Java, all software must ultimately be translated into machine code to be executed by the computer.
35) What are the Discrete Components used in Embedded systems?
The list of Discrete Components used in Embedded systems is:
o Transistors
o Diodes
o Resistors
o Capacitor
36) What is the link between oscillator frequency and machine-cycle period?
A general rule specifies that the oscillator frequency directly determines the speed at which your application runs. So, in most cases,
if you double the oscillator frequency, the speed of the application would be doubled.
37) What is the full form of MIPS?
MIPS stands for Million Instructions Per Second. It is an approximate measure of a computer's raw processing power. It may be
misleading because measurement techniques often differ, and different computers may require different sets of instructions to
perform the same activity.
38) How can we improve the 8051 microcontroller performance?
The simplest way to improve the performance of the 8051 microcontrollers is to increase the clock frequency. The 8051
microcontrollers allow the use of clock speeds well beyond the 12MHz limit of the original devices. The best way to improve the
performance is to make internal changes to the microcontroller so that fewer oscillator cycles are required to execute each machine
instruction.
39) What is the range of maximum oscillator frequency and the peak performance in the 8051
microcontrollers?
The 8051 microcontroller has a maximum oscillator frequency of 12 MHz, and peak performance is 1 MIP.
40) What do you understand by Memory Fragmentation?
Memory Fragmentation is an issue that arises while using dynamic memory allocation. When we keep allocating and releasing memory
spaces over time, in the end, we will get non-contiguous memory blocks that are free, and our in-use variables are scattered
everywhere in the RAM. This is called memory fragmentation. This can potentially lead to dynamic memory allocation failure. For
example, if you have to allocate an array of 100 integers and there is no contiguous block of memory with that space, this causes a
runtime error. This is why we don't use dynamic memory allocation in embedded systems firmware in the first place.
41) What are inline functions in Embedded C?
Inline functions are the types of function whose definitions are small and be substituted at the place where its function call has
happened. The ARM compilers support inline functions with the keyword __inline. These functions have a small definition, and the
function body is substituted in each call to the inline function.
42) What are the types of memory in an Embedded System in C language?
Following are the types of memory in an Embedded System in C language:
o DRAM (Dynamic RAM)
o SRAM (Static RAM)
o Mask Read-only Memory (ROM)
o PROM (Programmable Read-Only Memory)
o UV EPROM (UV Erasable Programmable Read-Only Memory)
o EEPROM (Electrically - Erasable PROM)
1) What is C language?
C is a mid-level and procedural programming language. The Procedural programming language is also known as the structured
programming language is a technique in which large programs are broken down into smaller modules, and each module uses
structured code. This technique minimizes error and misinterpretation. More details.
2) Why is C known as a mother language?
C is known as a mother language because most of the compilers and JVMs are written in C language. Most of the languages which
are developed after C language has borrowed heavily from it like C++, Python, Rust, javascript, etc. It introduces new core concepts
like arrays, functions, file handling which are used in these languages. More details.
3) Why is C called a mid-level programming language?
C is called a mid-level programming language because it binds the low level and high -level programming language. We can use C
language as a System programming to develop the operating system as well as an Application programming to generate menu driven
customer driven billing system. More details.
4) Who is the founder of C language?
Dennis Ritchie. More details.
5) When was C language developed?
C language was developed in 1972 at bell laboratories of AT&T. More details.
6) What are the features of the C language?
The main features of C language are given below:
o Simple: C is a simple language because it follows the structured approach, i.e., a program is broken into parts
o Portable: C is highly portable means that once the program is written can be run on any machine with little or no modifications.
o Mid Level: C is a mid-level programming language as it combines the low- level language with the features of the high-level language.
o Structured: C is a structured language as the C program is broken into parts.
o Fast Speed: C language is very fast as it uses a powerful set of data types and operators.
o Memory Management: C provides an inbuilt memory function that saves the memory and improves the efficiency of our program.
o Extensible: C is an extensible language as it can adopt new features in the future.
More details.
7) What is the use of printf() and scanf() functions?
printf(): The printf() function is used to print the integer, character, float and string values on to the screen.
Following are the format specifier:
o %d: It is a format specifier used to print an integer value.
o %s: It is a format specifier used to print a string.
o %c: It is a format specifier used to display a character value.
o %f: It is a format specifier used to display a floating point value.
scanf(): The scanf() function is used to take input from the user.
More details.
8) What is the difference between the local variable and global variable in C?
Following are the differences between a local variable and global variable:
Basis for
comparison
Local variable Global variable
Declaration A variable which is declared inside function or block is known as a local
variable.
A variable which is declared outside function or block is kn
as a global variable.
Scope The scope of a variable is available within a function in which they are
declared.
The scope of a variable is available throughout the program
Access Variables can be accessed only by those statements inside a function in
which they are declared.
Any statement in the entire program can access variables.
Life Life of a variable is created when the function block is entered and
destroyed on its exit.
Life of a variable exists until the program is executing.
Storage Variables are stored in a stack unless specified. The compiler decides the storage location of a variable.
More details.
9) What is the use of a static variable in C?
Following are the uses of a static variable:
o A variable which is declared as static is known as a static variable. The static variable retains its value between multiple function calls.
o Static variables are used because the scope of the static variable is available in the entire program. So, we can access a static variable
anywhere in the program.
o The static variable is initially initialized to zero. If we update the value of a variable, then the updated value is assigned.
o The static variable is used as a common value which is shared by all the methods.
o The static variable is initialized only once in the memory heap to reduce the memory usage.
More details.
10) What is the use of the function in C?
Uses of C function are:
o C functions are used to avoid the rewriting the same code again and again in our program.
o C functions can be called any number of times from any place of our program.
o When a program is divided into functions, then any part of our program can easily be tracked.
o C functions provide the reusability concept, i.e., it breaks the big task into smaller tasks so that it makes the C program more
understandable.
More details.
11) What is the difference between call by value and call by reference in C?
Following are the differences between a call by value and call by reference are:
Call by value Call by reference
Description When a copy of the value is passed to the function, then the original value
is not modified.
When a copy of the value is passed to the function, then the orig
value is modified.
Memory
location
Actual arguments and formal arguments are created in separate memory
locations.
Actual arguments and formal arguments are created in the s
memory location.
Safety In this case, actual arguments remain safe as they cannot be modified. In this case, actual arguments are not reliable, as they are modifie
Arguments The copies of the actual arguments are passed to the formal arguments. The addresses of actual arguments are passed to their respec
formal arguments.
Example of call by value:
1. #include <stdio.h>
2. void change(int,int);
3. int main()
4. {
5. int a=10,b=20;
6. change(a,b); //calling a function by passing the values of variables.
7. printf("Value of a is: %d",a);
8. printf("n");
9. printf("Value of b is: %d",b);
10. return 0;
11. }
12. void change(int x,int y)
13. {
14. x=13;
15. y=17;
16. }
Output:
Value of a is: 10
Value of b is: 20
Example of call by reference:
1. #include <stdio.h>
2. void change(int*,int*);
3. int main()
4. {
5. int a=10,b=20;
6. change(&a,&b); // calling a function by passing references of variables.
7. printf("Value of a is: %d",a);
8. printf("n");
9. printf("Value of b is: %d",b);
10. return 0;
11. }
12. void change(int *x,int *y)
13. {
14. *x=13;
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx
Interview Questions C.docx

More Related Content

Similar to Interview Questions C.docx

Compiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCompiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCAFxX
 
Software Reverse Engineering in a Security Context
Software Reverse Engineering in a Security ContextSoftware Reverse Engineering in a Security Context
Software Reverse Engineering in a Security ContextLokendra Rawat
 
Complete c programming presentation
Complete c programming presentationComplete c programming presentation
Complete c programming presentationnadim akber
 
C and CPP Interview Questions
C and CPP Interview QuestionsC and CPP Interview Questions
C and CPP Interview QuestionsSagar Joshi
 
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksMykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksVadym Muliavka
 
Cs2253 coa-2marks-2013
Cs2253 coa-2marks-2013Cs2253 coa-2marks-2013
Cs2253 coa-2marks-2013Buvana Buvana
 
Consider the following interrupting system. The active-edge inputs o.pdf
Consider the following interrupting system. The active-edge inputs o.pdfConsider the following interrupting system. The active-edge inputs o.pdf
Consider the following interrupting system. The active-edge inputs o.pdffasttrackscardecors
 
Java Performance & Profiling
Java Performance & ProfilingJava Performance & Profiling
Java Performance & ProfilingIsuru Perera
 
DEVICE DRIVERS AND INTERRUPTS SERVICE MECHANISM.pdf
DEVICE DRIVERS AND INTERRUPTS  SERVICE MECHANISM.pdfDEVICE DRIVERS AND INTERRUPTS  SERVICE MECHANISM.pdf
DEVICE DRIVERS AND INTERRUPTS SERVICE MECHANISM.pdfAkritiPradhan2
 

Similar to Interview Questions C.docx (20)

Embedded C.pptx
Embedded C.pptxEmbedded C.pptx
Embedded C.pptx
 
interview questions.docx
interview questions.docxinterview questions.docx
interview questions.docx
 
Compiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flatteningCompiler optimizations based on call-graph flattening
Compiler optimizations based on call-graph flattening
 
Software Reverse Engineering in a Security Context
Software Reverse Engineering in a Security ContextSoftware Reverse Engineering in a Security Context
Software Reverse Engineering in a Security Context
 
Complete c programming presentation
Complete c programming presentationComplete c programming presentation
Complete c programming presentation
 
Unit-2.pptx
Unit-2.pptxUnit-2.pptx
Unit-2.pptx
 
TECHNOSCRIPTS FAQ 2.docx
TECHNOSCRIPTS FAQ 2.docxTECHNOSCRIPTS FAQ 2.docx
TECHNOSCRIPTS FAQ 2.docx
 
C and CPP Interview Questions
C and CPP Interview QuestionsC and CPP Interview Questions
C and CPP Interview Questions
 
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT TalksMykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
Mykhailo Zarai "Be careful when dealing with C++" at Rivne IT Talks
 
Cs2253 coa-2marks-2013
Cs2253 coa-2marks-2013Cs2253 coa-2marks-2013
Cs2253 coa-2marks-2013
 
Ss debuggers
Ss debuggersSs debuggers
Ss debuggers
 
C interview questions
C interview  questionsC interview  questions
C interview questions
 
Hardware-Software Codesign
Hardware-Software CodesignHardware-Software Codesign
Hardware-Software Codesign
 
Embedded C programming session10
Embedded C programming  session10Embedded C programming  session10
Embedded C programming session10
 
C programming session10
C programming  session10C programming  session10
C programming session10
 
Consider the following interrupting system. The active-edge inputs o.pdf
Consider the following interrupting system. The active-edge inputs o.pdfConsider the following interrupting system. The active-edge inputs o.pdf
Consider the following interrupting system. The active-edge inputs o.pdf
 
C Language Presentation.pptx
C Language Presentation.pptxC Language Presentation.pptx
C Language Presentation.pptx
 
Java Performance & Profiling
Java Performance & ProfilingJava Performance & Profiling
Java Performance & Profiling
 
C programming.pdf
C programming.pdfC programming.pdf
C programming.pdf
 
DEVICE DRIVERS AND INTERRUPTS SERVICE MECHANISM.pdf
DEVICE DRIVERS AND INTERRUPTS  SERVICE MECHANISM.pdfDEVICE DRIVERS AND INTERRUPTS  SERVICE MECHANISM.pdf
DEVICE DRIVERS AND INTERRUPTS SERVICE MECHANISM.pdf
 

Recently uploaded

Nervous System & Motherhood (made by SanyaKurd)
Nervous System & Motherhood (made by SanyaKurd)Nervous System & Motherhood (made by SanyaKurd)
Nervous System & Motherhood (made by SanyaKurd)SanyaaKurd
 
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureHONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureKweku Zurek
 
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docx
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docxSPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docx
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docxIT Industry
 
Accident dtection using opencv and using AI
Accident dtection using opencv and using AIAccident dtection using opencv and using AI
Accident dtection using opencv and using AIrk7ramesh2580
 
Time Management by Akshit Jain ctld .ppt
Time Management by Akshit Jain ctld .pptTime Management by Akshit Jain ctld .ppt
Time Management by Akshit Jain ctld .pptAkshit Jain
 
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureHONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureKweku Zurek
 

Recently uploaded (6)

Nervous System & Motherhood (made by SanyaKurd)
Nervous System & Motherhood (made by SanyaKurd)Nervous System & Motherhood (made by SanyaKurd)
Nervous System & Motherhood (made by SanyaKurd)
 
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureHONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
 
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docx
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docxSPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docx
SPACE POGO SHOWS PROJECTIONS APPMAKING DONE!.docx
 
Accident dtection using opencv and using AI
Accident dtection using opencv and using AIAccident dtection using opencv and using AI
Accident dtection using opencv and using AI
 
Time Management by Akshit Jain ctld .ppt
Time Management by Akshit Jain ctld .pptTime Management by Akshit Jain ctld .ppt
Time Management by Akshit Jain ctld .ppt
 
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochureHONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
HONOURABLE LAWRENCE BANDASOA TABASE funeral brochure
 

Interview Questions C.docx

  • 1. Q) What is the difference between C and embedded C? The C standard doesn’t care about embedded, but vendors of embedded systems usually provide standalone implementations with whatever amount of libraries they’re willing to provide. C is a widely-used general-purpose high-level programming language mainly intended for system programming. On the other side, Embedded C is an extension to the C programming language that provides support for developing efficient programs for embedded devices. It is not a part of the C language. Following are the comparison chart for traditional C language and Embedded C: C Language Embedded C Language C is a widely-used general-purpose high-level programming language. It is used for cross-development purposes C is a high-level programming language. It maintains by the C standard committee. The C standard doesn’t care about embedded. Embedded C is an extension to the C programming language that provides support for developing efficient programs for embedded devices. C is independent of hardware and its underlying architecture. Embedded C is dependent on the hardware architecture. C is mainly used for developing desktop applications. Mainly intended for system programming. Embedded C is used in embedded systems for microcontroller-based applications.
  • 2. Q) What is the volatile keyword? The volatile keyword is a type qualifier that prevents the objects from compiler optimization. According to C standard, an object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. You can also say that the value of the volatile-qualified object can be changed at any time without any action being taken by the code. If an object is qualified by the volatile qualifier, the compiler reloads the value from memory each time it is accessed by the program that means it prevents from cache a variable into a register. Reading the value from memory is the only way to check the unpredictable change of the value. Q) What is the use of volatile keyword? The volatile keyword is mainly used where we directly deal with GPIO, interrupt or flag Register. It is also used with a global variable or buffer which shared between the threads. Q) What is the difference between the const and volatile qualifiers in C? The const keyword is compiler-enforced and says that the program could not change the value of the object that means it makes the object nonmodifiable type. Let us see an example, const int a = 0; If we will try to modify the value of “a”, we will get the compiler error because “a” is qualified with const keyword that prevents to change the value of the”a” (integer variable). Another side, volatile prevents any compiler optimization and says that the value of the object can be changed by something that is beyond the control of the program and so that compiler will not make any assumption about the object. Let see an example,
  • 3. volatile int a; When the compiler sees the above declaration then it avoids to make any assumption regarding the “a” and in every iteration read the value from the address which is assigned to the “a”. Q) Can a variable be both constant and volatile in C? Yes, we can use both constant and volatile together. One of the great use of volatile and const keyword together is at the time of accessing the GPIO registers. In the case of GPIO, its value will be changed by the ‘external factors’ (if a switch or any output device is attached with GPIO), if it is configured as an input. In that situation, volatile plays an important role and ensures that the compiler always read the value from the GPIO address and avoid to make any assumption. After using the volatile keyword, you will get the proper value whenever you are accessing the ports but still here is one more problem because the pointer is not const type so it might be your program change the pointing address of the pointer. So we have to create a constant pointer with a volatile keyword. Syntax of declaration, int volatile * const PortRegister; How to read the above declaration,
  • 4. Q) Can we have a volatile pointer? Yes, we can create a volatile pointer in C language. // piData is a volatile pointer to an integer. int * volatile piData; Q) The Proper place to use the volatile keyword? A volatile is an important qualifier in C programming. Here I am pointing some places where we need to use the volatile keyword.  Accessing the memory-mapped peripherals register or hardware status register. #define COM_STATUS_BIT 0x00000006 uint32_t const volatile * const pStatusReg = (uint32_t*)0x00020000; unit32_t GetRecvData() { unit32_t RecvData;
  • 5. //Code to receive data while (((*pStatusReg) & COM_STATUS_BIT) == 0) { // Wait until flag does not set //Received data in RecvData } return RecvData; }  Sharing the global variables or buffers between the multiple threads.  Accessing the global variables in an interrupt routine or signal handler. volatile int giFlag = 0; ISR(void) { giFlag = 1; } int main(void) { while (!giFlag) { //do some work
  • 6. } return 0; } Q) What is ISR? An ISR refers to the Interrupt Service Routines. These are procedures stored at specific memory addresses which are called when a certain type of interrupt occurs. The Cortex-M processors family has the NVIC that manages the execution of the interrupt. Q) Can we pass any parameter and return a value from the ISR? An ISR returns nothing and not allow to pass any parameter. An ISR is called when a hardware or software event occurs, it is not called by the code, so that’s the reason no parameters are passed into an ISR. In the above line, we have already read that the ISR is not called by the code, so there is no calling code to read the returned values of the ISR. It is the reason that an ISR is not returned any value. Q) What is interrupt latency? Basically, interrupt latency is the number of clock cycles that are taken by the processor to respond to an interrupt request. This clock cycle number is count between the assertions of the interrupt request and the first instruction of the interrupt handler. Interrupt Latency on the Cortex-M processor family
  • 7. The Cortex-M processors have very low interrupt latency. In the below table, I have mentioned, Interrupt latency of Cortex-M processors with zero wait state memory systems. Processors Cycles with zero wait state memory Cortex-M0 16 Cortex-M0+ 15 Cortex-M3 12 Cortex-M4 12 Cortex-M7 12 Q) How do you measure interrupt latency? With the help of the oscilloscope, we can measure the interrupt latency. You need to take the following steps.  First takes two GPIOs.  Configure one GPIO to generate the interrupt and second for the toggling (if you want you can attach an LED).  Monitor the PIN (using the oscilloscope or analyzer) which you have configured to generate the interrupt.  Also, monitor (using the oscilloscope or analyzer) the second pin which is toggled at the beginning of the interrupt service routine.  When you will generate the interrupt then the signal of both GPIOs will change.
  • 8. The interval between the two signals (interrupt latency) may be easily read from the instrument. Q) How to reduce interrupt latency? The interrupt latency depends on many factors, some factors I am mentioning in the below statements.  Platform and interrupt controller.  CPU clock speed.  Timer frequency  Cache configuration.  Application program. So using the proper selection of platforms and processors we can easily reduce the interrupt latency. We can also reduce the interrupt latency by making the ISR shorter and avoid to calling a function within the ISR. Q) Is it safe to call printf() inside Interrupt Service Routine (ISR)? It is not a good idea to call the printf() insider the ISR. The printf function is not reentrant, thread-safe. Q) Can we put a breakpoint inside ISR? Putting a breakpoint inside ISR is not a good idea. Yes - in an emulator.
  • 9. Otherwise, no. It's difficult to pull off, and a bad idea in any case. ISRs are (usually) supposed to work with the hardware, and hardware can easily behave very differently when you leave a gap of half a second between each instruction. Set up some sort of logging system instead. ISRs also ungracefully "steal" the CPU from other processes, so many operating systems recommend keeping your ISRs extremely short and doing only what is strictly necessary (such as dealing with any urgent hardware stuff, and scheduling a task that will deal with the event properly). So in theory, ISRs should be so simple that they don't need to be debugged. If it's hardware behavior that's the problem, use some sort of logging instead, as I've suggested. If the hardware doesn't really mind long gaps of time between instructions, then you could just write most of the driver in user space - and you can use a debugger on that! Q) Explain the interrupt execution sequence? An interrupt is an event that alters the sequence in which the processor executes instructions. An interrupt might be planned (specifically requested by the currently running program) or unplanned (caused by an event that might or might not be related to the currently running program). Q) What is the difference between an uninitialized pointer and a null pointer? Answer: An uninitialized pointer is a pointer that points unknown memory location. The behavior of the uninitialized pointer is undefined. If you try to dereference the uninitialized pointer code behavior will undefine. According to C standard, an integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. The behavior of the uninitialized pointer is defined. When you try to dereference the null pointer then your code will crash. Q) What are the causes of Interrupt Latency?
  • 10.  The first delay is typically caused by hardware: The interrupt request signal needs to be synchronized to the CPU clock. Depending on the synchronization logic, up to 3 CPU cycles may expire before the interrupt request has reached the CPU core.  The CPU will typically complete the current instruction, which may take several cycles. On most systems, divide, push-multiple or memory-copy instructions are the most time-consuming instructions to execute. On top of the cycles required by the CPU, additional cycles are often required for memory accesses. In an ARM7 system, the instruction STMDB SP!,{R0-R11, LR} typically is the worst-case instruction, storing 13 registers of 32-bits each to the stack, and takes 15 clock cycles to complete.  The memory system may require additional cycles for wait states.  After completion of the current instruction, the CPU performs a mode switch or pushes registers on the stack (typically PC and flag registers). Modern CPUs such as ARM generally perform a mode switch, which takes fewer CPU cycles than saving registers.  Pipeline fill: Most modern CPUs are pipelined. Execution of an instruction happens in various stages of the pipeline. An instruction is executed when it has reached its final stage of the pipeline. Since the mode switch has flushed the pipeline, a few extra cycles are required to refill the pipeline. Q) Can we use any function inside ISR? Yes, you can call a function within the ISR but it is not recommended because it can increase the interrupt latency and decrease the performance of the system. If you want to call a nested function within the ISR, you need to read the datasheet of your microcontroller because some vendors have a limit to how many calls can be nested. One important point needs to remember the function that is called from the ISR should be re-entrant. If the called function is not re- entrant, it could create issues. For example, If the function is not reentrant and supposes that it is called by another part of the code besides the ISR. So the problem will be invoked when if the ISR calls the same function which is already invoked outside of the ISR?
  • 11. Q) What is a nested interrupt? In a nested interrupt system, an interrupt is allowed any time and anywhere even an ISR is executed. But, only the highest priority ISR will be executed immediately. The second-highest priority ISR will be executed after the highest one is completed. The rules of a nested interrupt system are:  All interrupts must be prioritized.  After initialization, any interrupts are allowed to occur anytime and anywhere.  If a low-priority ISR is interrupted by a high-priority interrupt, the high-priority ISR is executed.  If a high-priority ISR is interrupted by a low-priority interrupt, the high-priority ISR continues executing.  The same priority ISRs must be executed by time order If you want to learn STM32 from scratch, you should follow this course “Mastering Microcontroller with Embedded Driver Development“. The course contains video lectures of 18.5-hours length covering all topics like, Microcontroller & Peripheral Driver Development for STM32 GPIO, I2C, SPI, USART using Embedded C.
  • 12. Q) What is NVIC in ARM Cortex? The Nested Vector Interrupt Controller (NVIC) in the Cortex-M processor family is an example of an interrupt controller with extremely flexible interrupt priority management. It enables programmable priority levels, automatic nested interrupt support, along with support for multiple interrupt masking, whilst still being very easy to use by the programmer. The Cortex-M3 and Cortex-M4 processors the NVIC supports up to 240 interrupt inputs, with 8 up to 256 programmable priority levels
  • 13. Q) Can we change the interrupt priority level of the Cortex-M processor family? Yes. We can change the priority levels of the interrupts by changing the corresponding bit in the Interrupt Priority (IP) register as shown in the following figure. A low priority interrupt can only be interrupted by the high priority interrupt, but not interrupted by another low priority interrupt. Q) Explain Interrupts tail-chaining – ARM?
  • 14. Tail-chaining is the back-to-back processing of exceptions without the overhead of state saving and restoration between interrupts. That means handling the pending interrupts without repeating the stacking. The processor tail-chains if a pending interrupt has higher priority than all stacked exceptions. For more detail, you can read Cortex-Manual. Q) Why is the “C” language mostly preferred over assembly language? C helps programmers focus on the structure of the code rather than the low-level demands of the CPU. They can organize code into components, such as functions and files and they have ways of managing the complexity of a project; without thinking about the nitty-gritty of issues such as how function calls work. Since C is a portable language, code can be organized into general-purpose libraries that can be used on any platform, often with no modification. It is a great weapon against ‘reinventing the wheel. Q) What is the start-up code? A start-up code is called before the main function, it creates a basic platform for the application. It is a small block of code that is written in assembly language. There are the following parts of the start-up code.  Declaration of the Stack area.  Declaration of the Heap area.  Vector table.  Reset handler code.  Other exception handler codes.
  • 15. Q) What are the start-up code steps? Start-up code for C programs usually consists of the following actions, performed in the order described:  Disable all interrupts.  Copy any initialized data from ROM to RAM.  Zero the uninitialized data area.  Allocate space for and initialize the stack.  Initialize the processor’s stack pointer.  Create and initialize the heap.  Enable interrupts.  Call main. Q) Infinite loops often arise in embedded systems. How do you code an infinite loop in C? In embedded systems, infinite loops are generally used. If I talked about a small program to control a led through the switch, in that scenario an infinite loop will be required if we are not going through the interrupt. There are different ways to create an infinite loop, here I am mentioning some methods. Method 1: while(1) { // task } Method 2: for(;;) { // task
  • 16. } Method 3: Loop: goto Loop; Q) How to access the fixed memory location in embedded C? Let us see an example code to understand this concept. This question is one of the best questions of the embedded C interview question. Suppose in an application, you need to access a fixed memory address. So you need to follow the below steps, these are high-level steps. //Memory address, you want to access #define RW_FLAG 0x1FFF7800 //Pointer to access the Memory address volatile uint32_t *flagAddress = NULL; //variable to stored the read value uint32_t readData = 0; //Assign addres to the pointer flagAddress = (volatile uint32_t *)RW_FLAG; //Read value from memory * flagAddress = 12; // Write //Write value to the memory
  • 17. readData = * flagAddress; Q) Difference between RISC and CISC processor? The RISC (reduced instruction set computer) and CISC (Complex instruction set computer) are the processors ISA (instruction set architecture). There are the following difference between both architecture: RISC CISC Acronym It stands for ‘Reduced Instruction Set Computer’. It stands for ‘Complex Instruction Set Computer’. Definition The RISC processors have a smaller set of instructions with few addressing nodes. The CISC processors have a larger set of instructions with many addressing nodes. Memory unit It has no memory unit and uses a separate hardware to implement instructions. It has a memory unit to implement complex instructions. Program It has a hard-wired unit of programming. It has a micro-programming unit.
  • 18. Design It is a complex complier design. It is an easy complier design. Calculations The calculations are faster and precise. The calculations are slow and precise. Decoding Decoding of instructions is simple. Decoding of instructions is complex. Time Execution time is very less. Execution time is very high. External memory It does not require external memory for calculations. It requires external memory for calculations. Pipelining Pipelining does function correctly. Pipelining does not function correctly. Stalling Stalling is mostly reduced in processors. The processors often stall. Code expansion Code expansion can be a problem. Code expansion is not a problem. Disc space The space is saved. The space is wasted.
  • 19. Applications Used in high-end applications such as video processing, telecommunications and image processing. Used in low-end applications such as security systems, home automations, etc. Q) What is the stack overflow? If your program tries to access beyond the limit of the available stack memory then stack overflow occurs. In other words, you can say that a stack overflow occurs if the call stack pointer exceeds the stack boundary. If stack overflow occurs, the program can crash or you can say that segmentation fault that is the result of the stack overflow. Q) What is the cause of the stack overflow? In the embedded application we have a little amount of stack memory as compare to the desktop application. So we have to work on embedded application very carefully either we can face the stack overflow issues that can be a cause of the application crash. Here, I have mentioned some causes of unwanted use of the stack.  Improper use of the recursive function.  Passing to many arguments in the function.  Passing a structure directly into a function.  Nested function calls.  Creating a huge size local array. Q) What is the difference between the I2c and SPI communication Protocols?
  • 20. In the embedded system, I2C and SPI both play an important role. Both communication protocols are the example of synchronous communication but still, both have some important differences. The important difference between the I2C and SPI communication protocol.  I2C supports half-duplex while SPI is full-duplex communication.  I2C requires only two-wire for communication while SPI requires three or four-wire for communication (depends on requirement).  I2C is slower as compared to the SPI communication.  I2C draws more power than SPI.  I2C is less susceptible to noise than SPI.  I2C is cheaper to implement than the SPI communication protocol.  I2C work on wire and logic and it has a pull-up resistor while there is no requirement of a pull-up resistor in case of the SPI.  In I2C communication we get the acknowledgment bit after each byte, it is not supported by the SPI communication protocol.  I2C ensures that data sent is received by the slave device while SPI does not verify that data is received correctly.  I2C supports multi-master communication while multi-master communication is not supported by the SPI.  One great difference between I2C and SPI is that I2C supports multiple devices on the same bus without any additional select lines (work based on device address) while SPI requires additional signal (slave select lines) lines to manage multiple devices on the same bus.  I2C supports arbitration while SPI does not support the arbitration.  I2C support the clock stretching while SPI does not support the clock stretching.  I2C can be locked up by one device that fails to release the communication bus.  I2C has some extra overhead due to start and stop bits.  I2C is better for long-distance while SPI is better for the short distance.  In the last I2C developed by NXP while SPI by Motorola. Q) What is the difference between Asynchronous and Synchronous Communication? There are the following differences between asynchronous and synchronous communication.
  • 21. Asynchronous Communication Synchronous Communication There is no common clock signal between the sender and receivers. Communication is done by a shared clock. Sends 1 byte or character at a time. Sends data in the form of blocks or frames. Slow as compare to synchronous communication. Fast as compare to asynchronous communication. Overhead due to start and stop bit. Less overhead. Ability to communicate long distance. Less as compared to asynchronous communication. A start and stop bit used for data synchronization. A shared clock is used for data synchronization. Economical Costly RS232, RS485 I2C, SPI. Q) What is the difference between RS232 and RS485?
  • 22. The RS232 and RS485 is an old serial interface. Both serial interfaces are the standard for data communication. This question is also very important and generally ask by an interviewer. Some important difference between the RS232 and RS485 Parameter RS232 RS485 Line configuration Single –ended differential Numbers of devices 1 transmitter 1 receiver 32 transmitters 32 receivers Mode of operation Simplex or full duplex Simplex or half duplex Maximum cable length 50 feet 4000 feet Maximum data rate 20 Kbits/s 10 Mbits/s signaling unbalanced balanced Typical logic levels +-5 ~ +-15V +-1.5 ~ +-6V Minimum receiver input impedance 3 ~ 7 K-ohm 12 K-ohm
  • 23. Receiver sensitivity +-3V +-200mV Q) What is the difference between Bit Rate and Baud Rate? Bit Rate Baud Rate Bit rate is the number of bits per second. Baud rate is the number of signal units per second. It determines the number of bits traveled per second. It determines how many times the state of a signal is changing. Cannot determine the bandwidth. It can determine how much bandwidth is required to send the signal. This term generally used to describe the processor efficiency. This term generally used to describe the data transmission over the channel. Bit rate = baud rate x the number of bits per signal unit Baud rate = bit rate / the number of bits per signal unit Q) What is segmentation fault in C?
  • 24. A segmentation fault is a common problem that causes programs to crash. A core file (core dumped file) also associated with a segmentation fault that is used by the developer to finding the root cause of the crashing (segmentation fault). Generally, the segmentation fault occurs when a program tried to access a memory location that is not allowed to access or tried to access a memory location in a way that is not allowed (tried to access read-only memory). Q) What are the common causes of segmentation fault in C? There are many reasons for the segmentation fault, here I am listing some common causes of the segmentation fault.  Dereferencing NULL pointers.  Tried to write read-only memory (such as code segment).  Trying to access a nonexistent memory address (outside process’s address space).  Trying to access memory the program does not have rights to (such as kernel structures in process context).  Sometimes dereferencing or assigning to an uninitialized pointer (because might point an invalid memory) can be the cause of the segmentation fault.  Dereferencing the freed memory (after calling the free function) can also be caused by the segmentation fault.  A stack overflow is also caused by the segmentation fault.  A buffer overflow (try to access the array beyond the boundary) is also a cause of the segmentation fault. Q) What is the difference between Segmentation fault and Bus error? In the case of segmentation fault, SIGSEGV (11) signal is generated. Generally, a segmentation fault occurs when the program tries to access the memory to which it doesn’t have access to. In below I have mentioned some scenarios where SIGSEGV signal is generated.  When trying to de-referencing a NULL pointer.  Trying to access memory which is already de-allocated (trying to use dangling pointers).
  • 25.  Using uninitialized pointer(wild pointer).  Trying to access memory that the program doesn’t own (eg. trying to access an array element out of array bounds). In case of a BUS error, SIGBUS (10) signal is generated. The Bus error issue occurs when a program tries to access an invalid memory or unaligned memory. The bus error comes rarely as compared to the segmentation fault. In below I have mentioned some scenarios where SIGBUS signal is generated.  Non-existent address.  Unaligned access.  Paging errors Q) Size of the integer depends on what? The C standard is explained that the minimum size of the integer should be 16 bits. Some programing language is explained that the size of the integer is implementation-dependent but portable programs shouldn’t depend on it. Primarily the size of integer depends on the type of the compiler which has written by compiler writer for the underlying processor. You can see compilers merrily changing the size of integer according to convenience and underlying architectures. So it is my recommendation to use the C99 integer data types ( uin8_t, uin16_t, uin32_t ..) in place of standard int. Q) Are integers signed or unsigned? According to the C standard, an integer data type is by default signed. So if you create an integer variable, it can store both positive and negative values. For more details on signed and unsigned integers, check out: A closer look at signed and unsigned integers in C
  • 26. Q) What is a difference between unsigned int and signed int in C? The signed and unsigned integer type has the same storage (according to the standard at least 16 bits) and alignment but still, there is a lot of difference them, in bellows lines, I am describing some difference between the signed and unsigned integer.  A signed integer can store the positive and negative value both but beside it unsigned integer can only store the positive value.  The range of nonnegative values of a signed integer type is a sub-range of the corresponding unsigned integer type. For example, Assuming the size of the integer is 2 bytes. signed int -32768 to +32767 unsigned int 0 to 65535  When computing the unsigned integer, it never gets overflow because if the computation result is greater than the largest value of the unsigned integer type, it is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type. For example, Computational Result % (Largest value of the unsigned integer+1)  The overflow of the signed integer type is undefined.  If Data is signed type negative value, the right shifting operation of Data is implementation-dependent but for the unsigned type, it would be Data/ 2pos.  If Data is signed type negative value, the left shifting operation of Data shows the undefined behavior but for the unsigned type, it would be Data x 2pos. Q) What is the difference between a macro and a function?
  • 27. Q) What is the difference between typedef & Macros? Let’s see the short description of the typedef and macro to understand the difference between them. typedef: The C language provides a very important keyword typedef for defining a new name for existing types. The typedef is the compiler directive mainly use with user-defined data types (structure, union or enum) to reduce their complexity and increase code readability and portability. Syntax, typedef type NewTypeName;
  • 28. Let’s take an example, typedef unsigned int UnsignedInt; Now UnsignedInt is a new type and using it, we can create a variable of unsigned int. So in the below example, Mydata is unsigned int variable. UnsignedInt Mydata; Note: A typedef creates synonyms or a new name for existing types it does not create new types. Macro: A macro is a pre-processor directive and it replaces the value before compiling the code. One of the major problems with the macro is that there is no type checking. Generally, the macro is used to create the alias, in C language. A macro is also used as a file guard in C and C++. Syntax, #define MACRO_NAME MACRO_VALUE Let’s take an example, #define VALUE 10 Now VALUE becomes 10 in your program. You can use the VALUE in place of the 10. For more details, you can see below-mentioned articles,
  • 29.  Macro in C.  typedef vs #define in C.  typedef in C. Q) What do you mean by enumeration in C? An enum in C is a user-defined data type. It consists set of named constant integers. Using the enum keyword, we can declare an enumeration type by using the enumeration tag (optional) and a list of named integer. Basically, we used the enum to increase the code readability and with enum easy to debug the code as compared to symbolic constant (macro). The most important property of enum is that it follows the scope rule and the compiler automatically assigns the value to its member constant. Note: A variable of enumeration type stores one of the values of the enumeration list defined by that type. Syntax of enum, enum Enumeration_Tag { Enumeration_List }; The Enumeration_Tag specifies the enumeration type name. The Enumeration_List is a comma-separated list of named constant. Example, enum FLASH_ERROR { DEFRAGMENT_ERROR, BUS_ERROR}; For more details, you can see below-mentioned articles,
  • 30.  Macro in C.  enum in C.  typedef vs #define in C. Q) What is the difference between const and macro?  The const keyword is handled by the compiler, in another hand, a macro is handled by the preprocessor directive.  const is a qualifier that is modified the behavior of the identifier but macro is preprocessor directive.  There is type checking is occurred with const keyword but does not occur with #define.  const is scoped by C block, #define applies to a file.  const can be passed as a parameter (as a pointer) to the function. In the case of call by reference, it prevents to modify the passed object value. Q) How to set, clear, toggle and checking a single bit in C? Note: Here I assume that bit of register starts with 0th position, it means the 2nd position is actually 3rd bits. D7 D6 D5 D4 D3 D2 D1 D0 Setting N-th Bit Setting an N-th bit means that if the N-th bit is 0, then set it to 1 and if it is 1 then leave it unchanged. In C, bitwise OR operator (|) use to set a bit of integral data type. As we know that | (Bitwise OR operator) evaluates a new integral value in which each bit position is 1 only when operand’s (integer type) has a 1 in that position. In simple words, you can say that “Bitwise OR ” of two bits is always one if any one of them is one. That means,
  • 31. 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1 Algorithm to set the bits: Number | = (1UL << nth Position); Clearing a Bit Clearing a bit means that if N-th bit is 1, then clear it to 0 and if it is 0 then leave it unchanged. Bitwise AND operator (&) use to clear a bit of integral data type. “AND” of two bits is always zero if any one of them is zero. That means, 0 & 0 = 0 1 & 0 = 0 0 & 1 = 0 1 & 1 = 1 Algorithm to clear the bit: To clear the nth bit, first, you need to invert the string of bits then AND it with the number. Number &= ~(1UL << nth Position);
  • 32. Checking a Bit To check the nth bit, shift the ‘1’ nth position toward the left and then “AND” it with the number. An algorithm to check the bit Bit = Number & (1UL << nth); Toggling a Bit Toggling a bit means that if the N-th bit is 1, then change it to 0 and if it is 0 then change it to 1. Bitwise XOR (^) operator use to toggle the bit of an integral data type. To toggle the nth bit shift the ‘1’ nth position toward the left and “XOR” it. That means, 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0 An algorithm to toggle the bits Number ^= (1UL << nth Position); Q) What will be the output of the below C program? #include <stdio.h> int main() {
  • 33. char var = 10; void *ptr = &var; printf("%d %d",*(char*)ptr,++(*(char*)ptr)); return 0; } Output: undefined Explanation: Due to the sequence point the output vary on a different platform. Q) Write a program swap two numbers without using the third variable? Let’s assume a, b two numbers, there are a lot of methods two swap two numbers without using the third variable. Method 1( (Using Arithmetic Operators): #include <stdio.h> int main() { int a = 10, b = 5; // algo to swap 'a' and 'b' a = a + b; // a becomes 15 b = a - b; // b becomes 10 a = a - b; // fonally a becomes 5 printf("After Swapping the value of: a = %d, b = %dnn", a, b);
  • 34. return 0; } Method 2 (Using Bitwise XOR Operator): #include <stdio.h> int main() { int a = 10, b = 5; // algo to swap 'a' and 'b' a = a ^ b; // a becomes (a ^ b) b = a ^ b; // b = (a ^ b ^ b), b becomes a a = a ^ b; // a = (a ^ b ^ a), a becomes b printf("After Swapping the value of: a = %d, b = %dnn", a, b); return 0; } Q) What will be the output of the below C program? #include <stdio.h> #define ATICLEWORLD 0x01 #define AUTHOR 0x02 int main()
  • 35. { unsigned char test = 0x00; test|=ATICLEWORLD; test|=AUTHOR; if(test & ATICLEWORLD) { printf("I am an Aticleworld"); } if( test & AUTHOR) { printf(" Author"); } return 0; } Output: I am an Aticleworld Author Explanation:When we are OR-ing the test( unsigned char variable) with 0x01 and 0x02. The value of test will be 0x03 (because initially test value is 0x00). When we perform the And-ing operatotion on test with 0x01 and 0x02 then expresstion will return non- zero value, for example (0x00000011 & 0x00000001 => 0x00000010). Q) What is meant by structure padding? In the case of structure or union, the compiler inserts some extra bytes between the members of structure or union for the alignment, these extra unused bytes are called padding bytes and this technique is called padding.
  • 36. Padding has increased the performance of the processor at the penalty of memory. In structure or union data members aligned as per the size of the highest bytes member to prevent the penalty of performance. Note: Alignment of data types mandated by the processor architecture, not by language. You can see the below Articles,  Brief Introduction of structure padding in C.  Top 11 structure padding interview questions in C. Q) What is the endianness? The endianness is the order of bytes to store data in memory and it also describes the order of byte transmission over a digital link. In the memory data store in which order depends on the endianness of the system, if the system is big-endian then the MSB byte store first (means at lower address) and if the system is little-endian then LSB byte store first (means at lower address). Some examples of the little-endian and big-endian system. Q) What is big-endian and little-endian?
  • 37. Suppose 32 bits Data is 0x11223344. Big-endian The most significant byte of data stored at the lowest memory address. Little-endian The least significant byte of data stored at the lowest memory address.
  • 38. Note: Some processor has the ability to switch one endianness to other endianness using the software means it can perform like both big-endian or little-endian at a time. This processor is known as the Bi-endian, here are some architecture (ARM version 3 and above, Alpha, SPARC) who provide the switchable endianness feature. Q) Write a C program to check the endianness of the system. Method 1: #include <stdio.h> #include <stdlib.h> #include <inttypes.h> int main(void) { uint32_t u32RawData; uint8_t *pu8CheckData; u32RawData = 0x11223344; //Assign data pu8CheckData = (uint8_t *)&u32RawData; //Type cast if (*pu8CheckData == 0x44) //check the value of lower address { printf("little-Endian"); } else if (*pu8CheckData == 0x11) //check the value of lower address
  • 39. { printf("big-Endian"); } return 0; } Method 2: #include <stdio.h> #include <stdlib.h> #include <inttypes.h> typedef union { uint32_t u32RawData; // integer variable uint8_t au8DataBuff[4]; //array of character } RawData; int main(void) { RawData uCheckEndianess; uCheckEndianess.u32RawData = 0x11223344; //assign the value if (uCheckEndianess.au8DataBuff[0] == 0x44) //check the array first index value {
  • 40. printf("little-endian"); } else if (uCheckEndianess.au8DataBuff[0] == 0x11) //check the array first index value { printf("big-endian"); } return 0; } Q) How to Convert little-endian to big-endian vice versa in C? We can convert little-endian to big-endian or vice versa using the C programs. So let us see few ways to convert one endian to another. #include <stdio.h> #include <inttypes.h> //Function to change one endian to another uint32_t ChangeEndianness(uint32_t u32Value) { uint32_t u32Result = 0; u32Result |= (u32Value & 0x000000FF) << 24; u32Result |= (u32Value & 0x0000FF00) << 8;
  • 41. u32Result |= (u32Value & 0x00FF0000) >> 8; u32Result |= (u32Value & 0xFF000000) >> 24; return u32Result; } int main() { uint32_t u32CheckData = 0x11223344; uint32_t u32ResultData =0; //swap the data u32ResultData = ChangeEndianness(u32CheckData); //converted data printf("0x%xn",u32ResultData); return 0; } Output: 0x44332211
  • 42. Q) What is static memory allocation and dynamic memory allocation? According to C standard, there are four storage duration, static, thread (C11), automatic, and allocated. The storage duration determines the lifetime of the object. The static memory allocation: Static Allocation means, an object has an external or internal linkage or declared with static storage-class. It’s initialized only once, before program startup and its lifetime is throughout the execution of the program. A global and static variable is an example of static memory allocation. The dynamic memory allocation: In C language, there are a lot of library functions (malloc, calloc, or realloc,..) which are used to allocate memory dynamically. One of the problems with dynamically allocated memory is that it is not destroyed by the compiler itself that means it is the responsibility of the user to deallocate the allocated memory. When we allocate the memory using the memory management function, they return a pointer to the allocated memory block and the returned pointer is pointing to the beginning address of the memory block. If there is no space available, these functions return a null pointer.
  • 43. Q) What is the memory leak in C? A memory leak is a common and dangerous problem. It is a type of resource leak. In C language, a memory leak occurs when you allocate a block of memory using the memory management function and forget to release it. int main () { char * pBuffer = malloc(sizeof(char) * 20); /* Do some work */ return 0; /*Not freeing the allocated memory*/ } Note: once you allocate a memory than allocated memory does not allocate to another program or process until it gets free. Q) What is the output of the below C code? #include <stdio.h> int main(void) { int var; for(var = -3 ; var <sizeof(int) ; var++) { printf("Hello Aticleworldn"); } return 0;
  • 44. } Output: Nothing will print. Explanation: In the above C code, We are trying to compare a signed int variable “var” with size_t, which is defined as an unsigned long int (sizeof operator return size_t). Here integer promotion occurs and the compiler will convert signed int -3 to unsigned long int and resultant value would very large as compare to int size. So the for loop condition will be false and there won’t be any iteration. Q) What is the output of the below C code? #include <stdio.h> int main() { int pos = 14; float data = 15.2; printf("%*f",pos,data); return 0; } Output: print 15.200000 with 6 spaces. Explanation: The output will be ______15.20000, where _ has been used to represent space here. The program will print a floating- point number with a width of at least 14 and since no precision has been specified, it will take the default precision of 6 decimal point for format specifier “f”.
  • 45. The symbol * can be used with a format specifier to replace the width or precision. Here it has been used to replace the width. The general format for %f can be seen as %(width). (precision)f. When * is used to specify width or precision. Let see a C code for the same. #include <stdio.h> int main() { int pos = 14; float data = 15.2; printf("%*.*f",pos,2,data); return 0; } Output: print 15.20 with spaces. Q) What is the difference between malloc and calloc? A malloc and calloc are memory management functions. They are used to allocate memory dynamically. Basically, there is no actual difference between calloc and malloc except that the memory that is allocated by calloc is initialized with 0. In C language,calloc function initialize the all allocated space bits with zero but malloc does not initialize the allocated memory. These both function also has a difference regarding their number of arguments, malloc takes one argument but calloc takes two.
  • 46. Q) What is the purpose of realloc( )? The realloc function is used to resize the allocated block of memory. It takes two arguments first one is a pointer to previously allocated memory and the second one is the newly requested size. The calloc function first deallocates the old object and allocates again with the newly specified size. If the new size is lesser to the old size, the contents of the newly allocated memory will be the same as prior but if any bytes in the newly created object goes beyond the old size, the values of the exceeded size will be indeterminate. Syntax: void *realloc(void *ptr, size_t size); Let’s see an example to understand the working of realloc in C language. #include <stdio.h> #include <stdlib.h> #include <string.h> int main () { char *pcBuffer = NULL; /* Initial memory allocation */ pcBuffer = malloc(8); //make sure piBuffer is valid or not if (pcBuffer == NULL) {
  • 47. // allocation failed, exit from the program fprintf(stderr, "Out of memory!n"); exit(1); } strcpy(pcBuffer, "aticle"); printf("pcBuffer = %sn", pcBuffer); /* Reallocating memory */ pcBuffer = realloc(pcBuffer, 15); if (pcBuffer == NULL) { // allocation failed, exit from the program fprintf(stderr, "Out of memory!n"); exit(1); } strcat(pcBuffer, "world"); printf("pcBuffer = %sn", pcBuffer); //free the allocated memory free(pcBuffer); return 0; } Output: pcBuffer = aticle pcBuffer = aticleworld
  • 48. Note: It should be used for dynamically allocated memory but if a pointer is a null pointer, realloc behaves like the malloc function. Q) What is the return value of malloc (0)? If the size of the requested space is zero, the behavior will be implementation-defined. The return value of the malloc could be a null pointer or it shows the behavior of that size is some nonzero value. It is suggested by the standard to not use the pointer to access an object that is returned by the malloc while the size is zero. Q) What is dynamic memory fragmentation? The memory management function is guaranteed that if memory is allocated, then it would be suitably aligned to any object which has the fundamental alignment. The fundamental alignment is less than or equal to the largest alignment that’s supported by the implementation without an alignment specification. One of the major problems with dynamic memory allocation is fragmentation, basically, fragmentation occurred when the user does not use the memory efficiently. There are two types of fragmentation, external fragmentation, and internal fragmentation. The external fragmentation is due to the small free blocks of memory (small memory hole) that is available on the free list but the program not able to use it. There are different types of free list allocation algorithms that used the free memory block efficiently. To understand the external fragmentation, consider a scenario where a program has 3 contiguous blocks of memory and the user frees the middle block of memory. In that scenario, you will not get a memory, if the required block of memory is larger than a single block of memory (but smaller or equal to the aggregate of the block of memory).
  • 49. The internal fragmentation is wasted of memory that is allocated for rounding up the allocated memory and in bookkeeping (infrastructure), the bookkeeping is used to keep the information of the allocated memory. Whenever we called the malloc function then it reserves some extra bytes (depend on implementation and system) for bookkeeping. This extra byte is reserved for each call of malloc and becomes a cause of the internal fragmentation.
  • 50. For example, See the below code, the programmer may think that the system will be allocated 8 *100 (800) bytes of memory but due to bookkeeping (if 8 bytes) system will be allocated 8*100 extra bytes. This is an internal fragmentation, where 50% of the heap waste. char *acBuffer[100]; int main() { int iLoop = 0; while(iLoop < 100) { acBuffer[iLoop ] = malloc(8); ++iLoop; } } Q) How is the free work in C? When we call the memory management functions (malloc, calloc or realloc) then these functions keep extra bytes for bookkeeping. Whenever we call the free function and pass the pointer that is pointing to allocated memory, the free function gets the bookkeeping information and release the allocated memory. Anyhow if you or your program change the value of the pointer that is pointing to the allocated address, the calling of the free function gives the undefined result. ____ The allocated block ____ / +--------+--------------------+
  • 51. | Header | Your data area ... | +--------+--------------------+ ^ | +-- Returned Address Let us see a program to understand the above concept. The behavior of the below program is not defined. #include <stdio.h> #include <stdlib.h> int main() { char *pcBuffer = NULL; //Allocate the memory pcBuffer = malloc(sizeof(char) * 16); //make sure piBuffer is valid or not if (pcBuffer == NULL) { // allocation failed, exit from the program fprintf(stderr, "Out of memory!n"); exit(1); }
  • 52. //Increment the pointer pcBuffer++; //Call free function to release the allocated memory free(pcBuffer); return 0; } OutPut: Undefined Result Q) What is a Function Pointer? A function pointer is similar to the other pointers but the only difference is that it points to a function instead of a variable. In another word, we can say that a function pointer is a type of pointer that store the address of a function and these pointed function can be invoked by function pointer in a program whenever required. Q) How to declare a pointer to a function in C? The syntax for declaring function pointer is very straightforward. It seems difficult in beginning but once you are familiar with function pointer then it becomes easy. The declaration of a pointer to a function is similar to the declaration of a function. That means the function pointer also requires a return type, declaration name, and argument list. One thing that you need to remember here is, whenever you declare the function pointer in the program then the declaration name is preceded by the * (Asterisk) symbol and enclosed in parenthesis. For example,
  • 53. void ( *fpData )( int ); For a better understanding, let’s take an example to describe the declaration of a function pointer in the C program. e.g, void ( *pfDisplayMessage) (const char *); In the above expression, pfDisplayMessage is a pointer to a function taking one argument, const char *, and returns void. When we declare a pointer to function in c then there is a lot of importance of the bracket. If in the above example, I remove the bracket, then the meaning of the above expression will be change and it becomes void *pfDisplayMessage (const char *). It is a declaration of a function that takes the const character pointer as arguments and returns a void pointer. Q) Where can the function pointers be used? There are a lot of places, where the function pointers can be used. Generally, function pointers are used in the implementation of the callback function, finite state machine and to provide the feature of polymorphism in C language …etc. Q) Write a program to check an integer is a power of 2? Here, I am writing a small algorithm to check the power of 2. If a number is a power of 2, function return 1. int CheckPowerOftwo (unsigned int x) { return ((x != 0) && !(x & (x - 1))); } Q) What is the output of the below code?
  • 54. #include <stdio.h> int main() { int x = -15; x = x << 1; printf("%dn", x); } Output: undefined behavior. Q) What is the output of the below code? #include <stdio.h> int main() { int x = -30; x = x >> 1; printf("%dn", x); } Output: implementation-defined.
  • 55. Q) Write a program to count set bits in an integer? unsigned int NumberSetBits(unsigned int n) { unsigned int CountSetBits= 0; while (n) { CountSetBits += n & 1; n >>= 1; } return CountSetBits; } Q) What is void or generic pointers in C? A void pointer in c is called a generic pointer, it has no associated data type. It can store the address of any type of object and it can be type-casted to any type. According to C standard, the pointer to void shall have the same representation and alignment requirements as a pointer to a character type. A void pointer declaration is similar to the normal pointer, but the difference is that instead of data types we use the void keyword. Syntax:
  • 56. void * Pointer_Name; Q) What is the advantage of a void pointer in C? There are following advantages of a void pointer in c.  Using the void pointer we can create a generic function that can take arguments of any data type. The memcpy and memmove library function are the best examples of the generic function, using these functions we can copy the data from the source to destination.  We know that void pointer can be converted to another data type that is the reason malloc, calloc or realloc library function return void *. Due to the void * these functions are used to allocate memory to any data type.  Using the void * we can create a generic linked list. For more information see this link: How to create generic Link List. Q) What are dangling pointers? Generally, daggling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers. It creates the problem because the pointer is still pointing the memory that is not available. When the user tries to dereference the daggling pointers than it shows the undefined behavior and can be the cause of the segmentation fault.
  • 57. For example, #include<stdio.h> #include<stdlib.h> int main() { int *piData = NULL; //creating integer of size 10.
  • 58. piData = malloc(sizeof(int)* 10); //make sure piBuffer is valid or not if (piData == NULL) { // allocation failed, exit from the program fprintf(stderr, "Out of memory!n"); exit(1); } //free the allocated memory free(piData); //piData is dangling pointer *piData = 10; printf("%d",*piData); return 0; } OutPut: Undefined Result In simple words, we can say that a dangling pointer is a pointer that is not pointing to valid memory. So if we access these pointers then the behaviour of the program will undefine. Q) What is the wild pointer?
  • 59. A pointer that is not initialized properly before its first use is known as the wild pointer. Uninitialized pointer’s behavior is totally undefined because it may point some arbitrary location that can be the cause of the program crash, that’s is the reason it is called a wild pointer. In other words, we can say every pointer in programming languages that are not initialized either by the compiler or programmer begins as a wild pointer. Note: Generally, compilers warn about the wild pointer. Syntax, int *piData; //piData is wild pointer. Q) What is a NULL pointer? According to C standard, an integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer.
  • 60. Syntax, int *piData = NULL; // piData is a null pointer Q) What are the post-increment and decrement operators? When we use a post-increment (++) operator on an operand then the result is the value of the operand and after getting the result, the value of the operand is incremented by 1. The working of the post-decrement (–) operator is similar to the post-increment operator but the difference is that the value of the operand is decremented by 1. Note: incrementation and decrementation by 1 are the types specified. Q) Which one is better: Pre-increment or Post increment? Nowadays compiler is enough smart, they optimize the code as per the requirements. The post and pre-increment both have their own importance we need to use them as per the requirements. If you are reading a flash memory byte by bytes through the character pointer then here you have to use the post-increment, either you will skip the first byte of the data. Because we already know that in the case of pre-increment pointing address will be increment first and after that, you will read the value. Let’s take an example of the better understanding, In the below example code, I am creating a character array and using the character pointer I want to read the value of the array. But what will happen if I used a pre-increment operator? The answer to this question is that ‘A’ will be skipped and B will be printed. #include <stdio.h>
  • 61. int main(void) { char acData[5] = {'A','B','C','D','E'}; char *pcData = NULL; pcData = acData; printf("%c ",*++pcData); return 0; } But in place of pre-increment if we use post-increment then the problem is getting solved and you will get A as the output. #include <stdio.h> int main(void) { char acData[5] = {'A','B','C','D','E'}; char *pcData = NULL; pcData = acData; printf("%c ",*pcData++); return 0; }
  • 62. Besides that, when we need a loop or just only need to increment the operand then pre-increment is far better than post-increment because in case of post increment compiler may have created a copy of old data which takes extra time. This is not 100% true because nowadays the compiler is so smart and they are optimizing the code in a way that makes no difference between pre and post- increment. So it is my advice, if post-increment is not necessary then you have to use the pre-increment. Note: Generally post-increment is used with array subscript and pointers to read the data, otherwise if not necessary then use pre in place of post-increment. Some compiler also mentioned that to avoid to use post-increment in looping condition. iLoop = 0. while (a[iLoop ++] != 0) { // Body statements } Q) Are the expressions *ptr ++ and ++*ptr same ? Both expressions are different. Let’s see a sample code to understand the difference between both expressions. #include <stdio.h> int main(void) { int aiData[5] = {100,200,300,400,500}; int *piData = aiData; ++*piData; printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData); return 0;
  • 63. } Output: 101 , 200 , 101 Explanation: In the above example, two operators are involved and both have the same precedence with a right to left associativity. So the above expression ++*p is equivalent to ++ (*p). In another word, we can say it is pre-increment of value and output is 101, 200, 101. #include <stdio.h> int main(void) { int aiData[5] = {100,200,30,40,50}; int *piData = aiData; *++piData; printf("aiData[0] = %d, aiData[1] = %d, *piData = %d", aiData[0], aiData[1], *piData); return 0; } Output: 100, 200, 200 Explanation: In the above example, two operators are involved and both have the same precedence with the right to left associativity. So the above expression *++p is equivalent to *(++p). In another word you can say it is pre-increment of address and output is 100, 200,200. Q) What does the keyword const mean? A const is only a qualifier, it changes the behavior of a variable and makes it read-only type. When we want to make an object read- only type, then we have to declare it as const. Syntax,
  • 64. const DataType Identifier = Value; e.g. const int iData = 0 At the time of declaration, const qualifier only gives the direction to the compiler that the value of declaring objects could not be changed. In simple words, const means not modifiable (cannot assign any value to the object at the runtime).
  • 65. Q) How will you protect a pointer by some accidental modification with the pointer address? With the help of the “const” keyword, we can avoid accidental modification of the pointer address. Q) When should we use const in a C program? There are the following places where we need to use the const keyword in the programs.  In case of call by reference, if you don’t want to change the value of the passed variable. E.g., int PrintData ( const char *pcMessage);  In some places, const is better than macro because const is handled by the compiler and has a type checking.  In the case of the I/O and memory-mapped register, const is used with the volatile qualifier for efficient access. for eg, const volatile uint32_t *DEVICE_STATUS = (uint32_t *) 0x80102040;  When you don’t want to change the value of an initialized variable. Q) What is the meaning of the below declarations? 1. const int a; 2. int const a; 3. const int *a; 4. int * const a; 5. int const * a const; 1. The “a” is a constant integer. 2. Similar to first, “a” is a constant integer.
  • 66. 3. Here “a” is a pointer to a const integer, the value of the integer is not modifiable, but the pointer is not modifiable. 4. Here “a” is a const pointer to an integer, the value of the pointed integer is modifiable, but the pointer is not modifiable. 5. Here “a” is a const pointer to a const integer that means the value of pointed integer and pointer both are not modifiable. Q) Differentiate between a constant pointer and pointer to a constant? Constant pointer: A constant pointer is a pointer whose value (pointed address) is not modifiable. If you will try to modify the pointer value, you will get the compiler error. A constant pointer is declared as follows : Data_Type * const Pointer_Name; Let’s see the below example code when you will compile the below code to get the compiler error. #include<stdio.h> int main(void) { int var1 = 10, var2 = 20; //Initialize the pointer int *const ptr = &var1; //Try to modify the pointer value
  • 67. ptr = &var2; printf("%dn", *ptr); return 0; } Output: compiler error. Pointer to a constant: In this scenario the value of the pointed address is constant that means we can not change the value of the address that is pointed by the pointer. A constant pointer is declared as follows : Data_Type const* Pointer_Name; Let’s take a small code to illustrate a pointer to a constant: #include<stdio.h> int main(void) { int var1 = 100; // pointer to constant integer const int* ptr = &var1;
  • 68. //try to modify the value of pointed address *ptr = 10; printf("%dn", *ptr); return 0; } Output: compiler error. Q) How to use a variable in a source file that is defined in another source file? Using the “extern” keyword we can access a variable from one source file to another. Q) What are the uses of the keyword static? In C language, the static keyword has a lot of importance. If we have used the static keyword with a variable or function, then only internal or none linkage is worked. I have described some simple use of a static keyword.  A static variable only initializes once, so a variable declared static within the body of a function maintains its prior value between function invocations.  A global variable with a static keyword has internal linkage, so it only accesses within the translation unit (.c). It is not accessible by another translation unit. The static keyword protects your variable to access from another translation unit.  By default in C language, the linkage of the function is external that it means it is accessible by the same or another translation unit. With the help of the static keyword, we can make the scope of the function local, it only accesses by the translation unit within it is declared.
  • 69. Q) What is the difference between global and static global variables? Global and static global variables have different linkages. It is the reason global variables can be accessed outside of the file but the static global variable only accesses within the file in which it is declared. A static global variable ===>>> internal linkage. A non-static global variable ===>>> external linkage. Q) Differentiate between an internal static and external static variable? In C language, the external static variable has the internal linkage and the internal static variable has no linkage. It is the reason they have a different scope but both will alive throughout the program. A external static variable ===>>> internal linkage. A internal static variable ===>>> none . Q) Can static variables be declared in a header file? Yes, we can declare the static variables in a header file. Static variables can be declared in the header files or any other source file. But in the header files, they can only be initialized once while in the source files, they can be initialized any number of times Q) What is the difference between declaration and definition of a variable? Declaration of a variable in C A variable declaration only provides sureness to the compiler at the compile time that variable exists with the given type and name, so that compiler proceeds for further compilation without needing all detail of this variable. When we declare a variable in C language, we only give the information to the compiler, but there is no memory reserve for it. It is only a reference, through which we only assure the compiler that this variable may be defined within the function or outside of the function.
  • 70. Note: We can declare a variable multiple times but defined only once. eg, extern int data; extern int foo(int, int); int fun(int, char); // extern can be omitted for function declarations Definition of variable in C The definition is action to allocate storage to the variable. In another word, we can say that variable definition is the way to say the compiler where and how much to create the storage for the variable generally definition and declaration occur at the same time but not almost. eg, int data; int foo(int, int) { } Note: When you define a variable then there is no need to declare it but vice versa is not applicable. Q) What is the difference between pass by value by reference in c and pass by reference in c? Pass By Value:  In this method, the value of the variable is passed. Changes made to formal will not affect the actual parameters.  Different memory locations will be created for both variables.  Here there will be a temporary variable created in the function stack which does not affect the original variable.
  • 71. Pass By Reference :  In Pass by reference, an address of the variable is passed to a function.  Whatever changes made to the formal parameter will affect the value of actual parameters(a variable whose address is passed).  Both formal and actual parameters shared the same memory location.  it is useful when you required to returns more than 1 value. Q) What is a reentrant function? In computing, a computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely be called again (“re-entered”) before its previous invocations complete execution. The interruption could be caused by an internal action such as a jump or call, or by an external action such as an interrupt or signal. Once the reentered invocation completes, the previous invocations will resume correct execution. Q) What is the inline function? An inline keyword is a compiler directive that only suggests the compiler substitute the function’s body at the calling the place. It is an optimization technique used by the compilers to reduce the overhead of function calls. for example, static inline void Swap(int *a, int *b) { int tmp= *a; *a= *b; *b = tmp; }
  • 72. Q) What is the advantage and disadvantage of the inline function? There are a few important advantages and disadvantages of the inline function. Advantages: 1) It saves the function calling overhead. 2) It also saves the overhead of variables push/pop on the stack, while function calling. 3) It also saves the overhead of return call from a function. 4) It increases the locality of reference by utilizing the instruction cache. 5) After inlining compiler can also apply intraprocedural optimization if specified. This is the most important one, in this way compiler can now focus on dead code elimination, can give more stress on branch prediction, induction variable elimination, etc.. Disadvantages: 1) May increase function size so that it may not fit in the cache, causing lots of cache miss. 2) After the inlining function, if variables numbers that are going to use register increases then they may create overhead on register variable resource utilization. 3) It may cause compilation overhead as if somebody changes code inside an inline function then all calling locations will also be compiled. 4) If used in the header file, it will make your header file size large and may also make it unreadable. 5) If somebody used too many inline functions resultant in a larger code size then it may cause thrashing in memory. More and number of page faults bringing down your program performance. 6) It’s not useful for an embedded system where a large binary size is not preferred at all due to memory size constraints. Q) What is virtual memory? Virtual memory is part of memory management techniques and it creates an illusion that the system has a sufficient amount of memory. In other words, you can say that virtual memory is a layer of indirection. Q) How can you protect a character pointer by some accidental modification with the pointer address? Using the const keyword we can protect a character pointer by some accidental modification with the pointer address. Eg, const char *ptr; here we can not change the value of the address pointed by ptr by using ptr.
  • 73. Q) Consider the two statements and find the difference between them? struct sStudentInfo { char Name[12]; int Age; float Weight; int RollNumber; }; #define STUDENT_INFO struct sStudentInfo* typedef struct sStudentInfo* studentInfo; statement 1 STUDENT_INFO p1, p2; statement 2 studentInfo q1, q2; Both statements looking the same but actually, both are different from each other. Statement 1 will be expanded to struct sStudentInfo * p1, p2. It means that p1 is a pointer to struct sStudentInfo but p2 is a variable of struct sStudentInfo. In statement 2, both q1 and q2 will be a pointer to struct sStudentInfo.
  • 74. Q) Can structures be passed to the functions by value? Yes, but it is not a good programming practice because if the structure is big maybe got StackOverflow if you have a very limited amount of stack. Q) What are the limitations of I2C interface?  Half-duplex communication, so data is transmitted only in one direction (because of the single data bus) at a time.  Since the bus is shared by many devices, debugging an I2C bus (detecting which device is misbehaving) for issues is pretty difficult.  The I2C bus is shared by multiple slave devices if anyone of these slaves misbehaves (pull either SCL or SDA low for an indefinite time) the bus will be stalled. No further communication will take place.  I2C uses resistive pull-up for its bus. Limiting the bus speed.  Bus speed is directly dependent on the bus capacitance, meaning longer I2C bus traces will limit the bus speed. Q) What is the Featured of CAN Protocol? There are few features of can protocol.  Simple and flexible in Configuration.  CAN is a Message-Based Protocol.  Message prioritization feature through identifier selection.  CAN offer Multi-master Communication.  Error Detection and Fault Confinement feature.  Retransmission of the corrupted message automatically when the bus is idle. Q) What is priority inversion? Priority inversion is a problem, not a solution. Priority inversion is a situation where a high-priority task is blocked on a low-priority task using a protected shared resource. During this blockage, a medium-priority task (that does not need the shared resource) can finish its work before the high-priority task.
  • 75. Q) What is priority inheritance? In priority inheritance, a low-priority task is automatically assigned the priority of a higher priority task when it blocks on the mutex. The low-priority task is re-assigned its original priority when it releases the mutex. Q) Significance of watchdog timer in Embedded Systems? Using the watchdog timer you can reset your device. It is a useful tool in helping your system recover from transient failures.
  • 76. Q) What Is Concatenation Operator in Embedded C? Token Pasting Operator (##) is sometimes called a merging or combining operator. It is used to merge two valid tokens, it is the reason we called it token concatenation. See the below example code, #include <stdio.h> #define MERGE(token1, token2) token1##token2 int main() { int var1 = 10; int var2 = 20; int var3 = 30; printf("%dn", MERGE(var, 1)); printf("%dn", MERGE(var, 2)); printf("%dn", MERGE(var, 3)); return 0; } Output: 10 ,20,30 1) What is Embedded C? / What do you understand by Embedded C language?
  • 77. Embedded C is a set of language extensions for the C programming language specified by the C Standards Committee. It is generally used to address commonality issues that exist between C extensions for different embedded systems. Embedded C programming typically requires nonstandard extensions to the C language to support enhanced microprocessor features such as fixed-point arithmetic, multiple distinct memory banks, and basic I/O operations. 2) What do you understand by the embedded system? An embedded system is a microprocessor-based computer hardware system and software designed to perform a specific function. An embedded system is either an independent system or acts as a part of a large system. 3) What are the key differences between C and Embedded C? C is a general-purpose, high-level programming language used to design any desktop-based applications. On the other hand, Embedded C is an extension of the C language, and it is used to develop micro-controller based applications. Here, Embedded refers to the hosting computer or microcontroller and not the programming language. Let's see the key differences between C and Embedded C in the following table. Differences between C and Embedded C:
  • 78. C language Embedded C C is a general-purpose programming language used to design any desktop-based applications. Embedded C is nothing but an extension C programming language, and it is used to develop micro-controller based applications. C is a type of high-level programming language. Embedded C is an extension of the C programming language. C programming language is the hardware-independent language. Embedded C is a completely hardware-dependent language. C is a simple language, and it is easy to read and modify. Embedded C is comparatively tough, and it is not easy to read and modify the Embedded C language. The compilers of the C programming language are OS-dependent. The compilers of Embedded C are OS independent. In the C programming language, the standard compilers are used to compile and execute the program. In Embedded C language, a specific compiler that can generate particular hardware/micro- controller based output is used to compile the code. Some popular compilers used to execute a C language program are: GCC (GNU Compiler collection) Borland Turbo C Intel C++ Some popular compilers used to execute an Embedded C language program are: Keil compiler BiPOM ELECTRONIC Green Hill software C programming language has a free format of program coding. In Embedded C language, formatting depends upon the type of microprocessor used in the application. Bug fixing is easy in a C language program. Bug fixing is complicated in an Embedded C language program. C language also supports other various programming languages during application. Embedded C language supports only the required processor of the application and not the programming languages. C programming language must require an operating system. Embedded C may or may not require an operating system. In the C programming language, we can give input to the program while it is running. In Embedded C language, we can give only the pre-defined inputs to the running program. The C programming language supports normal optimization. Embedded C supports the high level of optimization.
  • 79. 4) Is embedded C a programming language? Embedded C is not a core programming language. It is an extension of C programming language that is used to develop micro- controller based applications. The extensions introduced in Embedded C language from normal C programming language are the I/O Hardware Addressing, fixed-point arithmetic operations, accessing address spaces, etc. 5) What are the main advantages of Embedded C? Embedded C is the extension of the C programming language. Let's see the key advantages of Embedded C: Key advantages of Embedded C: o The coding speed of Embedded C is high, and it is simple and easy to understand. o It doesn't require any hardware changes such as extra memory or space for storage as it performs the same task all the time. o It is dedicated to its specific task and performs only one task at one time. o It is mainly used in modern automatic applications. Embedded applications are very suitable for industrial purposes. 6) What are the main disadvantages of Embedded C? Disadvantages of Embedded C: C programming language generally uses the resources of a desktop PC like memory, OS, etc. Embedded C language has to use with the limited resources, such as RAM, ROM, I/Os on an embedded processor. Some examples of the C Program applications: Logical programs System software programs etc. Some examples of the Embedded C Program applications: DVD TV Digital camera etc.
  • 80. o Embedded C performs only one task at a time, so it is not preferred when we have to perform multiple tasks simultaneously. o Embedded C only supports the hardware system. So, if you have to change the program, then you must have to change the hardware. o Embedded C also has some scalability issues, so; it cannot be easily scaled up as scope change or demand. o It has some limitations, such as limited memory or computer compatibility. 7) What is the volatile keyword in Embedded C, and what is its usage? In Embedded C, the volatile keyword is a type qualifier that prevents the objects from compiler optimization. According to the C standard, we can modify the volatile-qualified type object in ways unknown to the implementation. In other words, we can say that the value of the volatile-qualified object can be changed at any time without making any changes in the code. If the volatile qualifier qualifies an object, the compiler will reload the value from memory each time the program accesses it. Reading the value from memory is the only way to check the unpredictable change of the value. The volatile keyword is mainly used when we have to deal with GPIO, interrupt or flag Register directly. It is also used with a global variable or buffer shared between the threads. 8) What is the segmentation fault error in C? What are some common causes for the segmentation fault error? Segmentation fault error is a runtime error, which may occur due to some causes when a program runs. Following is a list of some common causes for the segmentation fault error in C: o Usages of the dereferenced pointer: If we use a pointer that may not have a valid address/memory location to point, it may create a segmentation fault error. o A program may return a segmentation fault error if you try to access a read-only memory area. o Segmentation fault error may also occur when you try to free memory (using a pointer), which is already freed.
  • 81. o The occurrence of segmentation fault error is the reason to generate stack overflow error in C. 9) What is the full form of ISR in Embedded C? In Embedded C, ISR stands for Interrupt Service Routines. These are the procedures stored at specific memory addresses and called when a certain type of interrupt occurs. 10) What is a stack overflow error in C? In C language, the stack overflow error may occur if the program tries to access the memory beyond its available maximum limit. For example, the stack overflow error may occur if a pointer exceeds the stack limitations (boundaries). When the stack overflow error occurs, the program terminates and does not execute further instructions. So, we must be very careful while using the pointer and limit boundaries. 11) Is it possible to pass any parameter and return a value from the ISR? No. It is not possible to pass any parameter and return a value from the ISR. The ISR returns nothing and does not allow passing any parameter. An ISR is called when a hardware or software event occurs, and the code does not call it. That's why no parameters are passed into an ISR. As the code does not call ISR, there is no calling code to read the returned values of the ISR. That's why an ISR does not return any value. 12) What do you understand by interrupt latency? Interrupt Latency is the number of clock cycles the processor takes to respond to an interrupt request. This clock cycle number is count between the interrupt request's assertions and the interrupt handler's first instruction.
  • 82. Interrupt Latency on the Cortex-M processor family: Cortex-M processors have very low interrupt latency. The following table shows the Interrupt latency of Cortex-M processors with zero wait state memory systems. Processors Cycles with zero wait state memory Cortex-M0 16 Cortex-M0+ 15 Cortex-M3 12 Cortex-M4 12 Cortex-M7 12 13) How can you measure the interrupt latency in Embedded C? In Embedded C, we can measure the interrupt latency with the help of the oscilloscope. Follow the steps given below: o Take two GPIOs first. Configure one GPIO to generate the interrupt and the second for the toggling (you can attach an LED also). o Use the oscilloscope or analyzer to monitor the PIN, which is already configured to generate the interrupt. o Now, monitor the second pin, which is toggled at the beginning of the interrupt service routine by using the oscilloscope or analyzer. o When you generate the interrupt, the signal of both GPIOs will change. o Now, you can easily read the instrument's interval between the two signals (interrupt latency).
  • 83. 14) How can you reduce the interrupt latency? There are several ways to reduce the interrupt latency in Embedded C. The interrupt latency depends on many factors. Following is a list of some factors: o Platform and interrupt controller o CPU clock speed o Timer frequency o Cache configuration o Application program etc. So, we can easily reduce the interrupt latency by using the proper selection of platform and processor. We can also reduce the interrupt latency by making the ISR shorter and avoid to calling a function within the ISR. 15) What is a static variable in C? Why do we use a static variable in C? Static variables have the property of preserving their value even after they are out of their scope. It means we can initialize static variables only once. Its scope is local, but it lives until the end of the program. The compiler persists with the variable till the end of the program. We can define static variables inside or outside the function. The default value of static variables is zero. The static variables are alive till the execution of the program. Syntax for the static variables in C language: 1. static datatype variable_name = value; A static variable is generally used to count something. For example, the function openBakAccount() calls whenever a new account opens in the bank. Then, to count the total number of opened accounts, we can declare a static variable in the function and increase it on each function call.
  • 84. 16) What are some interesting facts about static variables in C? Following is a list of some interesting facts about static variables in C: o There are two types of static variables, static int variable and static auto variable. A static int variable remains in memory while the program is running and a normal or auto variable is destroyed when a function call declared is over. For example, we can use a static int variable to count the number of times a function is called, but we cannot use an auto variable for this purpose. o Static variables are allocated memory in the data segment, not the stack segment. o The default value for static variables is 0. Like global variables, they are initialized as 0 if not initialized explicitly. o In C language, we can initialize the static variables using only constant literals. o Static global variables and functions are also possible in C++. They are mainly used to limit the scope of a variable or function to a file. o We should not declare static variables inside the structure because the C compiler requires the entire structure elements to be placed together. 17) How can you use a variable in a source file defined in another source file? We can use the "extern" keyboard to declare a variable that allows accessing the variable in another file. This is how we can use a variable in a source file defined in another source file. 18) How can you protect a character pointer by some accidental modification with the pointer address? We can use the constant character pointer (const char*) to protect a character pointer by accidentally modifying the pointer address. It prevents unnecessary modifications with the pointer address in the string.
  • 85. 19) What are the main differences between CISC and RISC? There are many differences between the RISC and CISC. Some of them are as follows: RISC CISC RISC stands for Reduced Instruction Set Computer. CISC stands for Complex Instruction Set Computer. RISC does not consist of a memory unit. CISC consists of a memory unit. RISC is a relatively faster processor than CISC in terms of calculations. CISC is a comparatively slower processor than RISC in terms of calculatio RISC is used to ensure the simple decoding of operations. CISC doesn't ensure simple decoding of operations. The execution time is RISC is low. The execution time is CISC is high. 20) What do you understand by a function pointer? A function pointer is a pointer that points to a function instead of a variable. That's why a function pointer is completely different from the class of other pointers. A function pointer stores the address of a particular function so that the concerned program can avail of it through function invoking. 21) Can a variable be both constant and volatile in C? Yes, a variable can be both constant and volatile in C. we can use constant and volatile both variables together. The volatile and const variable together is used at the time of accessing the GPIO registers. In this case, its value is changed by the 'external factors' if a switch or any output device is attached with GPIO. In this situation, the volatile variable is important because it ensures that the compiler always read the value from the GPIO address and avoids making any assumption.
  • 86. 22) What is a dangling pointer in embedded C? A dangling pointer is a pointer that points to a memory location that has been already free-ed by the application and is no longer in use. Sometimes, the programmers fail to initialize the pointer with a valid address; these types of initialized pointers are known as dangling pointers. Dangling pointers occur at the time of the object's destruction when the object is deleted or de-allocated from memory without modifying the pointer's value. If you try to dereference a dangling pointer, it will potentially lead to a runtime error. 23) What is the size of a character, integer, integer pointer, and character pointer in C? The size of the character is 1 byte, the size of the integer is 4 bytes, the size of the integer pointer, and the character pointer is 8 bytes on a 64-bit machine and 4 bytes on a 32-bit machine. 24) What are some Real-Time applications of Embedded Processors? Some real-time applications of Embedded Processors are: o Dishwashers o Automatic passengers’ cars o Mobile Phones o Television o Medical equipment, etc. 25) What are some examples of the embedded systems to use in Aerospace Applications? Some examples of the embedded systems to use in Aerospace Applications are: o Flight control systems
  • 87. o Autopilot mode o A passenger in-flight embedded system o Engine controllers o Landing and takeoff controller etc. 26) How many bits that the Embedded Software supports? The Embedded Software supports 8, 16 or 32 bit embedded processors. 27) What do you understand by a NULL pointer? What is its usage? NULL is a macro defined in C. The Null pointer is a pointer that does not point to any valid location. The NULL pointer is defined when we want to ensure that the pointer does not point to any valid location and not to use that pointer to change anything. Without using a null pointer, we can't verify whether this pointer points to any valid location or not. 28) Are Countdown to zero loops better than Count_up_loops? Yes, Countdown to zero loops are better than Count_up_loops because, at loop termination, comparison to zero can be optimized by the compiler. Most of the processors have instructions for comparing to zero. So they don't need to load the loop variable and the maximum value; subtract them and then compare them to zero. That is why count down to zero loops are better. 29) What are some examples of Embedded systems in automotive applications? Following are some examples of Embedded systems in automotive applications:
  • 88. o Traffic control systems o Braking systems o steer-by-wire systems o Cruise control applications o Airbag release systems o Engine management units etc. 30) What are some examples of domestic appliances that use an Embedded System? Following is a list of some examples of domestic appliances that use Embedded Systems: o Smart Televisions o Washing machines o Microwave ovens o Dishwashers o Garage door controllers o Video recorders and o Security systems etc. 31) What do you understand by the term structure padding in Embedded C? Structure padding is a concept used in the C programming language. It is used to add one or more empty bytes between the memory addresses to align the data in the memory. The compiler automatically does it to ensure that all its members are byte aligned.
  • 89. 32) What are some examples of Medical Equipments that uses the concept of Embedded Systems? Following are some examples of Medical Equipments that uses the concept of Embedded Systems: o Anesthesia monitoring systems o ECG monitors o MRI Scanners o Drug delivery systems o Ultrasound equipment etc. 33) Which Defense Systems use the concept of Embedded Systems? Following are some examples of Defense Systems that use the concept of Embedded Systems: o Radio systems o Radar systems o Missile guidance systems o Fighter aircraft flight control system o Target guidance systems etc. 34) What do you understand by Machine Code? Machine Code is the language of the computer rather than the programmer. A computer only accepts the instructions in the form of machine code or object code. When a programmer interprets the code, it is complex and error-prone. Whether in languages such as C, C++, and Java, all software must ultimately be translated into machine code to be executed by the computer.
  • 90. 35) What are the Discrete Components used in Embedded systems? The list of Discrete Components used in Embedded systems is: o Transistors o Diodes o Resistors o Capacitor 36) What is the link between oscillator frequency and machine-cycle period? A general rule specifies that the oscillator frequency directly determines the speed at which your application runs. So, in most cases, if you double the oscillator frequency, the speed of the application would be doubled. 37) What is the full form of MIPS? MIPS stands for Million Instructions Per Second. It is an approximate measure of a computer's raw processing power. It may be misleading because measurement techniques often differ, and different computers may require different sets of instructions to perform the same activity. 38) How can we improve the 8051 microcontroller performance? The simplest way to improve the performance of the 8051 microcontrollers is to increase the clock frequency. The 8051 microcontrollers allow the use of clock speeds well beyond the 12MHz limit of the original devices. The best way to improve the performance is to make internal changes to the microcontroller so that fewer oscillator cycles are required to execute each machine instruction.
  • 91. 39) What is the range of maximum oscillator frequency and the peak performance in the 8051 microcontrollers? The 8051 microcontroller has a maximum oscillator frequency of 12 MHz, and peak performance is 1 MIP. 40) What do you understand by Memory Fragmentation? Memory Fragmentation is an issue that arises while using dynamic memory allocation. When we keep allocating and releasing memory spaces over time, in the end, we will get non-contiguous memory blocks that are free, and our in-use variables are scattered everywhere in the RAM. This is called memory fragmentation. This can potentially lead to dynamic memory allocation failure. For example, if you have to allocate an array of 100 integers and there is no contiguous block of memory with that space, this causes a runtime error. This is why we don't use dynamic memory allocation in embedded systems firmware in the first place. 41) What are inline functions in Embedded C? Inline functions are the types of function whose definitions are small and be substituted at the place where its function call has happened. The ARM compilers support inline functions with the keyword __inline. These functions have a small definition, and the function body is substituted in each call to the inline function. 42) What are the types of memory in an Embedded System in C language? Following are the types of memory in an Embedded System in C language: o DRAM (Dynamic RAM) o SRAM (Static RAM) o Mask Read-only Memory (ROM)
  • 92. o PROM (Programmable Read-Only Memory) o UV EPROM (UV Erasable Programmable Read-Only Memory) o EEPROM (Electrically - Erasable PROM) 1) What is C language? C is a mid-level and procedural programming language. The Procedural programming language is also known as the structured programming language is a technique in which large programs are broken down into smaller modules, and each module uses structured code. This technique minimizes error and misinterpretation. More details. 2) Why is C known as a mother language? C is known as a mother language because most of the compilers and JVMs are written in C language. Most of the languages which are developed after C language has borrowed heavily from it like C++, Python, Rust, javascript, etc. It introduces new core concepts like arrays, functions, file handling which are used in these languages. More details. 3) Why is C called a mid-level programming language? C is called a mid-level programming language because it binds the low level and high -level programming language. We can use C language as a System programming to develop the operating system as well as an Application programming to generate menu driven customer driven billing system. More details.
  • 93. 4) Who is the founder of C language? Dennis Ritchie. More details. 5) When was C language developed? C language was developed in 1972 at bell laboratories of AT&T. More details. 6) What are the features of the C language? The main features of C language are given below: o Simple: C is a simple language because it follows the structured approach, i.e., a program is broken into parts o Portable: C is highly portable means that once the program is written can be run on any machine with little or no modifications. o Mid Level: C is a mid-level programming language as it combines the low- level language with the features of the high-level language. o Structured: C is a structured language as the C program is broken into parts. o Fast Speed: C language is very fast as it uses a powerful set of data types and operators. o Memory Management: C provides an inbuilt memory function that saves the memory and improves the efficiency of our program. o Extensible: C is an extensible language as it can adopt new features in the future. More details. 7) What is the use of printf() and scanf() functions? printf(): The printf() function is used to print the integer, character, float and string values on to the screen. Following are the format specifier:
  • 94. o %d: It is a format specifier used to print an integer value. o %s: It is a format specifier used to print a string. o %c: It is a format specifier used to display a character value. o %f: It is a format specifier used to display a floating point value. scanf(): The scanf() function is used to take input from the user. More details. 8) What is the difference between the local variable and global variable in C? Following are the differences between a local variable and global variable: Basis for comparison Local variable Global variable Declaration A variable which is declared inside function or block is known as a local variable. A variable which is declared outside function or block is kn as a global variable. Scope The scope of a variable is available within a function in which they are declared. The scope of a variable is available throughout the program Access Variables can be accessed only by those statements inside a function in which they are declared. Any statement in the entire program can access variables. Life Life of a variable is created when the function block is entered and destroyed on its exit. Life of a variable exists until the program is executing.
  • 95. Storage Variables are stored in a stack unless specified. The compiler decides the storage location of a variable. More details. 9) What is the use of a static variable in C? Following are the uses of a static variable: o A variable which is declared as static is known as a static variable. The static variable retains its value between multiple function calls. o Static variables are used because the scope of the static variable is available in the entire program. So, we can access a static variable anywhere in the program. o The static variable is initially initialized to zero. If we update the value of a variable, then the updated value is assigned. o The static variable is used as a common value which is shared by all the methods. o The static variable is initialized only once in the memory heap to reduce the memory usage. More details. 10) What is the use of the function in C? Uses of C function are: o C functions are used to avoid the rewriting the same code again and again in our program. o C functions can be called any number of times from any place of our program. o When a program is divided into functions, then any part of our program can easily be tracked. o C functions provide the reusability concept, i.e., it breaks the big task into smaller tasks so that it makes the C program more understandable. More details.
  • 96. 11) What is the difference between call by value and call by reference in C? Following are the differences between a call by value and call by reference are: Call by value Call by reference Description When a copy of the value is passed to the function, then the original value is not modified. When a copy of the value is passed to the function, then the orig value is modified. Memory location Actual arguments and formal arguments are created in separate memory locations. Actual arguments and formal arguments are created in the s memory location. Safety In this case, actual arguments remain safe as they cannot be modified. In this case, actual arguments are not reliable, as they are modifie Arguments The copies of the actual arguments are passed to the formal arguments. The addresses of actual arguments are passed to their respec formal arguments. Example of call by value: 1. #include <stdio.h> 2. void change(int,int); 3. int main() 4. { 5. int a=10,b=20; 6. change(a,b); //calling a function by passing the values of variables. 7. printf("Value of a is: %d",a); 8. printf("n");
  • 97. 9. printf("Value of b is: %d",b); 10. return 0; 11. } 12. void change(int x,int y) 13. { 14. x=13; 15. y=17; 16. } Output: Value of a is: 10 Value of b is: 20 Example of call by reference: 1. #include <stdio.h> 2. void change(int*,int*); 3. int main() 4. { 5. int a=10,b=20; 6. change(&a,&b); // calling a function by passing references of variables. 7. printf("Value of a is: %d",a); 8. printf("n"); 9. printf("Value of b is: %d",b); 10. return 0; 11. } 12. void change(int *x,int *y) 13. { 14. *x=13;