Tuesday, October 22, 2019

Stack and Stack Overflow

Hello Guys, In this section we will discuss about -
1. What is Stack ?
2. What is Stack overflow ?
3. How to avoid Stack overflow ?
Basically, this will be related to Embedded Systems.       

What is stack?
Stack is a special region of our process's memory, where processes are tracked. The types of data stored in the stack include -
1. local variables
2. return addresses
3. function arguments
4. compiler temporaries
5. interrupt contexts

So basically, we can say that the stack is an area of RAM where a program stores temporary data during the execution of code blocks.
Whenever a new local variable is declared it is pushed onto the stack.
The life span of variables on the stack is limited to the duration of the function. As soon as the function returns, the used stack memory will be free for use by subsequent function calls.
Stack follows Last-In-First-Out data structure.
A “stack pointer” register tracks the top of the stack; it is adjusted each time a value is “pushed” onto the stack. The set of values pushed for one function call is termed a “stack frame”; A stack frame consists at minimum of a return address.
Each time a function is called, the address of where to return to and certain information about the caller’s environment, such as some of the machine registers, are saved on the stack. The newly called function then allocates room on the stack for its automatic and temporary variables. This is how recursive functions in C can work. Each time a recursive function calls itself, a new stack frame is used, so one set of variables doesn’t interfere with the variables from another instance of the function.
We need to recognize that many, and indeed most, embedded systems contain multiple stacks.
Some common combinations are Single stack, Two stacks, One stack per task. 
Single stack - This is the classic approach where function return addresses, parameters, automatic variables and registers are all saved on to a single stack, microchips 32-bit compiler when used without an RTOS has this architecture.
Two stacks, one for return addresses and one for everything else. This approach is used by IAR. IAR refers to these two stacks as the RSTACK and the CSTACK. You also effectively get this approach with microprocessors that have a hardware return stack. For example, on 8-bit PIC processors.
Two stacks, one for exception handling and one for everything else. This is often done with hardware that has a dedicated exception stack.
One stack per task. This is a common approach when using an RSTACK.
How stack grows?
On the standard PC x86 computer architecture it grows toward address zero, on some other architectures it grows the opposite direction.

What is stack overflow?
Stack overflow is when a function or program uses more memory than is in the stack. As it grows beyond its allocated space, the dynamic stack contents begin to overwrite other things, such as critical application code and data. The stack is a fixed amount of memory that is set statically by the programmer before execution.
In embedded systems you might only have 256 bytes for the stack, and if each function takes up 32 bytes then you can only have function calls 8 deep - function 1 calls function 2 who calls function 3 who calls function 4 .... who calls function 8 who calls function 9, but function 9 overwrites memory outside the stack. This might overwrite memory, code, etc.
Many programmers make this mistake by calling function A that then calls function B, that then calls function C, that then calls function A. It might work most of the time, but just once the wrong input will cause it to go in that circle forever until the computer recognizes that the stack is overblown.
Recursive functions are also a cause for this, but if you're writing recursively (i.e. your function calls itself) then you need to be aware of this and use static/global variables to prevent infinite recursion.
So basically following There are two cases in which stack overflow can occur-
1. If we declare large number of local variables or declare an array or matrix or any higher dimensional array of large size can result in overflow of stack.
2. If function recursively call itself infinite times then the stack is unable to store large number of local variables used by every function call and will result in overflow of stack.



The above fig. describes how stack overwrites adjacent memory.

How to avoid stack overflow?
Embedded Systems
In the embedded world, especially in high reliability code (automotive, aircraft, space) you do extensive code reviews and checking, but you also do the following-
  • Disallow recursion and cycles - enforced by policy and testing.
  • Keep code and stack far apart (code in flash, stack in RAM, and never the twain shall meet).
  • Place guard bands around the stack - empty area of memory that you fill with a magic number (usually a software interrupt instruction, but there are many options here), and hundreds or thousands of times a second you look at the guard bands to make sure they haven't been overwritten.
  • Use memory protection (I.e. no execute on the stack, no read or write just outside the stack).
  • Interrupts don't call secondary functions - they set flags, copy data, and let the application take care of processing it (otherwise you might get 8 deep in your function call tree, have an interrupt, and then go out another few functions inside the interrupt, causing the blowout). You have several call trees - one for the main processes, and one for each interrupt. If your interrupts can interrupt each other... well, there be dragons…

