Saturday, March 7, 2015

Designing a Vehicle Instrument Panel Cluster—A Case Study

In modern vehicles, software-controlled electronics plays a major role in the functioning of the vehicle's subsystems. In a medium-sophistication vehicle, there will be 8 to 10 intelligent electronic modules performing functions such as engine control, transmission, brakes, steering, navigation, HVAC, safety, security, audio, driver information, and others. Though each of them works on its own, the modules will be connected using some in-vehicle network. Communication protocols such as SAE J1850, CAN, and KW2000 are commonly used for automobile inter-module communication.
The Instrument Panel Cluster (IPC), or Vehicle Dashboard, is one of the few devices with which the vehicle communicates to the driver. Devices such as a driver information center and heads-up display are considered subsystems or add-on devices to the IPC. Even though, from technology and complexity perspectives, the IPC is simpler than other modules, it is important to the driver, since it is one of the few modules the driver sees.
The IPC module takes signals from various sensors and communicates with almost all the other modules in the vehicle to get relevant information and status about the vehicle. The IPC processes data and provides information in an appropriate form to the driver.
System Design
  • Analog speedometer display
  • Analog tachometer display
  • Analog fuel display
  • Analog engine coolant temperature display
  • LCD single-line season/trip odometer
  • Nine discrete LED or bi-pin lamp telltales
  • Driver information center (DIC)—18*2 character dot-matrix display
  • Mode and reset switches to control the DIC and trip stem for odometer.
This list shows a typical requirement specification of an instrument cluster for a medium-sophistication vehicle such as a car or truck. Advanced clusters will have a higher number of gauges, high-resolution displays, compass, and other display features. These clusters may even integrate features such as security, vehicle immobilization, and so on, which are normally handled by other modules, in the vehicle.
You cannot design the cluster system from the previous specification alone. You need information on the types of inputs to the IPC, which needs to be processed. All the displayed data may not be directly sensed by the IPC. Other modules will sense and process some of the data and will then send this data to the IPC through an in-vehicle communication protocol.
You can divide inputs to the instrument cluster into four broad types, with examples of each shown:
  • Analog inputs (ignition voltage and coolant temperature)
  • Discrete inputs (switches and washer fluid status)
  • Digital pulses (Vehicle speed sensor output)
  • Serial data (Information from other modules such as the fuel used, telltale status, and warning data).
Basic Block Diagram
From the specifications and requirements described earlier in this article, you can develop a basic block diagram (Figure 1). First, we can summarize our system as follows:
  1. Four gauges
  2. Nine LED telltales
  3. Seven-segment LCD display (six digit)
  4. Dot-matrix display (18*2 character)
  5. Serial-communication module
  6. Analog/discrete/pulse inputs
  7. A microcontroller to process data and control the devices.
Component and Device Selection
After obtaining the basic block diagram, you now must select the devices and components that the system will contain. The considerations for selection include performance, price, availability, compatibility with other devices, and other factors.
Gauges
There are many methods to electronically move gauge pointers. A simple and straightforward method is by using stepper motors to control the gauges. To interface a microcontroller to the stepper motor, you can use stepper drivers, of which many types are available. For example, Switec provides an M-S quad driver that can control four stepper motors at a time, which is optimal for our requirement. The Switec driver provides a micro-step of 1/12th of a degree for each edge of the pulse train coming from the processor. Independent direction control and movement is possible for individual stepper motors. We can also use buffers to drive the stepper motor by using high-frequency pulse-width-modulated (PWM) signals generated directly from the microcontroller, but this requires more dedicated microcontroller I/O pins.
LED Telltales
We need to drive nine LEDs. It is a waste of port pins if we try to drive the LEDs directly from the microcontroller. Furthermore, the microcontroller may not have the required current capacity. Instead, we can use an LED driver for the same purpose. LED drivers that connect directly to the microcontroller through SPI/I2C are available.
Seven-Segment LCD Display
The season odometer is usually six digits, so we need a six-digit seven-segment LCD display. Other symbols such as "Km", "MI", and "TRIP" may also need to be displayed, thus requiring a customized LCD display.
Driver Information Center (DIC)
The DIC requirement is a two-line, 18-character display. You first need to choose between a VF tube and LCD displays. Both types are common in DICs. In our case, we will select an LCD display with back lighting. The next step is to choose the display driver. This display should be accessible by the processor using SPI/I2C. Depending on the type and number of characters to be displayed, the display driver should have enough character-generator ROM. Features such as a reverse video option should be taken under consideration while choosing the driver.
Serial Communication Module
We first need to identify the type of in-vehicle communication the vehicle will use. The latest microcontrollers have in-built communication modules, supporting protocols such as SAE J1850, CAN, and KW2000. Another alternative is to have an external chip that connects directly to the bus accessed by the microcontroller using SPI/I2C.
Microcontroller
The microcontroller selection is one of the most critical parts of the system design. You have many considerations to take into account, both software and hardware, in selecting the ideal microcontroller. Following are the minimum requirements for our processor.
  • 30 I/O lines that are pin addressable
  • Analog-to-digital module with five A/D channels/pins
  • An SPI/I2C module capable of driving five devices
  • External/Internal Interrupt capability
  • Two to four general-purpose timers.
