Tuesday, November 11, 2014

Different Symbols Meaning UNIX.

$ character represents the process ID number, or PID, of the current shell:
$echo $$
Above command would write PID of the current shell:
29949
The following table shows a number of special variables that you can use in your shell scripts:
VariableDescription
$0The filename of the current script.
$nThese variables correspond to the arguments with which a script was invoked. Here n is a positive decimal number corresponding to the position of an argument (the first argument is $1, the second argument is $2, and so on).
$#The number of arguments supplied to a script.
$*All the arguments are double quoted. If a script receives two arguments, $* is equivalent to $1 $2.
$@All the arguments are individually double quoted. If a script receives two arguments, $@ is equivalent to $1 $2.
$?The exit status of the last command executed.
$$The process number of the current shell. For shell scripts, this is the process ID under which they are executing.
$!The process number of the last background command.

Command-Line Arguments:

The command-line arguments $1, $2, $3,...$9 are positional parameters, with $0 pointing to the actual command, program, shell script, or function and $1, $2, $3, ...$9 as the arguments to the command.
Following script uses various special variables related to command line:
#!/bin/sh

echo "File Name: $0"
echo "First Parameter : $1"
echo "First Parameter : $2"
echo "Quoted Values: $@"
echo "Quoted Values: $*"
echo "Total Number of Parameters : $#"
Here is a sample run for the above script:
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2

Special Parameters $* and $@:

There are special parameters that allow accessing all of the command-line arguments at once. $* and $@ both will act the same unless they are enclosed in double quotes, "".
Both the parameter specifies all command-line arguments but the "$*" special parameter takes the entire list as one argument with spaces between and the "$@" special parameter takes the entire list and separates it into separate arguments.
We can write the shell script shown below to process an unknown number of command-line arguments with either the $* or $@ special parameters:
#!/bin/sh

for TOKEN in $*
do
   echo $TOKEN
done
There is one sample run for the above script:
$./test.sh Zara Ali 10 Years Old
Zara
Ali
10
Years
Old
Note: Here do...done is a kind of loop which we would cover in subsequent tutorial.

Exit Status:

The $? variable represents the exit status of the previous command.
Exit status is a numerical value returned by every command upon its completion. As a rule, most commands return an exit status of 0 if they were successful, and 1 if they were unsuccessful.
Some commands return additional exit statuses for particular reasons. For example, some commands differentiate between kinds of errors and will return various exit values depending on the specific type of failure.
Following is the example of successful command:
$./test.sh Zara Ali
File Name : ./test.sh
First Parameter : Zara
Second Parameter : Ali
Quoted Values: Zara Ali
Quoted Values: Zara Ali
Total Number of Parameters : 2
$echo $?
0
$
SOURCE:tutorialpoint

Tuesday, July 8, 2014

Priority inversion and how to avoid it.


Priority inversion occurs when a mutex or critical section held by a lower-priority thread delays the running of a higher-priority thread when both are contending for the same resource.

A fundamental maxim in a real-time system is that the highest priority task that is ready to run must be given control of the processor. If this does not happen deadlines can be missed and the system can become unstable . Priority inversion simply means that the priority you established for a task in your system is turned upside down by the unintended result of how priorities are managed and how system resources are assigned. It is an artifact of the resource sharing systems that are fundamental to RTOS operation.

Mutex (and/or Semaphore) objects are used to ensure that the various tasks can have exclusive access to system resources when they need them. Consider Task C that is writing to RAM. To protect against memory corruption which could occur if another higher priority task (Task A) preempts Task C and writes to the same block, Task C uses a Mutex to lock access to the RAM until the write is completed. However, Task A interrupts Task C before the operation can be completed and yet Task A needs to access the file system to complete its work. The result is a priority inversion. Task C must finish its work so that Task A can get access, but Task A has blocked Task C because Task A has a higher priority. Embedded gridlock! This scenario can be termed “bounded inversion.”

A variation of this is termed “unbounded inversion.” Task C has locked the RAM with a Mutex and is then preempted by Task B which is attempting to perform an unrelated, but higher priority operation. Highest priority Task A then preempts Task B but relinquishes control (blocks) since it cannot access the resource because of the Mutex claimed by task C. Task B then resumes operation and maintains control of the processor for as long as it needs it. Task A (the highest priority task) is unable to run during this unbounded period.

The simple solution is to let Task C finish what it was doing, uninterrupted, and then release the Mutex on the file system so that Task A can do what it needs to do. But the operating system objects are doing exactly what they were programmed to do and, without special logic to deal with these situations, the scheduler must honor the relative priorities of Tasks A, B and C and the inherent rules of the operating system.

Solutions:
Disabling all interrupts to protect critical sections
A priority ceiling
Priority inheritance
Random boosting
Avoid blocking