High-level languages and systems

But in high level languages run on operating systems-
  • Reduce your local variable storage (local variables are stored on the stack - although compilers are pretty smart about this and will sometimes put big locals on the heap if your call tree is shallow)
  • Avoid or strictly limit recursion.
  • Don't break your programs up too far into smaller and smaller functions - even without counting local variables each function call consumes as much as 64 bytes on the stack (32 bit processor, saving half the CPU registers, flags, etc)
Keep your call tree shallow (similar to the above statement)

 To prevent - always make sure there's an exit path that will be hit.

Stack sentinels and avoidance of recursion are an entrenched part of embedded systems.
MISRA Software Guidelines discourage recursion, saying that it can cause unpredictable behavior (MISRA Guidelines, pg. 20).



NASA recommends using stack guards (essentially the same as the technique that I call “stack sentinels”) to check for stack overflow or corruption (NASA 2004, p. 93).

Some best practices for preventing stack overflow
  • Avoid stack-hogging functions like printf( ) and related functions. Try to pass by reference instead of by copy. When passing by copy, it tends to go on the stack, particularly if it’s an array. With an array, it’s easier to run out of the stack and overflow the stack rapidly.
  • Another best practice is to limit the number of arguments to a function; for example, the first four arguments go into registers, and all subsequent arguments go onto the stack.  The Application Binary Interface (ABI) of an MCU tells a compiler how many arguments can be passed in the registers; all others must be passed on the stack.
  • Last, avoid recursive functions (a function that calls itself) as they use a significant portion of the stack as they go deeper. If you must use recursion, set variables to stop infinite recursion from happening. However, it’s a good practice to avoid recursion altogether.

Some solutions mentioned above are not portable, but quite fine.
It is typically part of compiler’s job to adhere to an ABI. An embedded ABI operates at the machine code level and determines how function calls are made, file formatting, use of the register, and the framework of the stack. ABIs vary between architectures in the embedded world.

Monday, August 12, 2019

Communication Protocol for Embedded Systems - Part 1 (I2C)


Hey, Let's discuss about communication protocols commonly used in embedded field. So, Let’s begin with what communication protocol actually mean.

Communication - Imparting of information from one system to another system via a medium is termed is Communication.

Protocol - Standard set of rules which determine how data is transmitted at both ends of communication.

So, we can say that Communication Protocol is basically standard set of rules that allow two electronic devices to connect to exchange data within them.
There are two types of electronics’ communication protocol -
1. Inter System Communication Protocol
2. Intra System Communication Protocol

Inter System Communication Protocol - This protocol is used to communicate the two different devices like communication between PC and Micro-controller, PC and Development Boards. In this scenario, communication is done via inter bus system.

Inter System Communication Protocol can be divided into 3 categories -
a. USB Communication Protocol
b. UART Communication Protocol
c. USART Communication Protocol

Intra System Communication Protocol - This protocol establishes the communication between the two devices within circuit board like Micro-controller and Sensors. Advantage of Intra System Communication Protocol is secure data access.

Intra System Communication Protocol can be divided into 3 categories -
a. I2C Protocol
b. SPI Protocol
c. CAN Protocol
In this blog, we will study in detail about Intra System Communication Protocol. 
So, let’s begin with I2C Protocol.

I2C Protocol -
The name I2C is shorthand for a standard Inter-Integrated Circuit bus.
I2C protocol is intended to allow multiple "slave" digital integrated circuits ("chips") to communicate with one or more "master" chips. Like the Serial Peripheral Interface (SPI), it is only intended for short distance communications within a single device. Like Asynchronous Serial Interfaces (such as RS-232 or UARTs), it only requires two signal wires to exchange information.