Other than these functions, you may also consider other built-in functions for the microcontroller, such as a built-in vehicle communication module, stepper driver, or LCD driver. On average, the complete processor software will occupy 70 to 90 Kbytes of ROM, 3 to 4 Kbytes of RAM, and 100 to 200 bytes of EEPROM. The microcontroller you select must have enough on-chip memory. You use the EEPROM for data backup, so it is best to keep it outside the processor. EEPROM chips with 256 bytes, accessible through SPI/I2C, are available.
You next need to choose the processor type and clock frequency. The system can use either a 16- or 8-bit processor, depending on the complexity of the processing. We may have a tradeoff between bits and clock frequency. Optimum clock frequency to use is around 4 MHz for a 16-bit processor or 8 MHz for an 8-bit device.
Detailed Block Diagram
After selecting the required components for the IPC, you next need to design the electrical circuit. Before going to that step, we need a detailed block diagram for better clarity.
Microcontroller
Figure 2 shows the configuration of the microcontroller pins. Separate pins are used to enable the peripherals. The built-in ADC senses all the analog inputs. Separate port pins are used to give pulses to the corresponding stepper motors. Write software such that with one direction pin, you can control the direction of all the stepper motors independently. Vehicle speed pulse train is given to the Capture interrupt/Timer pin so that no pulses are missed. A wakeup interrupt pin is provided for waking up the controller from sleep mode. Two PWM pins are provided to control the backlighting of the LCD odometer and DIC.

Figure 2:  Microcontroller pinout
Stepper Motor
Figure 3 shows the block diagram of stepper motor section. A quad stepper driver is used to control the stepper motors. Pulse train input for each stepper comes directly from the microcontroller. A single direction pin is used to control all the stepper motors. Software will take care of independently controlling the motors.

Figure 3:  Stepper motor controller
Serial Peripheral Interface
Through SPI, we will transfer data between the microcontroller and devices such as external EEPROM, LCD driver, LED driver, DIC driver, and communication module (Figure 4). The communication module and EEPROM have two-way communications. The other devices are also connected as bi-directional units since, at times, the microcontroller needs to read the status of the control registers.
Signal Conditioning
The signal conditioning section (Figure 5) deals with the conversion of various signals to signals compatible with the microcontroller. Ignition and battery voltages are scaled down to a 5V range. A 2.5V reference voltage is generated from regulated 5V DC. The regulator supplies power for all the peripheral ICs and circuits. The microcontroller can switch off the regulator using PWR_EN. The processor will go into sleep mode when the ignition switch is off and there is no activity on the communication bus. The processor is awakened by the WAKE_UP signal, generated by OR-ing Bus status, ignition switch and trip switch.

