Square Wave Generation using Delay in 8051

To create a square wave generation using Delay.

let us say we want to construct a 1khz square waveform

the processor instruction cycle of 8051 is 1.085microseconds

so for 1khz (1milli seconds =1/1khz), is 1ms/1.085microseconds = 921.6 (this value is set to the for loop)

#include <reg51.h>

void delay()




void main()







Main Algorithms of a Linux Kernel


  • Signals are one of the oldest facilities of Inter Process Communication.
  • Signals are used to inform the processes about the events.
  • signals will be sent via the following function (by the Kernel)

int send_sig_info(int sig, struct siginfo *info, struct task_struct *);

sig – refers the signal number

info – refers the sender

t – refers to the tasks (the kernel may send signals to many processes)

Booting the System

There are many bootloaders available for linux, the common ones being the LILO and the GRUB loader

LILO – LInux LOader

GRUB – GRand unified Bootloader

The steps while booting the kernel (only relevant steps are given)

  • Entry point at start which is available at arch/x86/boot/setup.S (This is responsible for initializing the hardware (assembler code)
  • Once the hardware is initialized, the process is switched to protected mode by setting a bit word in the machine status word.
  • Next the assembler instruction,       jmpi 0×100000 _KERNEL_CS, jumps to the start address of the 32 bit code of the actual operating system kernel and continues from startup_32 and in the file arch/x86/kernel/head.S . More sections of the hardwares are initialized here like Memory Management unit (Page tables), the Co processor, and the environment (stack, environment,etc)
  • The first C function start_kernel() from init/main.c is called
  • the following list the assembly linkage of the start_kernel function

asmlinkage void __init start_kernel(void)


char * command_line;

printk(linux_banner); //print kernel, the banner

setup_arch(&command_line);//architecture dependent codes relevant to x86


init_IRQ(); //hardware interrupt initialization

sched_init(); //initialize the schedules


softirq_init(); //soft interrupts

console_init();//initialize the console

init_modules();//initialize the modules (device drivers)


  • the init is called (will be searched in /sbin/init or /etc/init or /bin/init). if the init is not available, then a shell (/bin/bash) will be opened for debugging

Hardware  interrupts (IRQ)

Interrupts are used to allow the hardware to communicate with the operating system, there are two problems while writing interrupt routine,

  • firstly, The interrupt routines should serve the hardware as quickly as possible
  • secondly, large amount is to be handled by the interrupt routine

This can be solved by the following mechanisms

  • disabling all the software interrupts while servicing the hardware interrupts.
  • the processing of data is carried out asynchronously by the software interrupts through “tasklets ” or “bottom halves”

Software Interrupts

  • It is like a hardware interrupt but can be started only at certain times
  • The number of interrupts is limited
  • enum {HI_SOFTIRQ, NET_TX_SOFTIRQ, NET_RX_SOFTIRQ,TASKLET_SOFTIRQ}; the date types tells the software interrupts for hi priority software interrupts, Network Tranmssion and Receiving Interrupt and tasklet interrupt). upon interrupt is generated, the Interrupt routine will be executed

Kernel Data Structures

Task Structure

The fundamental entity of any operating system is the task or a process. The task structure is defined in the linux/sched.h and it is the important data structure and following are some of its parameters.
struct task_struct {
volatile long state; //determines the current state of the process like unrunnable, runnable and stopped
unsigned long flags; // various flags for accounting purpose like PF_STARTIN, PF_MEMALLOC

unsigned long ptrace; // process is being monitored by other process.

int sigpending; //define when the signals must be handed over to this process

mm_segment_t addr_limit;

struct exec_domain *exec_domain; //domain other than x86

long need_resched; //flag indicates that scheduling must be executed

int lock_depth; //structure is protected before simulataneous access can take place

long counter; //dynamic priority of a process

long nice; //static priority of a process

unsigned long policy; //scheduling policy like SCHED_RR, SCHED_FIFO, SCHED_OTHER

unsigned long rt_priority;

Process Relations

This data structure describes the relation between processes lilke child process, parent process, etc.
struct task_struct *p_opptr; //original parent process
struct task_struct *p_pptr; //Parent Process
struct task_struct *p_cptr; //child process
struct task_struct *p_ysptr; //youngest sibling process
struct task_struct *p_osptr; //old sibling process
the following diagram depicts the relationship between the process.

Process ID

Every process has its own process ID called pid defined as follows:
pid_t pid, pgrp, session, tgid; //pgrp – process group, session in which the process runs and tgid is thread group id

int leader; //there will be a leader process among the process

apart from the above, there are two other parameters like uid and gid referred namely as user identification and group identification, which enables to create the access right.


Times are measured in ticks. usually the timing signals are generated by the hardware timer every10ms which is captured by the timer interrupt.
there are different timing parameters are specified like
long per_cpu_utime[NO OF CPUS]; //user mode
long per_cpu_stime[NO OF CPUS]; //system mode
struct tms times; //the timing values are added for all the child processes and other processes
unsigned long start_time; //time at which the process was generated.


Files and inodes represent the file structures.
Files defines the attributes of file like mode of operation, position of the cursor, flags, reference count, directory entry, etc
inodes defines the information about the files like owner of the file, device in which the file is located, access rights of the file, size of the file, last access time, last modification time, etc
struct file {
mode_t f_mode; // mode of operation like read, write, append, etc
loff_t f_pos; //position of the read/write cursor
atomic_t f_count; //reference count like how many times the file has been opened by the system call
unsigned int f_flags; //access control
struct dentry *fs_dentry;// file descriptor
struct inode {
kdev_t i_dev:// device id in which the file is located
unsigned long i_ino;//file within device
umode_t i_mode; //mode of operation
uid_t i_uid; //user id which is the owner of the file
gid_t i_gid; //group id, the file can be accessed by a group
off_t i_size; //size of the file in bytes
time_t i_mtime; //last modification time
time_t i_atime; //last accessed time

Introduction to Linux Kernel