Priority Inheritance Protocol – Change the priority of Task C to the same as Task A. Task A has to wait for Task C to complete, but the assumption is that at the higher priority, Task C can get more cycles that are not pre-empted and can thus complete its critical region more quickly in real-time. When Task C completes its critical region, it returns to its original priority and ownership of the shared resource’s Mutex is then assigned to the waiting Task A.

Priority Ceiling Protocol – This method is also called Instant Inheritance Protocol. If there is a set of n tasks that use a shared resource, a Mutex is assigned to the shared resource and given a priority that is at least as high as, if not higher than, the highest priority of the n tasks in the set. When any task attempts to acquire ownership of the shared resource’s Mutex, it will be granted and its priority instantly changed to the priority of the Mutex. This action prevents any possibility of preemption by another member of the set of the shared resource’s users because all other tasks in the set are, by definition, at a lower priority than that of the current owner. Thus, there can be no tasks that are waiting to get ownership of the Mutex because they cannot get scheduled. This method effectively prevents the possibility of a priority inversion. Notice that this method also effectively deals with unbounded inversion issue because no other task (such as Task B) that has a priority between that of the lowest priority task in the set and the highest priority members of the set can get scheduled. When the owner task completes its critical region, the Mutex is released and the task returned to its original priority.
The Priority Ceiling Protocol used by other RTOSes avoids the potential problem of dealing with unbounded inversions but, since all tasks that use the same resource are permanently given the same high priority, even if they are not essential tasks, this may starve other, more important tasks.

The RTXC Quadros RTOS uses Priority Inheritance Protocol. It addresses bounded inversions and avoids the potential problem of Priority Ceiling Protocol that can starve tasks which are not part of the set.


priority inversion problem experienced by Mars Pathfinder.
Priority Inheritance Protocols: An Approach to Real-Time Synchronization.


References:
http://info.quadros.com/
http://www.embedded.com/
wikipedia

Monday, June 30, 2014

Boot up and Shutdown process Linux:


You can use the following two files regarding boot logs:

/var/log/boot.log
/var/log/dmesg

On a Ubuntu/Debian, Bootlog is turned off by default. Turn it on like this:

vi /etc/default/bootlogd

# Run bootlogd at startup ?
BOOTLOGD_ENABLE=Yes

Following stages for boot up for an x86 system:



1.System BIOS(Basic Input Output System) checks the system and launches the first stage boot loader on the MBR(Master Boot Record) of the primary hard disk.

2.First stage boot loader loads itself into memory and launches the second stage boot loader from the /boot/ partition.

3.Second stage boot loader loads the kernel into memory, which in turn loads any necessary modules and mounts the root partition read-only.

4.The boot loader often presents the user with a menu of possible boot options. The boot loader can be configured to time out if the user does not interact with the boot loader, thus selecting a default kernel and system configuration. After the selection is made, or after reaching a selection time-out, boot loader loads the kernel, which decompresses itself and sets up system functions such as essential hardware and memory paging, before calling start_kernel().

5.start_kernel() then performs the majority of system setup (interrupts, the rest of memory management, device and driver initialization, etc.) before spawning separately, the idle process and scheduler, and the /sbin/init process (which is executed in user space).
6.The /sbin/init program loads all services and user-space tools, and mounts all partitions listed in /etc/fstab.
7.The user is presented with a login screen for the freshly booted Linux system.

Beginning of boot process is different for different hardware platform .However, once the kernel is found and loaded by the boot loader, the default boot process is identical across all architectures.Here we are focusing on x86 architecture.

Wednesday, June 25, 2014

Boot loader

A boot loader is a computer program that loads an operating system or some other software for the computer after completion of the self-tests. Within the hard reboot process, it runs after completion of the self-tests, then loads and runs the software. A boot loader is loaded into main memory from persistent memory, such as a hard disk drive or, in some older computers, from a medium such as punched cards, punched tape, or magnetic tape. The boot loader then loads and executes the processes that finalize the boot. Like POST processes, the boot loader code comes from a "hard-wired" and persistent location; if that location is too limited for some reason, that primary boot loader calls a second-stage boot loader or a secondary program loader.

On modern general purpose computers, the boot up process can take tens of seconds, and typically involves performing a power-on self-test, locating and initializing peripheral devices, and then finding, loading and starting an operating system. The process of hibernating or sleeping does not involve booting. Minimally, some embedded systems do not require a noticeable boot sequence to begin functioning and when turned on may simply run operational programs that are stored in ROM. All computing systems are state machines, and a reboot may be the only method to return to a designated zero-state from an unintended, locked state.

Boot is short for bootstrap or bootstrap load and derives from the phrase to pull oneself up by one's bootstraps. The usage calls attention to the requirement that, if most software is loaded onto a computer by other software already running on the computer, some mechanism must exist to load the initial software onto the computer. Early computers used a variety of ad-hoc methods to get a small program into memory to solve this problem. The invention of read-only memory (ROM) of various types solved this paradox by allowing computers to be shipped with a start up program that could not be erased. Growth in the capacity of ROM has allowed ever more elaborate start up procedures to be implemented.