Figure 5:  IPC signal conditioning
After completing the detailed block diagram, we can design the electrical circuit. Details of this task are beyond the scope of this article.
Software Design
In a real-time embedded system, software plays the most important role in how the system functions. Now you have a system, which you need to make intelligent by developing the appropriate software. There are many parameters you need to consider before writing the code, such as selecting the operating system, device drivers, and communication-handling protocols. It is good practice to write the code after preparing the design documents. Design documentation consists of a control flow diagram, data flow diagram, data dictionary, and pseudo code/flow chart.
Real Time Operating System (RTOS)
Since the cluster program is straightforward and does not require very complex priority handling, we do not need a commercial RTOS. We can design our own non-preemptive operating system. The basic time rate is dependent on the time-critical specifications. In our case, this rate is around 10 ms. We can have tasks occurring at:
10 ms
20 ms
200 ms
500 ms
1 second
You can design the operating system such that only two task combinations are occurring in one time slot. Table 1 shows a typical arrangement of the tasks in the RTOS (placing of a one-second task is not shown in this table. Assume the one-second task is in the 94th time slot).

Table 1:  Typical arrangement of the tasks in the RTOS
From the Table 1 arrangement we will get task combinations such as:
Task Combinations
10 ms
10 ms + 20 ms
10 ms + 200 ms
10 ms + 500 ms
10 ms + 1 second
After deciding on the structure of the RTOS, we have to allocate our functions in the corresponding tasks. Care should be taken not to overflow the time slot. The 10 ms task should be made the minimum execution time so that there is enough room for other task combinations.
Language Selection
Writing the code in assembly code will make it compact and faster, but reduces code maintainability. Many programming languages are available for Embedded software development such as C, Modula 2, and ADA. It is a good idea to use C as the programming language because of the language's easy portability, reuse, and popularity.
Device Drivers
Device-driver development is another important task in software design. This is very specific to the processor and types of devices you use. We can reuse the device driver modules if they are available in similar projects with the same processor. You must develop the modules to handle an SPI interface with different devices, analog-to-digital conversion, stepper-motor control, and I/O handling.
Communication Handlers
The communication in a real-time system is usually mapped with an Open System Interconnection (OSI) Seven Layer model for communication networks.
Following are the seven OSI layers:
  1. Application
  2. Presentation
  3. Session
  4. Transport
  5. Network
  6. Data Link
  7. Physical.
While considering in-vehicle communication protocols like J1850 or CAN, we may not exactly map to OSI layers. The generic communication-handler modules will usually be available. We have to make these modules compatible with the cluster software. Following is a discussion of the software layers normally used in vehicle communications. While designing the software, it is good practice to place each layer in a separate module.
  • Device-Driver Layer—This software layer provides the control necessary to manage data flow in and out of the protocol device. The primary purpose of this layer is to convert service requests to device-specific commands, and to convert device-specific status information to a device-independent format. The upper layers utilize this layer to move byte streams to and from the protocol device without needing to know what specific protocol device implementation is present. In our case, we are using SPI to communicate with the protocol device. We will use a separate device driver for SPI communication, and will use the same device-driver functions for communicating with the protocol device.
  • Message Loader/Unloader Layer—This software layer is used to manage one specific message which is either to be transmitted on or received from the link. From the transmit perspective, this layer is used to construct a valid message and pass the resulting byte sequence to the device driver, one byte at a time. From the receive perspective, this layer is responsible for constructing and buffering valid messages from the sequence of bytes passed to the layer from the device driver.
  • Message-Manager Layer—This software layer is used to manage the collection of messages utilized by the device. From the transmit perspective, this layer is used to determine which message is next to be transmitted on the link, and to request from the message loader/unloader that the message be transmitted. From the receive perspective, this layer is responsible for processing received messages passed to this layer from the message loader/unloader.
  • Application Layer—This layer consists of software that generates the message transmission requests and utilizes received message transmissions. This layer is the ultimate source and destination of all message data. In our case, fuel messages, warning messages, and telltale messages, among others, are received through in-vehicle communication. The application layer will pass the data to the corresponding application modules for processing and taking actions dependent on the received data.
