It is not exciting to read a lot of general stuff about software API's, so let's code our first real-life application right now.
Jump start example - Heart Beat Blinky LED
This example aims to show how straightfoward it is to code a "heart beat" LED task with YasK. An complex blink pattern is not so easy to program from scratch. See how clean and linear this code looks. This code is so strange: it contains neither while(), nor for() loops, and just one if-then-else statement.
This piece of code implements the most important concepts of YasK, so look at it carefully, please.
The hear_beat task drives the LED as follows :
while(true) {
ON: 30 ms
OFF: 150 ms
ON: 30 ms
OFF: 700 ms
}
The code of the heart_beat task:
short heart_beat( YASK_MSG_T *msg)
{
static char mbx = YASK_NONE; // mailbox handle
if( msg)
{
switch( msg->idn)
{
case 1: // LED On 1
IOSset_bit( LED_PORT, LED_BIT);
// Start the first timer (30 ms) and execute case 2 when done
YASKpost( mbx, // mailbox
2, // message identifier
0, // optional indentifier
30, // time out
YASK_PRI_TSK); // message priority
break;
case 2: // LED Off 1
IOSreset_bit( LED_PORT, LED_BIT);
// Start the second timer (150 ms) and execute case 3 when done
YASKpost( mbx, 3, 0, 150, YASK_PRI_TSK);
break;
case 3: // LED On 2
IOSset_bit( LED_PORT, LED_BIT);
// Start the third timer (30 ms) and execute case 4 when done
YASKpost( mbx, 4, 0, 30, YASK_PRI_TSK);
break;
case 4: // LED Off 2
IOSreset_bit( LED_PORT, LED_BIT);
// Start the fourth timer (700 ms) and execute case 1 when done
YASKpost( mbx, 1, 0, 700, YASK_PRI_TSK);
break;
default: // Warn if an unknown message is received
printf("heart_beat: Unknowkn message %d\r\n", msg->idn);
break;
} // End of switch on received message identifier
}
else // come here if I am called with a NULL message
{
// get a mailbox handle on myself (this task) and give it a friendly name
mbx = YASKregister( heart_beat, // Recipient task
"HeartBeat"); // Friendly mailbox name
// Start blinking immediately: execute case 1 as soon as possible
// YASKpost( mailbox, identifier, option, delay, priority)
YASKpost( mbx, 1, 0, 0, YASK_PRI_TSK);
} // End of if/else on message
return 0;
} // End of heart_beat()
Explanations:
short heart_beat( YASK_MSG_T *msg)
The heart_beat task is a regular C function with only one input parameter: YASK_MSG_T *msg. This input contains the message sent to the task. The task returns a short integer upon completion.
static char mbx = YASK_NONE; // mailbox handle
The variable mbx contains a mailbox handle. This handle is simply an index of an internal array of YasK. This handle is provided by YasK when I register the mailbox. The variable must be static in order to keep this handle between two activations of the task.
if( msg)
{
This test checks if the received message is not NULL. YasK never sends NULL messages to a task, so when a task receives a NULL message, that generally means that the task needs to be started. This occurs once during program start up.
switch( msg->idn)
{
Once I have checked that the received message contains information, I start a switch/case statement based on the identifier contained in the message. The identifier is an unsigned char.
case 1: // LED On
IOSset_bit( LED_PORT, LED_BIT);
In case 1, I first set the output port wired to my LED in order to light it. IOSset_bit is a macro that does this job. This macro does not belong to YasK. In your implementation, you will put here your own code.
YASKpost( mbx, // mailbox
2, // message identifier
0, // optional indentifier
30, // time out (ms)
YASK_PRI_TSK); // message priority
break;
Once the led is lighted, I need to wait 30 ms before I turn it off. The YASKpost call does this job. The YASKpost call is the most important routine of YasK's API. It simply puts a message in a recipient's mailbox and returns. YasK will then struggle to deliver the message to the recipient task in time....
Read more »