Ver código fonte

[C++] Add C++ interface for RT-Thread kernel.

bernard 8 anos atrás
pai
commit
eb2c098197

+ 42 - 0
components/cplusplus/Lock.h

@@ -0,0 +1,42 @@
+/*
+ * File      : Lock.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+
+namespace rtthread {
+
+class Lock
+{
+public:
+    Lock(Mutex& mutex) : m(mutex) {m.lock();}
+    ~Lock() {m.unlock();}
+
+protected:
+    Mutex &m;
+};
+
+}

+ 95 - 0
components/cplusplus/Mail.h

@@ -0,0 +1,95 @@
+/*
+ * File      : Mail.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+
+#include <rtthread.h>
+
+namespace rtthread {
+
+/**
+ * The Mail class allow to control, send, receive, or wait for mail.
+ * A mail is a memory block that is send to a thread or interrupt service routine.
+ * @param  T         data type of a single message element.
+ * @param  queue_sz  maximum number of messages in queue.
+ */
+
+template<typename T, uint32_t queue_sz>
+class Mail {
+public:
+    /** Create and Initialise Mail queue. */
+    Mail(const char* name = "")
+    {
+        rt_mb_init(&mID, name, mPool, queue_sz, RT_IPC_FLAG_FIFO);
+    }
+
+    ~Mail()
+    {
+        rt_mb_detach(&mID);
+    }
+
+    /** Put a mail in the queue.
+      @param   mptr  memory block previously allocated with Mail::alloc or Mail::calloc.
+      @return  status code that indicates the execution status of the function.
+    */
+    bool put(T *mptr, int32_t millisec = 0)
+    {
+        rt_int32_t tick;
+
+        if (millisec < 0)
+            tick = -1;
+        else
+            tick = rt_tick_from_millisecond(millisec);
+
+        return rt_mb_send_wait(&mID, (rt_uint32_t)mptr, tick) == RT_EOK;
+    }
+
+    /** Get a mail from a queue.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  event that contains mail information or error code.
+    */
+    T* get(int32_t millisec = -1)
+    {
+        T *t = NULL;
+        rt_int32_t tick;
+
+        if (millisec < 0)
+            tick = -1;
+        else
+            tick = rt_tick_from_millisecond(millisec);
+
+        rt_mb_recv(&mID, &t, tick);
+
+        return t;
+    }
+
+private:
+    struct rt_mailbox mID;
+    T* mPool[queue_sz];
+};
+
+}

+ 35 - 0
components/cplusplus/Mutex.cpp

@@ -0,0 +1,35 @@
+#include "Mutex.h"
+
+using namespace rtthread;
+
+Mutex::Mutex(const char *name)
+{
+    rt_mutex_init(&mID, name, RT_IPC_FLAG_FIFO);
+}
+
+bool Mutex::lock(int32_t millisec)
+{
+    rt_int32_t tick;
+
+    if (millisec < 0)
+        tick = -1;
+    else
+        tick = rt_tick_from_millisecond(millisec);
+
+    return rt_mutex_take(&mID, tick) == RT_EOK;
+}
+
+bool Mutex::trylock()
+{
+    return lock(0);
+}
+
+void Mutex::unlock()
+{
+    rt_mutex_release(&mID);
+}
+
+Mutex::~Mutex()
+{
+    rt_mutex_detach(&mID);
+}

+ 60 - 0
components/cplusplus/Mutex.h

@@ -0,0 +1,60 @@
+/*
+ * File      : Mutex.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <rtthread.h>
+
+namespace rtthread {
+
+/** The Mutex class is used to synchronise the execution of threads.
+ This is for example used to protect access to a shared resource.
+*/
+class Mutex {
+public:
+    /** Create and Initialize a Mutex object */
+    Mutex(const char* name = "mutex");
+    ~Mutex();
+
+    /** Wait until a Mutex becomes available.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: WaitForever)
+      @return  true if the mutex was acquired, false otherwise.
+     */
+    bool lock(int32_t millisec = -1);
+
+    /** Try to lock the mutex, and return immediately
+      @return  true if the mutex was acquired, false otherwise.
+     */
+    bool trylock();
+
+    /** Unlock the mutex that has previously been locked by the same thread
+     */
+    void unlock();
+
+private:
+    struct rt_mutex mID;
+};
+
+}

