Example: Printing in Background Task

DSP/BIOS vs. Portos

A background task that runs at low priority receives commands to print messages (format string and up to 3 double values). A high priority task sends the messages. In this example, for the DSP/BIOS we use tasks while for Portos we use priority functions. This is a simplistic example; some functions may do more stuff.

Note that we use dynamic memory allocation in order to prevent multiple copies of the message. But also note that the Portos preprocessor automatically and efficiently handles the function arguments and dynamic memory allocation. It is invisible to the programmer in this example.

See also Queue of DMA Requests.

DSP/BIOS Tasks
Portos Priority Functions

#include <stdio.h>
#include <std.h>
#include <tsk.h>
#include <mbx.h>
#include <buf.h>

// Tasks, mailbox
static TSK_Handle taskMain;
static TSK_Handle taskPrint;
static MBX_Handle mbx;

// Block-oriented dynamic memory for messages
static BUF_Handle msgPool;

// Message sent to printing task
typedef struct {

char *format;
double a;
double b;
double c;

} MessagePrint;

#include <stdio.h>
#include <portos.h>


// Main task (high priority 5)
void task_main(void)
{

// For ever loop
while ( 1 ) {

MessagePrint *msg;

// Do some stuff
...

// Send message to background printing task
msg = BUF_alloc(msgPool);
if ( !msg ) SYS_abort("Message pool full");
msg.format = "result %f %f %f\n";
msg.a = 1.2;
msg.b = 3.4;
msg.c = 5.6;
MBX_post(mbx, &msg, SYS_FOREVER);

}

}

// Main priority function (high priority 5)
void func_main(po_priority(5))
{

// Do some stuff
...

// Send message to background printing function
func_print(po_priority, "result %f %f %f\n", 1.2, 3.4, 5.6);

}

// Printing task (low priority 3)
void task_print(void)
{

// For ever loop
while ( 1 ) {

MessagePrint *msg;

// Wait for message
MBX_pend(mbx, &msg, SYS_FOREVER);
printf(msg->format, msg->a, msg->b, msg->c);
BUF_free(msgPool, msg);

}

}

// Printing priority function (low priority 3)
void func_print(po_priority(3), char *format,
..........................double a, double b, double c)
{

printf(format, a, b, c);

}

// Start of program
int main()
{

TSK_Attrs attr1 = {0};
TSK_Attrs attr2 = {0};

// Create tasks
attr1.name = "taskMain";
attr1.priority = 5;
attr1.stacksize = 512;
attr1.stack = NULL;
attr1.initstackflag = 1;
taskMain = TSK_create((Fxn)task_main, &attr1);
if ( !taskMain ) SYS_abort("Can't create Task Main");

attr2.name = "taskPrint";
attr2.priority = 3;
attr2.stacksize = 512;
attr2.stack = NULL;
attr2.initstackflag = 1;
taskMyfunc = TSK_create((Fxn)task_print, &attr2);
if ( !taskPrint ) SYS_abort("Can't create Task Print");

// Create dynamic memory pool
msgPool = BUF_create(20, sizeof(MessagePrint), 8, NULL);
if ( !msgPool ) SYS_abort("Could not create msg Pool");

// Create mailbox
mbx = MBX_create(sizeof(MessagePrint*), 20, NULL);
if ( !mbx ) SYS_abort("Can't create Mailbox");

// main() returns but hardware interrupts go on
return 0;

}

// Start of program
int main()
{

// Init Portos
po_init();

// main() returns but hardware interrupts go on
return 0;

}