Application-Software Development
The final major task in software development is writing the application code. First we will split the complete application into different features. This is the phase for which we need to gather exact customer requirements, including all the minute details. After the necessary clarifications, we will finally go to the system's features. We will allocate separate modules for each feature. Some features can have more than one module, depending on how we can maintain and reuse that module. Modules will have global functions, which will be called directly or indirectly in the appropriate time-slot of the RTOS. The following features/modules will be appropriate for our application.
  • Odometer Value Computation
    Computes and updates the odometer by taking the pulse input from the vehicle speed sensor.
  • Odometer Display
    Converts odometer data to a displayable format.
  • Telltales Display
    Turns on the LEDs depending on the various status of the vehicle.
  • Gauges
    Process various parameters and convert them into a format that can drive the stepper motors.
  • Stepper-Motor Interface
    Drives the stepper motor by generating pulses to the stepper driver.
  • Power Mode
    Determines the power mode of the cluster by looking into the ignition switch status and power-mode message from other vehicle modules.
  • Driver-Information-Center Functions
    Processes various driver-information functions, including trip distance, average speed, fuel economy, fuel used, range distance, and outside air temperature, and converts the data into a displayable format. Many calculations and algorithms might be involved in this operation. It is good practice to have separate modules for each of these functions.
  • Serial Peripheral Interface
    Handles the SPI interface between the microcontroller and peripherals.
  • Dot-Matrix LCD Driver
    Sends various DIC parameters to the LCD display through SPI.
  • Seven-Segment LCD Driver
    Sends odometer data to the seven-segment LCD display through SPI.
  • LED Display Driver
    Telltale displays are illuminated by setting the corresponding bits and sending the bits to the LED driver through SPI.
  • Dimming
    Backlighting of LCD displays, gauge backlighting, and LED intensity are controlled by the PWM output from the microcontroller.
  • Input/Output Processing
    Reads various input ports and periodically sets the output ports.
  • ADC Handling
    Periodically converts all the ADC-channel data and stores the result.
  • External EEPROM Handling
    The external EEPROM is read and written through SPI. Putting data in a buffer and sending it bit-by-bit serially needs to be handled properly since an EEPROM write may take 3 to 10 ms. You can use separate modules for the EEPROM driver and EEPROM queue handling.

Sunday, May 11, 2014

Basic Interview Questions(Embedded C Programming)

1. What is Storage class? Explain with example  
The storage class determines the part of memory where storage is allocated for an object (particularly variables and functions) and how long the storage allocation continues to exist. In C program, there are four storage classes: automatic, register, external and static.
    1.  Auto
      • They are declared at the start of a program’s block such as in the curly braces ( { } ).  Memory is allocated automatically upon entry to a block and freed automatically upon exit from the block.
      • Automatic variables may be specified upon declaration to be of storage class auto.  However, it is not required to use the keyword auto because by default, storage class within a block is auto.
      Register
      Automatic variables are allocated in the main memory of the processor; accessing these memory location for computation will take long time.
      • when we required to optimize the execution time, move the critical variable to processor register. this can be done by using the register key word.
      • when storage class is register, compiler is instructed to allocate a register for this variable.
      • scope of the register variable is same as auto variable.
      NOTE: Allocation of register is not guaranteed always, it depends on number register available in processor and number register used for manipulation. if you define 4 variable as register storage class and and processor has only 2 register for variable allocation, then compiler will allocate 2 variable in registers and treat the remaining 2 variable as auto variable. therefore usage of register keyword should should be justified and cross checked with disassembly weather register is allocated or not.
      Extern
      • For using the external global variable from other files extern keyword is used.
      • any file can access this global variable and lifetime over entire program run.
      Static
      • static variable have lifetime over entire program run.
      • scope of this variable is limited based on the place of declaration.
      • if static variable is defined in a file and not inside any function, then scope of the variable is limited within that file.
      • if static variable is defined inside a function, then the scope of the variable is limited within that function.
      • we can use this variable any file and any function indirectly by accessing through pointer.
