-->

Sunday, November 30, 2014

What is little endian and big endian or What is Network byte order and host byte order ?




               Little endian and Big endian are memory architecture to store Multi byte data into memory.Say integer,float data types are occupy more then 1 byte in memory.And these are also called as Network Byte order and Host byte order.

Little endian?

      Little endian means lower order byte in number is stored lower order address in memory.
 

       For example:

                     int number = 0x1234;
                  
                     Memory Address              Value                       
                        1000                                    34           ------>   Base_Addr_0 +  Lower_order_byte;
                        1002                                    12           ------>  Base_Addr_1  +  Higher_order_byte;


Big endian?


     Big endian means higher order byte in number is stored lower order address in memory..

For example:


                   int number = 0x1234;

                     Memory Address              Value
                      
                       1000                                    12             ---->   Base_Addr_0 +  Higher_order_byte;
                       1002                                    34            ----->  Base_Addr_1  +  Lower_order_byte;
 

The above example shows memory representation of integer data type which is stored Little and Big endian machines.

How to check your PC is based on little endian or big endian Architecture?

 Here, some example given below:-

      Example 1:

             
void main(void)
                  {
                           int number = 0x1234;   // 0x represent as Hex value
                           char *ptr=(char*) & number;  
                           if(*c==0x34)
                                   {printf("Little Endian");}

                           else if(*c==0x12)
                                    {printf("Big Endian");}
                            else { printf("**************");}

                   }
     Example 2:

             
void main(void)
                      {
                             int number =1;
                             if(*(char)&number==1)printf("Little Endian");                         
                            else printf("Big Endian");
                      }
                    
    Example 3: 

              
void show_memory(unsigned char*,unsigned char);  //Function declaration.
               void main(void)

                      {
                              int number= 0x1234;
                              char *ptr =(*char)&number;
                              show_memory(*ptr,sizeof(number)); //Function Calling
                              getch(); 
                              return 0;
                       } 

                        
               void show_memory(unsigned char *p,unsigned char n)

                      {
                                for(char i=0;i<n;i++) printf("%d  ",p[i]);                      }
                      

      Note : if your machine is little endian output will be 34 12....Suppose big endian means output will be 12  34


What bi endian? 

    Bi Endian means combination of little and big endian.Bi Endian processor can run in both little and big endian.

      Example of Little and big and Bi endian architecture?
  1. Intel based processors are Little Endian.
  2. ARM based processors were Little Endian...now its became Bi-Endian.
  3. MOTOROLA processors were Big Endian...now its became Bi-Endian.


  

Friday, November 7, 2014


 Disk Storage

   1 Bit = Binary Digit
  8 Bits = 1 Byte
1024 Bytes = 1 Kilobyte
1024 Kilobytes = 1 Megabyte
1024 Megabytes = 1 Gigabyte
1024 Gigabytes = 1 Terabyte
1024 Terabytes = 1 Petabyte
 1024 Petabytes = 1 Exabyte
1024 Exabytes = 1 Zettabyte
1024 Zettabytes = 1 Yottabyte
1024 Yottabytes = 1 Brontobyte
1024 Brontobytes = 1 Geopbyte

Tuesday, October 21, 2014

Interview Question

Question 1 :What is the difference between macros and inline functions?

 Ans : 

 Macro- does not involve in compilation if there is any logical error also just replaces the code.

Inline- look like function, but control doesn't goes to function and execute, it simply replaces the code like macro but involves in compilation. 

Question 2:Difference between structure and union? 

Monday, October 20, 2014

Volatile Keyword


 

 Volatile Keyword:


      volatile is a qualifier that is applied to a variable when it is declared. It tells the compiler that the value of the variable may change at any time-without any action being taken by the code the compiler finds nearby. The implications of this are quite serious. However, before we examine them, let's take a look at the syntax.

Have you experienced any of the following in your C/C++ embedded code? 

          1. Code that works fine-until you turn optimization on.

          2. Code that works fine-as long as interrupts are disabled.

          3. Flaky hardware drivers.

          4. Tasks that work fine in isolation-yet crash when another task is enabled



If you answered yes to any of the above, it's likely that you didn't use the C keyword volatile.

Syntax:


     To declare a variable volatile, include the keyword volatile before or after the data type in the variable definition. For instance both of these declarations will declare foo to be a volatile integer:   

                 volatile int foo;
                 int volatile foo;

     Now, it turns out that pointers to volatile variables are very common. Both of these declarations declare foo to be a pointer to a volatile integer: 

                volatile int * foo; 
                int volatile * foo;  

                int volatile * volatile foo;

     Incidentally, for a great explanation of why you have a choice of where to place volatile and why you should place it after the data type (for example, int volatile * foo), consult Dan Sak's column, "Top-Level cv-Qualifiers in Function Parameters" (February 2000, p. 63).  

     Finally, if you apply volatile to a struct or union, the entire contents of the struct/union are volatile. If you don't want this behavior, you can apply the volatile qualifier to the individual members of the struct/union.



