- What is the segmentation fault error in C?
- What are some common causes for the segmentation fault error in C?
- What is ‘stack overflow’ error in C?
- Why do you think stack overflow transpires in the first place?
- Why do we use ‘volatile’ keyboard in C?
- How to use a variable in a source file which is defined in another source file?
- How will you protect a character pointer by some accidentally modification with the pointer address?
- Why do we use ‘static’ variable in C?
- Can you highlight the differences between CISC and RISC?
- What do you understand by a function pointer?
- What do you understand by the term structure padding?
- Can you tell us something about the dangling pointers in embedded C?
- What is the function of the keyword const? Give an example.
- Why should we use the keyword const in the first place?
- What is the chief functionality of realloc ()?
- Can parameter be both const and volatile ?
- What is an inline function?
- Is Count Down_to_Zero Loop better than Count_Up_Loops?
- Can structures be passed to the functions by value?
- What is the size of character, integer, integer pointer, character pointer?
- What is a NULL pointer and what is its use?
- What is a void pointer and what is its use?
- What is ISR?
- What is the return type of ISR?
- What is interrupt latency?
- How to reduce interrupt latency?
- Can we use any function inside ISR?
- Can we use printf inside ISR?
- Can we put a breakpoint inside ISR?
- Can static variables be declared in a header file?
- Can include files be nested?
- What is the difference between hard real-time and soft real-time OS?
- What type of scheduling is there in RTOS?
- What is priority inversion?
- What is priority inheritance?
- What is a semaphore?
- Types of Semaphores?
- What is spin lock?
- In platforms with significant constraints on memory size, is it more preferable to allocate memory statically or dynamically?
- Why are C and C++ still very popular and widely supported in embedded firmware development?
- Is firmware and data embedded in microcontrollers generally safe from downloading, tampering, or hacking?
- Which parameters decide the size of data type for a processor ?
- Significance of watchdog timer in Embedded Systems
- Why ++n executes faster than n+1?
- When should we use register modifier?
- What is NVIC in ARM Cortex?
- Can we change the interrupt priority level of Cortex-M processor family?
- What is the start-up code?
- What is segmentation fault in C?
- What are the common causes of segmentation fault in C?
- Are integers signed or unsigned?
- What do you mean by enumeration in C?
- What is the endianness?
- What is the difference between malloc and calloc?
- What is the return value of malloc (0)?
- Where can the function pointers be used?
- What is void or generic pointers in C?
- What are the post-increment and decrement operators?
- What is a reentrant function?
- What is virtual memory?
- Why embedded system is useful?
- Explain whether we can use semaphore or mutex or spinlock in interrupt context in Linux Kernel?
- What is the bus in a microcontroller?
- What is qualifiers?
Segmentation fault is a runtime error, which may occur due to some causes (listed below) when the program is running properly.
- Usages of the dereferenced pointer (i.e. a pointer which may not have a valid address/memory location to point).
- If you are trying to access a memory area which is read-only. In that case, the program may return segmentation fault error.
- It may also occur when you try to free a memory (using a pointer), which is already freed.
- Segmentation fault is the reason to generate stack overflow error in C.
This error may occur if the program tries to access the memory beyond its available maximum limit. We can also say that if a pointer exceeds the stack limitations (boundaries).
When this error occurs program terminates and does not execute further instructions. Therefore, we must be careful while using the pointer and limit boundaries.
There could be many potential reasons behind the occurrence of the stack overflow. For instance, redundant arguments and clumsy application of recursion could be the leading proponents. Apart from that, it may occur due to the construction of an outsize local array and the presence of nested function calls.
"volatile" is used to prevent the compiler to optimize any variable. When any variable is used frequently, the compiler optimizes it and keeps the variables in his memory (there are some specific memory blocks (registers), from there variable is accessibility is fast) to serve its value faster to the program.
Therefore, a "volatile" is used to prevent the compiler for any type of optimization on the variable. Volatile variables are used with those variables which are used to communicate with the computer hardware, signals, handlers etc.
"extern" keyboard can be used to declare a variable which allows accessing the variable in another file.
Constant character pointer (const char*) prevents the unnecessary modifications with the pointer address in the string.
- A static variable does not redeclare that means if it is declared in a function it will not redeclare on each function call, therefore, static is able to maintain the value.
- Its scope is local but it is live until the end of the program.
- Generally, it is used to count something, for example, there is function openBakAccount() which calls every time when a new account opens in the bank. Then, to count the total number of the opened account, we can declare a static variable in the function and can increase it on each function call.
There are many differences between the two. Reduced Instruction Set Computer, or RISC, does not consist of a memory unit unlike the CISC, or Complex Instruction Set Computer. Secondly, RISC is a relatively faster processor than CISC in terms of calculations. Also, RISC ensures a simple decoding of operations unlike a CISC processor. Lastly, RISC has a very low execution time compared to CISC.
As the name suggests, it is a pointer that points to a function instead of a variable. And this is precisely where a function pointer stands apart from the class of other pointers. Technically speaking, a function pointer is one which stores the address of a particular function in order to be availed of by the concerned program through function invoking.
Padding is essentially the induction of redundant bytes into a particular structure. More specifically, it is the function of the compiler to embed some extra bytes between the units of either a structure or a union. This is known as the process of padding. Basically, structure padding is used for the purpose of data type orientation. Consequently, structure padding ends up augmenting the performance quotient of the processor.
Dangling pointers are clearly aberrations that arise due to the obliteration of a referencing object. It is known as dangling because the pointer is essentially pointing to a ghost memory, one that is not at its disposal. Consequently, it gives rise to what is known as the segmentation fault.
So far as the keyword const is concerned, it is basically used to make a variable read-only type. For example: const int iData=0; During compilation, the keyword const chiefly acts as an indication to the compiler that the value of the declaring object is not subject to further alteration. So, it stands that the keyword is incapable of reassigning at runtime.
Indeed, const has many essential applications throughout the course of a program. For instance, it is of great use in a call by reference function argument. Secondly, const is particularly useful when you do not seek to change the value of an initialized variable.
As the titular indication suggests, it is chiefly used to resize the allocation of memory. Technically, it takes in two arguments. The first one is the pointer to the formerly allocated memory while the second one is the reference to the new size.
Yes. Example is read only status register. Volatile cause can change unexpectedly. Const cause program should not change it.
- Inline function is a feature to increase execution time of program and reduce function calling overhead.
- With inline, compiler replaces the function call statement with function code itself. This compile does not have to jump to another location to execute the function.
- Disadvantage includes increases the executable size due to code expansion.
- Count down to zero loops are better.
- Reason behind this is that at loop termination, comparison to zero can be optimized by the compiler.
- Most processors have instruction for comparing to zero. So they don’t need to load the loop variable and the maximum value, subtract them and then compare to zero. That is why count down to zero loop is better
- Passing structure by its value to a function is possible, but not a good programming practice.
- First of all, if we pass the structure by value and the function changes some of those values, then the value change is not reflected in caller function.
- Also, if the structure is big, then passing the structure by value means copying the whole structure to the function argument stack which can slow the program by a significant amount.
- The size of character is 1 byte.
- Size of integer is 4 bytes.
- Size of integer pointer and character is 8 bytes on 64 bit machine and 4 bytes on 32 bit machine.
The NULL is a macro defined in C. Null pointer actually means a pointer that does not point to any valid location. We define a pointer to be null when we want to make sure that the pointer does not point to any valid location and not to use that pointer to change anything. If we don't use null pointer, then we cannot verify whether this pointer points to any valid location or not.
The void pointer means that it points to a variable that can be of any type. Other pointers points to a specific type of variable while void pointer is a somewhat generic pointer and can be pointed to any data type, be it standard data type(int, char etc) or user define data type (structure, union etc.). We can pass any kind of pointer and reference it as a void pointer.
An ISR(Interrupt Service Routine) is an interrupt handler, a callback subroutine which is called when a interrupt is encountered.
ISR does not return anything. An ISR returns nothing because there is no caller in the code to read the returned values.
Interrupt latency is the time required for an ISR responds to an interrupt.
Interrupt latency can be minimized by writing short ISR routine and by not delaying interrupts for more time.
We can use function inside ISR as long as that function is not invoked from other portion of the code.
Printf function in ISR is not supported because printf function is not reentrant, thread safe and uses dynamic memory allocation which takes a lot of time and can affect the speed of an ISR up to a great extent.
Putting a break point inside ISR is not a good idea because debugging will take some time and a difference of half or more second will lead to different behavior of hardware. To debug ISR, definitive logs are better.
A static variable cannot be declared without defining it. A static variable can be defined in the header file. But doing so, the result will be having a private copy of that variable in each source file which includes the header file. So it will be wise not to declare a static variable in header file, unless you are dealing with a different scenario.
Yes. Include files can be nested any number of times. But you have to make sure that you are not including the same file twice. There is no limit to how many header files that can be included. But the number can be compiler dependent, since including multiple header files may cause your computer to run out of stack memory.
A Hard real-time system strictly adheres to the deadline associated with the task. If the system fails to meet the deadline, even once, the system is considered to have failed. In case of a soft real-time system, missing a deadline is acceptable. In this type of system, a critical real-time task gets priority over other tasks and retains that priority until it completes.
RTOS uses pre-emptive scheduling. In pre-emptive scheduling, the higher priority task can interrupt a running process and the interrupted process will be resumed later.
If two tasks share a resource, the one with higher priority will run first. However, if the lower-priority task is using the shared resource when the higher-priority task becomes ready, then the higher-priority task must wait for the lower-priority task to finish. In this scenario, even though the task has higher priority it needs to wait for the completion of the lower-priority task with the shared resource. This is called priority inversion.
Priority inheritance is a solution to the priority inversion problem. The process waiting for any resource which has a resource lock will have the maximum priority. This is priority inheritance. When one or more high priority jobs are blocked by a job, the original priority assignment is ignored and execution of critical section will be assigned to the job with the highest priority in this elevated scenario. The job returns to the original priority level soon after executing the critical section.
Semaphore is actually a variable or abstract data type which controls access to a common resource by multiple processes.
- Binary semaphore – It can have only two values (0 and 1). The semaphore value is set to 1 by the process in charge, when the resource is available.
- Counting semaphore – It can have value greater than one. It is used to control access to a pool of resources.
If a resource is locked, a thread that wants to access that resource may repetitively check whether the resource is available. During that time, the thread may loop and check the resource without doing any useful work. Suck a lock is termed as spin lock.
It’s preferable to use static memory allocation on platforms with memory sizes in the low kilobytes and below. This is because data overhead, CPU overhead, and memory fragmentation can be significant issues when using dynamic memory allocation.
Hardware constraints, both for memory sizes and CPU speed, limit what can be done on embedded devices. C and C++ usually have very minimal overhead and are very “close to the hardware” in terms of abstractions offered to developers. This makes them suitable for even the smallest devices.
No. Unless the microcontroller is specially constructed to offer countermeasures against firmware downloading and/or modification, any code and data uploaded to a microcontroller should be considered relatively easy to download and modify. (Such hardened microcontrollers are usually expensive.)
Actually, compiler is the one responsible for size of the data type. But it is true as long as OS allows that. If it is not allowable by OS, OS can force the size.
The watchdog timer is a timing device with a predefined time interval. During that interval, some event may occur or else the device generates a time out signal. It is used to reset to the original state whenever some inappropriate events take place which can result in system malfunction. It is usually operated by counter devices.
The expression ++n requires a single machine instruction such as INR to carry out the increment operation. In case of n+1, apart from INR, other instructions are required to load the value of n. That is why ++n is faster.
The register modifier is used when a variable is expected to be heavily used and keeping it in the CPU’s registers will make the access faster.
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.
Yes, we can.
A start-up code is called prior to the main function, it creates a basic platform for the application. It is a small block of code that is written in assembly language.
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).
- 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.
According to C standard, an integer data type is by default signed. So if you create an integer variable, it can store both positive and negative value.
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.
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.
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.
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.
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.
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.
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.
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.
The virtual memory is the 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.
With embedded system, it is possible to replace dozens or even more of hardware logic gates, input buffers, timing circuits, output drivers, etc. with a relatively cheap microprocessor.
Semaphore or Mutex cannot be used for interrupt context in Linux Kernel. While spinlocks can be used for locking in interrupt context.
It is a pathway to move the data rapidly through digital signals. There three different types of internal buses with are related to the processor. The buses are data, bus, address bus and control bus. All these together make up the system bus.
Qualifiers defines the property of the variable. Two qualifiers are const and volatile. The const type qualifier declares an object to be unmodifiable. The volatile type qualifier declares an item whose value can legitimately be changed by something beyond the control of the program in which it appears, such as a concurrently executing thread / interrupt routine.
(100% free to get started, no credit card required)