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

It makes simple to implement asynchronous processing between threads. Task class is an implementation of mail driven thread, for it makes to use Thread and Mail classes in mbed-rtos library easier.

The example of the use of this library, please refer to the following program.

Import programmail_driven_task_example

Simple example of the use of mail_driven_task library

Task.h

Committer:
mzta
Date:
2014-12-25
Revision:
2:b12e4c1338db
Parent:
1:381a6f6263c7
Child:
3:0c93bdf73d87

File content as of revision 2:b12e4c1338db:

#ifndef TASK_H
#define TASK_H

#include <cstdio>
#include <cstdarg>
#include "mbed.h"
#include "rtos.h"

using namespace std;

/** Log level symbol definition */
typedef enum {
    LOG_DEBUG = 0,
    LOG_INFO,
    LOG_WARN,
    LOG_ERR
} LogLevel;

/** max length of mail queue block per task */
#define MAX_MAIL_NUM 16

/** max length of log string */
#define LOG_BUF_SIZE 64

typedef void (*Routine)(void const *argument);
typedef uint32_t MessageID;
typedef uint32_t TaskID;

/** struct for static task configuration */
struct TaskConfig {
    TaskConfig(
        const char *task_name,
        Routine func,
        osPriority task_priority = osPriorityNormal,
        uint32_t stack_size = DEFAULT_STACK_SIZE,
        unsigned char *stack_pointer = NULL
    ) {
        name         = task_name;
        routine      = func;
        priority     = task_priority;
        stackSize    = stack_size;
        stackPointer = stack_pointer;
    }
    const char *name;
    Routine routine;
    osPriority priority;
    uint32_t stackSize;
    unsigned char *stackPointer;
};

/** struct for mail event passing */
struct MailPacket {
    uint32_t messageId;
    void *packet;
};

typedef Mail<MailPacket, MAX_MAIL_NUM> MailBox;

/** Task class : A Thread which driven by mail event, and it have own logger. */
class Task
{
public:
    /** Initialize task config table.
     * @param cfg array of TaskConfig
     * @param num_of_task length of cfg
     * @return void
     */
    static void init(TaskConfig *config, uint32_t num_of_task);

    /** Send mail to task specified by task_id with Any data.
     * @param task_id destination task's id
     * @param message_id mail id
     * @param packet any data pointer
     * @return void
     */
    static void sendMail(TaskID task_id, MessageID message_id, void *packet);


    static int readClock();

    Thread *thread;

    /** Wait for mail addressed to itself.
     * @return received MailPacket
     */
    MailPacket *waitMail();

    /** Delete a mail queue block. it's responsible for received task.
     * @param mail received MailPacket
     * @return void
     */
    void deleteMail(MailPacket *mail);

    /** Output log to task's own stream pointer.
     * @param lv loglevel
     * @param format log format
     * @param ... log arguments
     * @return void
     */
    void log(LogLevel lv, const char *format, ...);

    /** Logger class */
    class Logger
    {
    public:
        /** Logger constructor
         * @param task_name For log prefix
         * @param sp Stream pointer for output destination(the default is USB serial).
         */
        Logger(const char *task_name, Stream *sp = Logger::sci);

        /** Log level setter
         * @param lv log level
         * @return void
         */
        static void setLogLevel(LogLevel lv);
        void setLogStream(Stream *sp);
        static const char *lvSym[];
        static Stream *sci;
        static LogLevel lv;
        Stream *sp;
        const char *tag;
        char buf[LOG_BUF_SIZE];
    };

private:
    /** Create a new thread with its own logger.
     * @param cfg TaskConfig struct pointer
     * @return void
     */
    Task(TaskConfig *config);
    ~Task();

    static Timer clock;
    static Task **taskTable;
    static TaskConfig *taskConfig;

    MailBox mbox;
    Logger  *logger;
};

#endif