Use 


A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change: 



  1. Memory-mapped peripheral registers
  2. Global variables modified by an interrupt service routine
  3. Global variables within a multi-threaded application .

    

1.Peripheral registers: 


      Embedded systems contain real hardware, usually with sophisticated peripherals. These peripherals contain registers whose values may change asynchronously to the program flow. As a very simple example, consider an 8-bit status register at address 0x1234. It is required that you poll the status register until it becomes non-zero. The nave and incorrect implementation is as follows:  


                UINT1 * ptr = (UINT1 *) 0x1234; 

                
                while (*ptr == 0);// Wait for register to become non-zero.


       This will almost certainly fail as soon as you turn the optimizer on, since the compiler will generate assembly language that looks something like this: 


                mov    ptr, #0x1234     
                mov    a, @ptr loop     
                bz    loop

        The rationale of the optimizer is quite simple: having already read the variable's value into  the accumulator (on the second line), there is no need to reread it, since the value will always be the same. Thus, in the third line, we end up with an infinite loop. To force the compiler to do what we want, we modify the declaration to:  


       UINT1 volatile * ptr = (UINT1 volatile *) 0x1234; 

        The assembly language now looks like this: 

                  mov     ptr, #0x1234
                  loop    mov    a, @ptr  
                  bz    loop 



      The desired behavior is achieved:

     Subtler problems tend to arise with registers that have special properties. For instance, a lot of peripherals contain registers that are cleared simply by reading them. Extra (or fewer) reads than you are intending can cause quite unexpected results in these cases.  

     
2.Interrupt service routines(ISR)

     Interrupt service routines often set variables that are tested in main line code. For example, a serial port interrupt may test each received character to see if it is an ETX character (presumably signifying the end of a message). If the character is an ETX, the ISR might set a global flag. An incorrect implementation of this might be:  


Program #1

     int etx_rcvd = FALSE; 

     void main()
          {
                          
                    while (!ext_rcvd)
                         {
                                 // Wait
                          }
    
          } 

    interrupt void rx_isr(void)
         {
                 ...
               if (ETX == rx_char)
                  {
                      etx_rcvd = TRUE;
                  }
        }


       With optimization turned off, this code might work. However, any half decent optimizer will "break" the code. The problem is that the compiler has no idea that etx_rcvd can be changed within an ISR. As far as the compiler is concerned, the expression !ext_rcvd is always true, and, therefore, you can never exit the while loop. Consequently, all the code after the while loop may simply be removed by the optimizer. If you are lucky, your compiler will warn you about this. If you are unlucky (or you haven't yet learned to take compiler warnings seriously), your code will fail miserably. Naturally, the blame will be placed on a "lousy optimizer." 

      The solution is to declare the variable etx_rcvd to be volatile. Then all of your problems (well, some of them anyway) will disappear. 


3.Multi-threaded applications:

      Despite the presence of queues, pipes, and other scheduler-aware communications mechanisms in real-time operating systems, it is still fairly common for two tasks to exchange information via a shared memory location (that is, a global). When you add a pre-emptive scheduler to your code, your compiler still has no idea what a context switch is or when one might occur. Thus, another task modifying a shared global is conceptually identical to the problem of interrupt service routines discussed previously. So all shared global variables should be declared volatile. For example: 


Program #2

       int cntr; 
       void task1(void)
           {
                cntr = 0;
                while (cntr == 0)
                  {
                       sleep(1);
                  }
           

      void task2(void)
           {
                cntr++;
                sleep(10);
           } 
  

  This code will likely fail once the compiler's optimizer is enabled. Declaring cntr to be volatile is the proper way to solve the problem.  




Q:Can a variable become both constant and volatile?

  A:Yes.

 The const modifier implies that this particular program code cannot change the value of the actual variable, but that will not imply that the value can not be changed by means outside this code.
For instance, within the example in frequently asked questions, the timer structure was accessed through a volatile const pointer.

The function by itself did not change the value of the timer, so it had been declared const. However, the value had been changed by hardware on the computer, so it was declared volatile. If a variable is both equally const and volatile, the two modifiers can come in either order.

Receive Our Quality Tutorials Straight In Your Inbox By Submitting Your Email ID Below...

Your Information Will Never Be Shared.