  • The Linux or the unix kernel is just developed under the microkernel architecture…
  • The Microkernel provides only the necessary minimum of functionality (inter process communication and the memory management) and can be accordingly be implemented in a small and compact form. Building on this microkernel, the remaining functions of the operating system are relocated to the autonomous processes communicating with the microkernel via a well defied interface.
  • Generally, microkernel systems have been created whose performance can be improved by the monolithic systems.  Since linux provides slow i386 architecture, so linux is developed using the monolithic design..
  • the code size of linux mainly occupied by the device drivers and similars. on the other hand, the central routines of process and memory management are relatively small and easily understood, with 13000 lines of C code in each
  • Thus LINUX is successfully tries to make use of the advantages of a microkernel architecture without giving up its original monolithic design.

States of a Process
Running – The task is active and running inthe non privileged user mode. This state can be interrupted only when there is a system call or the interrupt.
Interrupt Routine – The interrupt routine becomes active when the hardware signals an exception condition which may be new characters from the keyboard or any other hardware interrupt.
System calls – system calls are initiated by software interrupts
Waiting – the process is waiting for an external event. Eg. waiting for a button press…
Ready – the process is ready to run under the CPU, but some other process is currently running under the cpu.
Return from system call – This state is adopted after the end of the system call or end of the interrupts.

Kernel Directory Structure

In Linux the Kernel source is available under /usr/src/linux.

  • Architecture dependent code is available in the following directory structure

    • arch/alpha – for the DEC Alpha Architecture
    • arch/x86 – for the Intel 32 bit Architecture
    • arch/arm – for the ARM Architecture
    • arch/ia64 – for the intel 64 bit architecture
    • arch/m68k – for the 68000 architecture and compatible processors. 
  • init/ directory contains all the functions needed to start the kernel.  
  • kernel/ – central sections of the kernel. Most important system calls are implemented here. 
  • arch/x86/mm or mm/ – takes care of memory management by requesting and releasing kernel memories.  
  • fs/ is the virtual file system interface. Some important file systems are proc, ext2,ext3,. The proc file systems is used for system management. 
  • drivers/ – every operating system requires drivers for its hardware components. These are held in this directory and classified into groups according to their subdirectories like the following

    • drivers/char – character oriented devices
    • drivers/block – block oriented devices
    • drivers/i2c – a generic i2c driver
    • drivers/scsi – the SCSI interface
    • drivers/usb – drivers for the USB subsystem 
  • ipc/ – indicates the Inter process communication  
  • lib/ – indicates the standard C library functions

Characteristics of Linux

Linux is

  1. Multiuser – allows number of users to work with the system at the same time
  2. Multitasking – supports true preemptive multitasking. All processes independently of each other.
  3. Multiprocessing – from kernel Version2.0 onwards, linux supports multiprocessor architectures. Applications are distributed across several processors.
  4. Architecture Independent – runs almost on all platform that are able to process bits and bytes. examples like IBM s390, Sparc, ARM, etc
  5. Demand Load Executables – only those parts of a program actually required for execution are loaded into memory.
  6. Support POSIX1003.1 standard – Linux since version. onwards supports POSIX 1003.1, which defines a minimum interface to a Unix like operating system
  7. Memory protected Mode – uses the processor’s memory protection mechanisms to provent the process from accessing memory allocated to the system kernel or other processes. This is for the security of the system
  8. Shared Libraries – it is a collection of routines needed by a program to work. There are number of standard libraries used by more then one process at the same time. so these libraries are made to load into memory for once and all the programs can make use of it.
  9. Support Various Filesystem – supports various file systems like Proc, Ext2, Ext3 and Ext4. The most commonly used file system is Ext3 and Ext4 also developed, both are journaling file systems.