A semaphore is called binary semaphore when its value is 0, it is assumed that it has been taken (or accepted) & when its value is 1, it is assumed that it has been released & no task has taken it yet.
An ISR can release the token. A task can release the token as well accept the token or wait for taking the token.
Shared data problem solutions:
One solution is atomic queue operation for solving the shared data problem.
1.Use modifier volatile with a declaration for a variable that returns from the interrupt. This declaration warns the compiler that certain variables can modify because the ISR does not consider the fact that the variable is also shared with a calling function.
2.Use reentrant functions with atomic function instructions in that part of a junction that needs its complete execution before it can be interrupted.
3.Put a shared in a critical queue. A function that requires the value of this variable always deletes it from the queue front, and another function, which inserts the value of this variable. always does so at the queue back.
4.Disable the interrupts before a critical section starts executing & enable the interrupts on its completion it is a powerful drastic option. An interrupt even is of higher priority than the present critical function gets disabled.
Shared-Data Problems
Void Task1 (void)
{
:
vconterErrors(9);
:
}
void Task2 (void)
{
:
vcontErrors(11);
:
}
static int cErrors;
void vconutErrors (int vNewErrors)
{
cErrors += cNewErrors:
}
Fig. Tasks can share code
The above fig shows a bug in the code. Here both task1 and task2 call vcontErrors. This is a perfectly valid thing to do in an RTOS. Any or all of the tasks can share as many subroutines as is convenient.
The difficulty with the program is that because both Task1 and Task2 call vcontErrors and since vcontErrors uses the variable cErrors is now shared by the 2 tasks.
If task1 calls vcontErrors, and if the RTOS then stops Task1 and runs Task2 which then calls vcontErrors, the variable cErrors may get corrupted in just the same way as it would if Task2 were an interrupt routine that had interrupted Task1.
Reentrancy:
Reentrant functions are functions that can be called by more than one task and that will always work correctly, even if the RTOS switches from one task to another in the middle of executing the function.
The 3 rules to decide if a function is reentrant are:
1. A reentrant function may not use variables in a nonatomic way unless they are stored on the stack of the task that called the function or are otherwise the private variables of that task that called the function or are otherwise the private variables of that task.
2. A reentrant function may not call any other functions that are not themselves reentrant.
3. A reentrant function may does not use the hardware in a nonatomic way.