+ 88 - 0
components/cplusplus/Queue.h

@@ -0,0 +1,88 @@
+/*
+ * File      : Queue.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+
+#include <rtthread.h>
+
+namespace rtthread {
+
+/**
+ * The Queue class allow to control, send, receive, or wait for messages.
+ * A message can be a integer or pointer value  to a certain type T that is send
+ * to a thread or interrupt service routine.
+ * @param  T         data type of a single message element.
+ * @param  queue_sz  maximum number of messages in queue.
+ */
+template<typename T, uint32_t queue_sz>
+class Queue
+{
+public:
+    /** Create and initialise a message Queue. */
+    Queue()
+    {
+        rt_mq_init(&mID, "mq", mPool, sizeof(T), sizeof(mPool), RT_IPC_FLAG_FIFO);
+    };
+
+    ~Queue()
+    {
+        rt_mq_detach(&mID);
+    };
+
+    /** Put a message in a Queue.
+      @param   data      message pointer.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: 0)
+      @return  status code that indicates the execution status of the function.
+    */
+    rt_err_t put(T& data, int32_t millisec = 0)
+    {
+        return rt_mq_send(&mID, &data, sizeof(data));
+    }
+
+    /** Get a message or Wait for a message from a Queue.
+      @param   millisec  timeout value or 0 in case of no time-out. (default: osWaitForever).
+      @return  bool .
+    */
+    bool get(T& data, int32_t millisec = WAIT_FOREVER)
+    {
+        rt_int32_t tick;
+
+        if (millisec < 0)
+            tick = -1;
+        else
+            tick = rt_tick_from_millisecond(millisec);
+
+        return rt_mq_recv(&mID, &data, sizeof(data), tick) == RT_EOK;
+    }
+
+private:
+    struct rt_messagequeue mID;
+
+    char mPool[(sizeof(struct rt_messagequeue)+sizeof(T)) * queue_sz];
+};
+
+}

+ 1 - 0
components/cplusplus/SConscript

@@ -4,6 +4,7 @@ from building import *
 
 cwd = GetCurrentDir()
 src = Glob('*.cpp') + Glob('*.c')
+
 CPPPATH = [cwd]
 
 group = DefineGroup('CPlusPlus', src, depend = ['RT_USING_CPLUSPLUS'], CPPPATH = CPPPATH)

+ 30 - 0
components/cplusplus/Semaphore.cpp

@@ -0,0 +1,30 @@
+#include "Semaphore.h"
+
+using namespace rtthread;
+
+Semaphore::Semaphore(const char *name, int32_t count)
+{
+    rt_sem_init(&mID, name, count, RT_IPC_FLAG_FIFO);
+}
+
+bool Semaphore::wait(int32_t millisec)
+{
+    rt_int32_t tick;
+
+    if (millisec < 0)
+        tick = -1;
+    else
+        tick = rt_tick_from_millisecond(millisec);
+
+    return rt_sem_take(&mID, tick) == RT_EOK;
+}
+
+void Semaphore::release(void)
+{
+    rt_sem_release(&mID);
+}
+
+Semaphore::~Semaphore()
+{
+    rt_sem_detach(&mID);
+}

+ 56 - 0
components/cplusplus/Semaphore.h

@@ -0,0 +1,56 @@
+/*
+ * File      : Semaphore.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <rtthread.h>
+
+namespace rtthread {
+
+/** The Semaphore class is used to manage and protect access to a set of shared resources. */
+class Semaphore
+{
+public:
+    /** Create and Initialize a Semaphore object used for managing resources.
+      @param number of available resources; maximum index value is (count-1).
+    */
+    Semaphore(const char *name = "sem", int32_t count = 0);
+    ~Semaphore();
+
+    /** Wait until a Semaphore resource becomes available.
+      @param   millisec  timeout value or 0 in case of no time-out.
+      @return  true on success.
+    */
+    bool wait(int32_t millisec = -1);
+
+    /** Release a Semaphore resource that was obtain with Semaphore::wait.
+    */
+    void release(void);
+
+private:
+    struct rt_semaphore mID;
+};
+
+}