2. what is qualifiers?   
 
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.
3. What are volatile variables? Where we should use?
A volatile variable is one that can change unexpectedly. Consequently, the compiler can make no assumptions about the value of the variable. In particular, the optimizer must be careful to reload the variable every time it is used instead of holding a copy in a register. Examples of volatile variables are:
  • Hardware registers in peripherals (for example, status registers)
  • Non-automatic variables referenced within an interrupt service routine
  • Variables shared by multiple tasks in a multi-threaded applications
4. What does the keyword const mean? What do the following declarations mean?
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
The first two mean the same thing, namely a is a const (read-only) integer.
The third means a is a pointer to a const integer (that is, the integer isn’t modifiable, but the pointer is).
The fourth declares a to be a const pointer to an integer (that is, the integer pointed to by a is modifiable,but the pointer is not).
The final declaration declares a to be a const pointer to a const integer
(that is, neither the integer pointed to by a, nor the pointer itself may be modified).
5. Can a parameter be both const and volatile ? Explain.
Yes. An example is a read-only status register. It is volatile because it can change unexpectedly. It is const because the program should not attempt to modify it
6. Can a pointer be volatile ? Explain.
   Yes, although this is not very common. An example is when an interrupt service routine modifies a pointer to a buffer
7. What’s wrong with the following function?
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
This one is wicked. The intent of the code is to return the square of the value pointed to by *ptr . However, since *ptr points to a volatile parameter, the compiler will generate code that looks something like this:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
}
Because it’s possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square! The correct way to code this is:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
8. Data Declarations
a) int a; // An integer
b) int *a; // A pointer to an integer
c) int **a; // A pointer to a pointer to an integer
d) int a[10]; // An array of 10 integers
e) int *a[10]; // An array of 10 pointers to integers
f) int (*a)[10]; // A pointer to an array of 10 integers
g) int (*a)(int); // A pointer to a function a that takes an integer argument and
returns an integer
h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer
argument and return an integer
10. What are Dangling pointers and Wild Pointers
Dangling Pointer :
Dangling pointers in computer programming are pointers that do not point to a valid object of the appropriate type. Dangling pointers arise when an object is deleted or deallocated, without modifying the value of the pointer, so that the pointer still points to the memory location of the deallocated memory.
Examples of Dangling Pointers
int main()
{
     int *p;
     p = (int *) malloc (sizeof (int));
    free(p);
    *p=10;
}
In the above piece of code we are using *p after we free the memory to it.
Such usage is called dangling pointer usage.
int main()
{
int *p = NULL;
{
int a = 10;
p = &a;
}
/*address of a is out of scope and pointer p is now called the dangling pointer, we should initialize the p to NULL before coming out or initialize the pointer to some known value before using it again*/

}
int* fun1()
{
int a = 10;
return(&a); /*in this line we are returning the pointer of variable ‘a’ which is out scope.*/
}
Wild Pointers:
Wild pointers are created by omitting necessary initialization prior to first use. Thus, strictly speaking, every pointer in programming languages which do not enforce initialization begins as a wild pointer. This most often occurs due to jumping over the initialization, not by omitting it. Most compilers are able to warn about this.
{
int* a;
/* a is wild pointer, it is not initialized and it may have some garbage value*/
}
correct way is
{
int* a = NULL;
}
10. When should unions be used? Why do we need them in Embedded Systems  programming?
Unions are particularly useful in Embedded programming or in situations where direct access to the hardware/memory is needed. Here is a trivial example:
typedef union
{
    struct {
        unsigned char byte1;
        unsigned char byte2;
        unsigned char byte3;
        unsigned char byte4;
    } bytes;
    unsigned int dword;
} HW_Register;
HW_Register reg;
Then you can access the reg as follows:
reg.dword = 0×12345678;
reg.bytes.byte3 = 4;
Endianism and processor architecture are of course important.
Another useful feature is the bit modifier:
typedef union
{
    struct {
        unsigned char b1:1;
        unsigned char b2:1;
        unsigned char b3:1;
        unsigned char b4:1;
        unsigned char reserved:4;
    } bits;
    unsigned char byte;
} HW_RegisterB;
HW_RegisterB reg;
With this code you can access directly a single bit in the register/memory address:
x = reg.bits.b2;
Low level system programming is a reasonable example.
unions are used to breakdown hardware registers into the component bits. So, you can access an 8-bit register into the component bits.
This structure would allow a control register to be accessed as a control_byte or via the individual bits. It would be important to ensure the bits map on to the correct register bits for a given endianness.
typedef union {
    unsigned char control_byte;
    struct {
        unsigned int nibble  : 4;
        unsigned int nmi     : 1;
        unsigned int enabled : 1;
        unsigned int fired   : 1;
        unsigned int control : 1;
    }
} ControlRegister;
11. Why is sizeof(‘a’) not 1?
Perhaps surprisingly, character constants in C are of type int, so sizeof(‘a’) is sizeof(int) (though it’s different in C++).
Result:
In Turbo C output is: 2
In Turbo C++ output is: 1
 
