Posted on Leave a comment

Microcontroller + FPGA

The microcontroller performs the task of minimization of peripherals on the PCB by miniaturization and integrating them in one housing.

FPGA on the other hand is used to implement digital logic. Since FPGA can be programmed in a remote location using standard tools. And the growing market of the FPGA has made the tools required to program and debug very affordable.

There are microcontrollers that have FPGA built inside of them. They can implement very small digital logic. But that will result in the minimization of components on the PCB.

They bridge the gap between a dedicated FPGA and a microcontroller. For small applications which only needs a very small custom logic design, they can be used.

Programmable System-On-Chip (PSoC) from Cypress semiconductor and C2000 TMS320F28379D from Texas Instrument are such examples.

The FPGA can be used to implement the Finite State machines Logic.

The microcontroller manufacturer also provides additional peripheral which can be connected in a customized fashion using the crossbar interconnects to make a custom peripheral. And since the logic is not outside there is high security.

FPGA provided on these microcontrollers cannot replace the traditional FPGA.

PSoC from Cypress is highly configurable and along with digital logic, it also has analogue peripheral such as op-amps and comparator which can be used to create custom logic.

Posted on Leave a comment

Introduction to Embedded System

An embedded system is a combination of software and hardware to perform a specific task at a instant of time.

There are two types of embedded system:

  1. Real-Time
    These are the system in which the output has to reach the desired set-point within an allocated time.
  2. Non Real-Time
    In the system the output doesn’t depend on the input. There is no time window allocation for the performing of task.

An embedded system can be distributed. A distributed embedded system is the one in which you can externally add or subtract specifics components. Example: consumer PC etc.

All the principles of control system directly affect the embedded system.

An Embedded system can be designed in two ways:

  1. Standalone mode
    In standalone mode, the system does all the work independently and doesn’t rely on any other external resources.
  2. Distributed mode
    In distributed mode, the system is a subset and depends on other subsets.

A processing element can be a self-contained unit or it may be spread across physically. example: AMD Sempron 145 is a self-contained unit whereas relay based processing element is physically spread across space.

Posted on Leave a comment

How to use gdb debugger in raspberry pi for ARM assembly programs

After you have written your program. You try to run your program, sometimes the output produced by your program is not as you would have desired.

That’s when you use the debugger to look into the code and figure out what went wrong.

Debugging gives you an insight look into the low level programming instructions that your compiler have produced. But to understand the logic and program execution; you need to know at least the basics of assembly programming.

On Linux based operating system such as Debian, a gdb debugger is available.

But it not very friendly to operate. So there are various tools that make it easy to work with the gdb debugger. One of them is the GEF extension.

The GEF extension provides you with the view of registers, stack and disassembly of program, on a single page.

Posted on Leave a comment

Stack implementation without pointer

Stack is a type of data structure, where data is stored in Last In First Out fashion. In embedded system there are different kind of stacks available.
They are implemented in hardware and software.
The hardware implementation of stack is faster than software stack; but the size of stack in hardware is limited.

There are two types of stack available in hardware implementation:
1. Up-counting
2. Down-counting
Up-counting stack: where the memory location of the top element of stack is incremented from the low memory address;
Down-counting stack where the memory location is decremented from the highest memory address.

The following is a general stack implementation program which is written on x86 machine.


#include <stdio.h>

#define MAX 7

int arr[MAX]; // array of size MAX

int top = -1; //top is the index which stores the location
              // of the last inserted element in stack
/*
isFull Function checks that the top == MAX
isEmpty Function checks that the top == -1
*/
int isFull();
int isEmpty();

/*
push(int num)     To insert a element in stack
pop()             To remove the last inserted element in stack
display()         To display all the element in stack
*/

void pop();
void push(int num);

void display();

int main() {

display();	//display the elements of the stack

    push(32);
    push (1);
    push (26);
    push (64);
    push (127);
    push (-98);
    push (43);
    push (5);
    push (255);
    push (5);
    display();
    pop();

return 0;
}

int isEmpty(){
	if(top == -1){
		return 1;
	}
	else
		return 0;
}

int isFull(){
	if(top == MAX){
		return 1;
	}
	else
		return 0;
}

/*check if the stack is full or not.
If stack full 
write overflow
else 
increment the TOP and write the value.
*/
void push(int num){
	if(isFull()){
	printf("Stack Full OverFlow\n");
	}
	else {
		top++;
		arr[top] = num;
	}
	display();
}
/*check if the stack is empty or not.
If stack empty 
write underflow
else 
decrement the TOP.
*/
void pop(){
	if( isEmpty() ) {
	printf("Stack Full OverFlow\n");
	}
	else {
		top--;
	}
	display();
}

void display(){
	if( isEmpty() ){
		printf("Stack Empty UNDERFLOW\n");
		
	}
	else{
		int temp;
		for(temp = top; temp >= 0 ; temp--){
			printf("%d ",arr[temp]);
		}
		printf("\n");
		/*int *ptr = arr;
		while(ptr <= ((&arr)+MAX) ){
			printf("%d ",*ptr);
			ptr = ptr + 1;
			printf("\n");
		}
		*/
		
	}
}