+ 103 - 0
components/cplusplus/Thread.cpp

@@ -0,0 +1,103 @@
+#include "Thread.h"
+
+using namespace rtthread;
+
+Thread::Thread(rt_uint32_t stack_size,
+               rt_uint8_t  priority,
+               rt_uint32_t tick,
+               const char *name)
+: _entry(RT_NULL), started(false)
+{
+    rt_event_init(&_event, name, 0);
+
+    _thread = rt_thread_create(name,
+                               (thread_func_t)func,
+                               this,
+                               stack_size,
+                               priority,
+                               tick);
+}
+
+Thread::Thread(void (*entry)(void *p),
+               void *p,
+               rt_uint32_t stack_size,
+               rt_uint8_t  priority,
+               rt_uint32_t tick,
+               const char *name)
+: _entry(RT_NULL), started(false), _param(p)
+{
+    rt_event_init(&_event, name, 0);
+
+    _thread = rt_thread_create(name,
+                               (thread_func_t)func,
+                               this,
+                               stack_size,
+                               priority,
+                               tick);
+}
+
+Thread::~Thread()
+{
+    rt_thread_delete(_thread);
+}
+
+bool Thread::start()
+{
+    if (rt_thread_startup(_thread) == RT_EOK)
+    {
+        started = true;
+    }
+
+    return started;
+}
+
+void Thread::sleep(int32_t millisec)
+{
+    rt_int32_t tick;
+
+    if (millisec < 0)
+        tick = 1;
+    else
+        tick = rt_tick_from_millisecond(millisec);
+
+    rt_thread_delay(tick);
+}
+
+void Thread::func(Thread *pThis)
+{
+    if (pThis->_entry != RT_NULL)
+    {
+        pThis->_entry(pThis->_param);
+    }
+    else
+    {
+        pThis->run();
+    }
+
+    rt_event_send(&pThis->_event, 1);
+}
+
+void Thread::run()
+{
+    /* please overload this method */
+}
+
+void Thread::wait(int32_t millisec)
+{
+    join(millisec);
+}
+
+void Thread::join(int32_t millisec)
+{
+    if (started)
+    {
+        rt_int32_t tick;
+
+        if (millisec < 0)
+            tick = -1;
+        else
+            tick = rt_tick_from_millisecond(millisec);
+
+        rt_event_recv(&_event, 1, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, tick, RT_NULL);
+    }
+}

+ 82 - 0
components/cplusplus/Thread.h

@@ -0,0 +1,82 @@
+/*
+ * File      : Thread.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2016, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2016/10/1      Bernard      The first version
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <rtthread.h>
+
+namespace rtthread
+{
+
+/** The Thread class allow defining, creating, and controlling thread functions in the system. */
+class Thread
+{
+public:
+    typedef void (*thread_func_t) (void *param);
+
+    /** Allocate a new thread without starting execution
+      @param   priority       initial priority of the thread function. (default: osPriorityNormal).
+      @param   stack_size      stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
+      @param   stack_pointer  pointer to the stack area to be used by this thread (default: NULL).
+    */
+    Thread(rt_uint32_t stack_size = 2048,
+           rt_uint8_t  priority = (RT_THREAD_PRIORITY_MAX * 2)/3,
+           rt_uint32_t tick = 20,
+           const char *name = "th");
+
+    Thread(void (*entry)(void *p),
+           void *p = RT_NULL,
+           rt_uint32_t stack_size = 2048,
+           rt_uint8_t  priority = (RT_THREAD_PRIORITY_MAX * 2)/3,
+           rt_uint32_t tick = 20,
+           const char *name = "th");
+
+    virtual ~Thread();
+
+    bool start();
+
+    static void sleep(int32_t millisec);
+
+    void wait(int32_t millisec);
+    void join(int32_t millisec = -1);
+
+protected:
+    virtual void run();
+
+private:
+    static void func(Thread *pThis);
+
+private:
+    rt_thread_t _thread;
+
+    thread_func_t _entry;
+    void *_param;
+
+    /* event for thread join */
+    struct rt_event _event;
+    bool started;
+};
+
+}