12. why n++ executes faster than n+1? 
The expression n++ requires a single machine instruction such as INR to carry out the increment operation whereas, n+1 requires more instructions to carry out this operation.
13. Volatile explanation revisited !
Another use for volatile is signal handlers. If you have code like this:
quit = 0;
while (!quit)
{
    /* very small loop which is completely visible to the compiler */
}
The compiler is allowed to notice the loop body does not touch the quit variable and convert the loop to a while (true) loop. Even if the quit variable is set on the signal handler for SIGINT andSIGTERM; the compiler has no way to know that.
However, if the quit variable is declared volatile, the compiler is forced to load it every time, because it can be modified elsewhere. This is exactly what you want in this situation.
14. Data Alignment & Structure Padding
Data Alignment: Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system’s performance due to the way the CPU handles memory
Data Structure Padding: To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding
Here is a structure with members of various types, totaling 8 bytes before compilation:
struct MixedData
{
    char Data1;
    short Data2;
    int Data3;
    char Data4;
};
After compilation the data structure will be supplemented with padding bytes to ensure a proper alignment for each of its members:
struct MixedData  /* After compilation in 32-bit x86 machine */
{
    char Data1; /* 1 byte */
    char Padding1[1]; /* 1 byte for the following 'short' to be aligned on a 2 byte boundary 
assuming that the address where structure begins is an even number */
    short Data2; /* 2 bytes */
    int Data3;  /* 4 bytes - largest structure member */
    char Data4; /* 1 byte */
    char Padding2[3]; /* 3 bytes to make total size of the structure 12 bytes */
};
The compiled size of the structure is now 12 bytes. It is important to note that the last member is padded with the number of bytes required so that the total size of the structure should be a multiple of the largest alignment of any structure member (alignment(int) in this case, which = 4 on linux-32bit/gcc)
In this case 3 bytes are added to the last member to pad the structure to the size of a 12 bytes (alignment(int) × 3).
struct FinalPad {
  float x;
  char n[1];
};
In this example the total size of the structure sizeof(FinalPad) = 8, not 5 (so that the size is a multiple of 4 (alignment of float)).
struct FinalPadShort {
  short s;
  char n[3];                                                                                
};
In this example the total size of the structure sizeof(FinalPadShort) = 6, not 5 (not 8 either) (so that the size is a multiple of 2 (alignment(short) = 2 on linux-32bit/gcc)).
It is possible to change the alignment of structures to reduce the memory they require (or to conform to an existing format) by reordering structure members or changing the compiler’s alignment (or “packing”) of structure members.
struct MixedData  /* after reordering */
{
    char Data1;
    char Data4;   /* reordered */
    short Data2;
    int Data3;  
};
The compiled size of the structure now matches the pre-compiled size of8 bytes. Note that Padding1[1] has been replaced (and thus eliminated) byData4 and Padding2[3] is no longer necessary as the structure is already aligned to the size of a long word.
The alternative method of enforcing the MixedData structure to be aligned to a one byte boundary will cause the pre-processor to discard the pre-determined alignment of the structure members and thus no padding bytes would be inserted.
While there is no standard way of defining the alignment of structure members, some compilers use #pragma directives to specify packing inside source files. Here is an example:
#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */

struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
};

#pragma pack(pop)   /* restore original alignment from stack */
This structure would have a compiled size of 6 bytes on a 32-bit system. The above directives are available in compilers from Microsoft, Borland, GNU and many others.
Another example:
struct MyPackedData
{
    char Data1;
    long Data2 __attribute__((packed));
    char Data3;
};

15. What is the difference between 'for' and 'while' loops?
for loop: When it is desired to do initialization, condition check and increment/decrement in a single statement of 
an iterative loop, it is recommended to use 'for' loop. 
Syntax:
for(initialization;condition;increment/decrement)
{
//block of statements
increment or decrement
} 
Program: Program to illustrate for loop 
#include<stdio.h>
int main() {
 int i;
 for (i = 1; i <= 5; i++) {
 //print the number
 printf("\n %d", i);
 }
 return 0;
}
Output:
1
2
3
4
5
Explanation:
The loop repeats for 5 times and prints value of 'i' each time. 'i' increases by 1 for every cycle of loop. 
while loop: When it is not necessary to do initialization, condition check and increment/decrement in a single 
statement of an iterative loop, while loop could be used. In while loop statement, only condition statement is 
present. 
Syntax:
#include<stdio.h>
int main() {
 int i = 0, flag = 0;
 int a[10] = { 0, 1, 4, 6, 89, 54, 78, 25, 635, 500 };
 //This loop is repeated until the condition is false
 while (flag == 0) {
 if (a[i] == 54) {
 //as element is found, flag = 1,the loop terminates
 flag = 1;
 }
 else {
 i++;
 }
 }
 printf("Element found at %d th location", i);
 return 0;
}
Output:
Element found at 5th location
Explanation:
Here flag is initialized to zero. 'while' loop repeats until the value of flag is zero, increments i by 1. 'if' condition 
checks whether number 54 is found. If found, value of flag is set to 1 and 'while' loop terminates. 
16.Which bitwise operator is suitable for checking whether a particular bit is ON or OFF?
Bitwise AND operator.
Example: Suppose in byte that has a value 10101101 . We wish to check whether bit number 3 is ON (1) or OFF 
(0) . Since we want to check the bit number 3, the second operand for AND operation we choose is binary 
00001000, which is equal to 8 in decimal. 
Explanation: 
ANDing operation : 
 10101101 original bit pattern
 00001000 AND mask
 ---------
 00001000 resulting bit pattern
 --------- 
The resulting value we get in this case is 8, i.e. the value of the second operand. The result turned out to be a 8 
since the third bit of operand was ON. Had it been OFF, the bit number 3 in the resulting bit pattern would have 
evaluated to 0 and complete bit pattern would have been 00000000. Thus depending upon the bit number to be 
checked in the first operand we decide the second operand, and on ANDing these two operands the result 
decides whether the bit was ON or OFF.
17. Which bitwise operator is suitable for turning OFF a particular bit in a number? 
Bitwise AND operator (&), one's complement operator(~) 
Example: To unset the 4th bit of byte_data or to turn off a particular bit in a number.
Explanation: 
Consider,
char byte_data= 0b00010111;
byte_data= (byte_data)&(~(1<<4));
1 can be represented in binary as 0b00000001 = (1<<4)
<< is a left bit shift operator, 
it shifts the bit 1 by 4 places towards left.
(1<<4) becomes 0b00010000
And ~ is the one's complement operator in C language.
So ~(1<<4) = complement of 0b00010000
 = 0b11101111
Replacing value of byte_data and ~(1<<4) in

(byte_data)&(~(1<<4));

we get (0b00010111) & (0b11101111)
Perform AND operation to below bytes.
 00010111
 11101111
 -----------
 00000111
 -----------
Thus the 4th bit is unset.