Task class is an implementation of mail driven thread, for it makes to use Thread and Mail classes in mbed-rtos library easier.

Dependents:   mail_driven_task_example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Task.cpp Source File

Task.cpp

00001 #include "Task.h"
00002 
00003 Timer Task::clock;
00004 Task **Task::taskTable;
00005 TaskConfig *Task::taskConfig;
00006 
00007 Stream *Task::Logger::sci = new Serial(USBTX, USBRX);
00008 LogLevel Task::Logger::lv = LOG_WARN;
00009 const char *Task::Logger::lvSym[] = {"D", "I", "W", "E"};
00010 
00011 Task::Task(TaskConfig *cfg)
00012 {
00013     thread = new Thread(
00014         cfg->routine, this, cfg->priority, cfg->stackSize, cfg->stackPointer);
00015     logger = new Logger(cfg->name);
00016 }
00017 
00018 void Task::init(TaskConfig *cfg, uint32_t num_of_task)
00019 {
00020     /** set the lowest priority to main thread. */
00021     osThreadSetPriority(osThreadGetId(), osPriorityIdle);
00022 
00023     taskConfig = cfg;
00024     taskTable  = new Task*[num_of_task];
00025 
00026     for (int id = 0; id < num_of_task; id++) {
00027         taskTable[id] = new Task(&taskConfig[id]);
00028     }
00029 
00030     /** start logger tick */
00031     clock.start();
00032 }
00033 
00034 void Task::sendMail(TaskID task_id, MessageID message_id, void *packet)
00035 {
00036     MailPacket *mail = taskTable[task_id]->mbox.alloc();
00037     mail->messageId  = message_id;
00038     mail->packet     = packet;
00039     taskTable[task_id]->mbox.put(mail);
00040 }
00041 
00042 void Task::deleteMail(MailPacket *mail)
00043 {
00044     mbox.free(mail);
00045 }
00046 
00047 MailPacket *Task::waitMail()
00048 {
00049     osEvent event;
00050     while(true) {
00051         event = mbox.get();
00052         if (event.status == osEventMail) {
00053             break;
00054         } else {
00055             log(LOG_INFO, "event(%d)recieved", event.status);
00056         }
00057     }
00058     return (MailPacket*)event.value.p;
00059 }
00060 
00061 void Task::log(LogLevel lv, const char *format, ...)
00062 {
00063     if (Logger::lv > lv) return;
00064 
00065     float t = (float)clock.read_ms() / 1000;
00066     logger->sp->printf("%.3f:[%s][%s] ",
00067                        t, Logger::lvSym[lv], logger->tag);
00068 
00069     va_list arg;
00070     va_start(arg, format);
00071     vsprintf(logger->buf, format, arg);
00072     va_end(arg);
00073 
00074     logger->sp->printf(logger->buf);
00075     logger->sp->printf("\n");
00076 }
00077 
00078 Task::Logger::Logger(const char *task_name, Stream *sp)
00079 {
00080     this->tag = task_name;
00081     this->sp  = sp;
00082 }
00083 
00084 void Task::Logger::setLogLevel(LogLevel lv)
00085 {
00086     Logger::lv = lv;
00087 }