I2C features -
Wires Used
2
Maximum Speed
Standard Mode - 100 kbps
Fast Mode - 400 kbps
High Speed Mode - 3.4 Mbps
Ultra Fast Mode - 5 Mbps
Synchronous or Asynchronous
Synchronous
Serial or Parallel
Serial
Max number of Masters
Unlimited
Max number of Slaves
128 for 7-bit address
1024 for 10-bit address
(Theoretically)*
 *Actually there are some reserved addresses like 0x00.
I2C necessitates two wires SDA (Serial Data Line) and SCL (Serial Clock Line) to carry information between devices. These two active wires are said to be bidirectional.

SDA - The line for the master and slave to send and receive data.
SCL (Serial Clock) – The line that carries the clock signal.
Since, I2C is a serial communication protocol, so data is transferred bit by bit along a single wire (SDA line).

Open-Drain Outputs
Having pull-up resistors is an open-drain scheme. I2C bus devices pull-down the voltage on the bus instead of using their own operating voltage. The pull-up resistor value depend on a number of factors. There are number of  formulas to calculate the correct pull-up resistor value.
If you don’t want to bother calculating the resistor value, use the typical 10  or 4.7 kΩ.

I2C Basic Commands Sequence
1. Start Bit Condition
2. Stop Bit Condition
3. Acknowledgement Condition
4. Master to slave Write operation
5. Read Operation Slave to Master

I2C Timing Diagram


Both SDA and SCL lines are high when idle. A start condition occurs when the SDA goes low before the SCL. Data is sent immediately following the start condition. The end of transmission is signaled by a stop condition. A stop condition occurs when the SDA goes high after SCL.

Start and Stop Bit Condition
When the master (micro-controller) wishes to talk to a slave device (for example ADC), it begins communication by issuing a start condition on the I2C bus, and then issues a stop condition. The I2C start and stop logic levels are shown in the figure.
The I2C start condition defines as a high to low transition of the SDA line while the SCL line is high. AN I2C stop condition occurs when the SDA line toggles from low to high while the SCL line is high.
The I2C master always generates the Start (S) and Stop (P) conditions. Once the I2C master initiates a START condition, the I2c bus is considered as being in busy state.

 

Besides this there is also a “Repeated Start” condition which allows a master to continue the current transaction without losing atomicity.
This is achieved by NOT sending a stop after the transaction but sending a Start in its place.

Acknowledgement Condition
Each byte transmitted over the I2C bus is followed by an acknowledge condition from the receiver, which means, after the master pulls SCL low to complete the transmission of 8-bit, the SDA will be pulled low by the receiver to the master.
If, after the transmission of the receiver does not pull, the SDA line LOW is considered to be a NCK condition.

 


Master to Slave Write Operation
1. Send a start sequence
2. Send the I2C address of the slave with the R/W bit low (even address)
3. Send the internal register number you want to write to
4. Send the data byte
5. [Optionally, send any further data bytes]
6. Send the stop sequence.
The bit sequence will look like this -



Read Operation Slave to Master
1. Send a start sequence
2. Send 0xC0 ( I2C address of the CMPS03 with the R/W bit low (even address)
3. Send 0x01 (Internal address of the bearing register)
4. Send a start sequence again (repeated start)
5. Send 0xC1 ( I2C address of the CMPS03 with the R/W bit high (odd address)
6. Read data byte from CMPS03
7. Send the stop sequence.
The bit sequence will look like this -


Advantages of I2C
1. Devices can work as both master and slave.
2. I2C employs better error handling functionality.
3. Addressing mechanism eases master slave communication

Disadvantages of I2C
1. The biggest disadvantage of I2C Communication Protocols is its limited speed.
2. The size of the data frame is limited to 8 bits.
3. I2C is a half-duplex protocol which adds complexity.

Applications
I2C is used where short distance communication within boards or devices are needed and when we need to connect more devices to the network.