Output Of the above program


Stack Empty UNDERFLOW

32 

1 32 

26 1 32 

64 26 1 32 

127 64 26 1 32 

-98 127 64 26 1 32 

43 -98 127 64 26 1 32 

5 43 -98 127 64 26 1 32 
Stack Full OverFlow

5 43 -98 127 64 26 1 32 
Stack Full OverFlow

5 43 -98 127 64 26 1 32 

5 43 -98 127 64 26 1 32 

43 -98 127 64 26 1 32 

Posted on Leave a comment

The command-line argument in C

Lets say if we want our program to work with other programs and other program call our program. Then just like how we provide arguments in function call; we can call our program and the arguments can be given using the command line.

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]){
	int arr[5] = {1,2,3,4,5};

	printf("the argument number of of main argc : %d\n",argc);
	printf("The first argument : %s\n",argv[1]);
	
	return 0;
}


argc contains the number of argument passed to the main function.

argv is the argument vector. Contains the argument given from index 1 and above.

index 0 of argv is the file name of the function.

Posted on Leave a comment

Union

Union is another user defined data type.

The difference between union and struct is that; struct uses a contagious memory allocation for each individual item inside it; whereas union uses the size of biggest element for allocation of memory.

union segment1 {
int x1;
char y2;
};

// sizeof segement1 union is 4 bytes 

struct segment2{
int x1;
char y2;
};

// sizeof segement1 union is 8 bytes 

Posted on Leave a comment

Convert program written in C into assembly

Sometimes to understand code , you need to look into assembly language. I write mostly using C. So sometimes to better understand the program i converte the program into assembly. The syntax changes from machine to machine.

Here is the program that i will use to convert to assembly using two different machine. One is ARM based and the other is x86_64.

#include <stdio.h>

struct CarDetail{
int CarNumber;
char CarOptions;
};

int main() {
struct CarDetail maruti_alto;

maruti_alto.CarNumber = 123;
maruti_alto.CarOptions = 'L';

printf("Maruti Alto Details\nNumber = \t%d\nOptions = \t%c",maruti_alto.CarNumber,maruti_alto.CarOptions);
return 0;
}

ARM

If i convert the above program using ARM based machine using command

gcc main.c -S -o main.s
        .arch armv6
	.file	"main.c"
	.text
	.section	.rodata
	.align	2
.LC0:
	.ascii	"Maruti Alto Details\012Number = \011%d\012Options ="
	.ascii	" \011%c\000"
	.text
	.align	2
	.global	main
	.arch armv6
	.syntax unified
	.arm
	.fpu vfp
	.type	main, %function
main:
	@ args = 0, pretend = 0, frame = 8
	@ frame_needed = 1, uses_anonymous_args = 0
	push	{fp, lr}
	add	fp, sp, #4
	sub	sp, sp, #8
	mov	r3, #123
	str	r3, [fp, #-12]
	mov	r3, #76
	strb	r3, [fp, #-8]
	ldr	r3, [fp, #-12]
	ldrb	r2, [fp, #-8]	@ zero_extendqisi2
	mov	r1, r3
	ldr	r0, .L3
	bl	printf
	mov	r3, #0
	mov	r0, r3
	sub	sp, fp, #4
	@ sp needed
	pop	{fp, pc}
.L4:
	.align	2
.L3:
	.word	.LC0
	.size	main, .-main
	.ident	"GCC: (Raspbian 8.3.0-6+rpi1) 8.3.0"
	.section	.note.GNU-stack,"",%progbits

If we want to remove relative addressing modes and make it very simple you can use -fomit-frame-pointer option

gcc main.c -S -fomit-frame-pointer -o main-omit-fp.s
        .arch armv6
	.file	"main.c"
	.text
	.section	.rodata
	.align	2
.LC0:
	.ascii	"Maruti Alto Details\012Number = \011%d\012Options ="
	.ascii	" \011%c\000"
	.text
	.align	2
	.global	main
	.arch armv6
	.syntax unified
	.arm
	.fpu vfp
	.type	main, %function
main:
	@ args = 0, pretend = 0, frame = 8
	@ frame_needed = 0, uses_anonymous_args = 0
	str	lr, [sp, #-4]!
	sub	sp, sp, #12
	mov	r3, #123
	str	r3, [sp]
	mov	r3, #76
	strb	r3, [sp, #4]
	ldr	r3, [sp]
	ldrb	r2, [sp, #4]	@ zero_extendqisi2
	mov	r1, r3
	ldr	r0, .L3
	bl	printf
	mov	r3, #0
	mov	r0, r3
	add	sp, sp, #12
	@ sp needed
	ldr	pc, [sp], #4
.L4:
	.align	2
.L3:
	.word	.LC0
	.size	main, .-main
	.ident	"GCC: (Raspbian 8.3.0-6+rpi1) 8.3.0"
	.section	.note.GNU-stack,"",%progbits

X86_64

gcc main.c -S -o main.s
	.file	"main.c"
	.text
	.section	.rodata
	.align 8
.LC0:
	.string	"Maruti Alto Details\nNumber = \t%d\nOptions = \t%c"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$123, -8(%rbp)
	movb	$76, -4(%rbp)
	movzbl	-4(%rbp), %eax
	movsbl	%al, %edx
	movl	-8(%rbp), %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
	.section	.note.GNU-stack,"",@progbits
gcc main.c -S -fomit-frame-pointer -o main-omit-fp.s
	.file	"main.c"
	.text
	.section	.rodata
	.align 8
.LC0:
	.string	"Maruti Alto Details\nNumber = \t%d\nOptions = \t%c"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	subq	$24, %rsp
	.cfi_def_cfa_offset 32
	movl	$123, 8(%rsp)
	movb	$76, 12(%rsp)
	movzbl	12(%rsp), %eax
	movsbl	%al, %edx
	movl	8(%rsp), %eax
	movl	%eax, %esi
	leaq	.LC0(%rip), %rdi
	movl	$0, %eax
	call	printf@PLT
	movl	$0, %eax
	addq	$24, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
	.section	.note.GNU-stack,"",@progbits
Posted on Leave a comment

Struct

Variables are used for storage of individual data elements. But what if we want to group different data element and use them as a individual element.

//Example 1
#include <stdio.h>
struct tag_name {
int x;
char y;
float z;
}element1;

int main() {
struct tag_name element2;

element1.x = 1;
element1.y = 'a';
element1.z = 3.14;

element2.x = eletment1.x;
element2.y = eletment1.y;
element2.z = eletment1.z;

printf("element 1\nx = %d \ty = %c \tz= %f\nelement 2\nx = %d \ty = %c \tz= %f\n", element1.x,element1.y,element1.z,element2.x,element2.y,element2.z);
return 0;
}
Struct example 1 Code Output
Struct example 1 Code Output

Nesting Struct is a way of creating more complex data structure.

// Example 2
#include <stdio.h>

typedef struct {
int x;
char y;
} point;

int main() {
point p1, *ptPtr;

p1.x = 9;
p1.y = 'x';

printf("p1.x = %d\n",p1.x);
printf("p1.y = %c\n",p1.y);

struct line {
point pt1;
point pt2;
};

struct line l1, *l1Ptr;

l1Ptr = &l1;
ptPtr = &l1.pt1;

l1.pt1.x = 44;
l1.pt1.y = 'r';

printf("l1.pt1.x = %d\n",l1.pt1.x);
printf("l1.pt1.y = %c\n",l1.pt1.y);

printf("l1.pt1.x = %d\n",l1Ptr->pt1.x);
printf("l1.pt1.y = %c\n",ptPtr->y);


return 0;
}


Example 2 output

Posted on Leave a comment

First Program in C language

The very first program in every language is “Hello World”. You can compile this program very easily.

// a single line comment

/*
* A multi line comment
*/

#include <stdio.h> // Header File

int main()         // Marks the start of program 
{ 
    printf("Hello World!\n"); // Prints the "hello world" statement onto the
                              // serial output device such as monitor.
return 0;
}
Posted on Leave a comment

Operating System and Embedded System

An operating system is a software that runs directly on the hardware.

It comes in between user software and hardware. The operating system is a combination of different software’s. Every software that operating system has to perform functions to manage the memory, processing time and complete utilization of resources without any deadlock situations.

At the very core of an operating system is a scheduler, which is guided by a Timer. The timer provides the regular interval for the scheduler to run. The job of the scheduler is to run various user program. It also monitors and controls the allocation of memory space to each user program.

An operating system can be classified as

  • real-time
  • single user
  • multi-user
  • multitasking
  • multiprocessing
  • general-purpose

Real-Time OS:
These are operating which respond to an event( internal or external) in a specified unit of time. If the system does not respond to the event in a specified unit of time; it corresponds to the failure of the system.

There are two major classifications of real-time os:
1. Hard Real-Time OS
2. Soft Real-Time OS

Hard Real-Time OS: These are the system which absolutely must respond to an event within a specified unit of time with the appropriate action. And that action is strictly governed and monitored. Failure of the OS in response time results in total system loss. Example: Network communication operating system running in mainframes to provide backbone infrastructure of voice-based communication such as PBX, POTS, Wireless Mobile Communication etc.

Soft Real-Time OS: These are also real-time operating but they are not so strict at hard real-time operating system. A missed event will not lead to a catastrophic loss. Example: General-pupose mobile devices operating system is soft real time operating system; in the event of incoming call the operating system may not respond to the user input and give priority to the incoming call notification from the modem.

Majorly embedded system have small memory and processing footprint. So to accommodate a ready made solution is very much out of the equation. You have to either heavily customize the operating system or make your own scheduler.

There are different real-time operating system provider
1. FreeRTOS
2. uC RTOS
3. mbed RTOS
4. CMSIS-RTOS