diff options
| author | nxf58843 <[email protected]> | 2021-08-23 09:55:04 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-08-23 09:55:04 -0700 |
| commit | fb16e80e575a44828f5367f4fb7380162b0354f0 (patch) | |
| tree | bb965cc935083d99e083667d4f0f1533d50a29f5 /src/osal | |
| parent | 616562a48aa1d8ce2f4ca71f6e780a8bec9fb5eb (diff) | |
| parent | ea902493db49843dcdeca6bfa2b2efe540f44b2f (diff) | |
Merge pull request #2 from hathach/master
Pulling latest from source
Diffstat (limited to 'src/osal')
| -rw-r--r-- | src/osal/osal.h | 24 | ||||
| -rw-r--r-- | src/osal/osal_freertos.h | 47 | ||||
| -rw-r--r-- | src/osal/osal_mynewt.h | 10 | ||||
| -rw-r--r-- | src/osal/osal_none.h | 36 | ||||
| -rw-r--r-- | src/osal/osal_pico.h | 187 | ||||
| -rw-r--r-- | src/osal/osal_rtthread.h | 130 |
6 files changed, 397 insertions, 37 deletions
diff --git a/src/osal/osal.h b/src/osal/osal.h index 8b7527a7e..28bdf479c 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -36,12 +36,12 @@ #include "common/tusb_common.h" -enum -{ - OSAL_TIMEOUT_NOTIMEOUT = 0, // return immediately - OSAL_TIMEOUT_NORMAL = 10, // default timeout - OSAL_TIMEOUT_WAIT_FOREVER = 0xFFFFFFFFUL -}; +// Return immediately +#define OSAL_TIMEOUT_NOTIMEOUT (0) +// Default timeout +#define OSAL_TIMEOUT_NORMAL (10) +// Wait forever +#define OSAL_TIMEOUT_WAIT_FOREVER (UINT32_MAX) #define OSAL_TIMEOUT_CONTROL_XFER OSAL_TIMEOUT_WAIT_FOREVER @@ -53,6 +53,12 @@ typedef void (*osal_task_func_t)( void * ); #include "osal_freertos.h" #elif CFG_TUSB_OS == OPT_OS_MYNEWT #include "osal_mynewt.h" +#elif CFG_TUSB_OS == OPT_OS_PICO + #include "osal_pico.h" +#elif CFG_TUSB_OS == OPT_OS_RTTHREAD + #include "osal_rtthread.h" +#elif CFG_TUSB_OS == OPT_OS_CUSTOM + #include "tusb_os_custom.h" // implemented by application #else #error OS is not supported yet #endif @@ -60,7 +66,6 @@ typedef void (*osal_task_func_t)( void * ); //--------------------------------------------------------------------+ // OSAL Porting API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec); //------------- Semaphore -------------// static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef); @@ -76,8 +81,9 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl); //------------- Queue -------------// static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef); -static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data); -static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr); +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data); +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr); +static inline bool osal_queue_empty(osal_queue_t qhdl); #if 0 // TODO remove subtask related macros later // Sub Task diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 240206e33..66070c273 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -58,7 +58,23 @@ static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semde static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { - return in_isr ? xSemaphoreGiveFromISR(sem_hdl, NULL) : xSemaphoreGive(sem_hdl); + if ( !in_isr ) + { + return xSemaphoreGive(sem_hdl) != 0; + } + else + { + BaseType_t xHigherPriorityTaskWoken; + BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); +#else + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#endif + + return res != 0; + } } static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) @@ -118,14 +134,35 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); } -static inline bool osal_queue_receive(osal_queue_t const queue_hdl, void* data) +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) { - return xQueueReceive(queue_hdl, data, portMAX_DELAY); + return xQueueReceive(qhdl, data, portMAX_DELAY); +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + if ( !in_isr ) + { + return xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER) != 0; + } + else + { + BaseType_t xHigherPriorityTaskWoken; + BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); + +#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 + if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); +#else + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#endif + + return res != 0; + } } -static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data, bool in_isr) +static inline bool osal_queue_empty(osal_queue_t qhdl) { - return in_isr ? xQueueSendToBackFromISR(queue_hdl, data, NULL) : xQueueSendToBack(queue_hdl, data, OSAL_TIMEOUT_WAIT_FOREVER); + return uxQueueMessagesWaiting(qhdl) == 0; } #ifdef __cplusplus diff --git a/src/osal/osal_mynewt.h b/src/osal/osal_mynewt.h index e47e140c1..6882329c1 100644 --- a/src/osal/osal_mynewt.h +++ b/src/osal/osal_mynewt.h @@ -125,7 +125,7 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return (osal_queue_t) qdef; } -static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data) +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) { struct os_event* ev; ev = os_eventq_get(&qhdl->evq); @@ -137,7 +137,7 @@ static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data) return true; } -static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr) +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { (void) in_isr; @@ -161,6 +161,12 @@ static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, b return true; } +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + return STAILQ_EMPTY(&qhdl->evq.evq_list); +} + + #ifdef __cplusplus } #endif diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index b27e628a9..a1f997cf2 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -34,14 +34,7 @@ //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -static inline void osal_task_delay(uint32_t msec) -{ - (void) msec; - // TODO only used by Host stack, will implement using SOF -// uint32_t start = tusb_hal_millis(); -// while ( ( tusb_hal_millis() - start ) < msec ) {} -} //--------------------------------------------------------------------+ // Binary Semaphore API @@ -130,19 +123,14 @@ typedef struct typedef osal_queue_def_t* osal_queue_t; // role device/host is used by OS NONE for mutex (disable usb isr) only -#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ - uint8_t _name##_buf[_depth*sizeof(_type)]; \ - osal_queue_def_t _name = { \ - .role = _role, \ - .ff = { \ - .buffer = _name##_buf, \ - .depth = _depth, \ - .item_size = sizeof(_type), \ - .overwritable = false, \ - }\ +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + osal_queue_def_t _name = { \ + .role = _role, \ + .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ } -// lock queue by disable usb isr +// lock queue by disable USB interrupt static inline void _osal_q_lock(osal_queue_t qhdl) { (void) qhdl; @@ -176,8 +164,7 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) return (osal_queue_t) qdef; } -// non blocking -static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data) +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) { _osal_q_lock(qhdl); bool success = tu_fifo_read(&qhdl->ff, data); @@ -186,7 +173,7 @@ static inline bool osal_queue_receive(osal_queue_t const qhdl, void* data) return success; } -static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, bool in_isr) +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) { if (!in_isr) { _osal_q_lock(qhdl); @@ -203,6 +190,13 @@ static inline bool osal_queue_send(osal_queue_t const qhdl, void const * data, b return success; } +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + // Skip queue lock/unlock since this function is primarily called + // with interrupt disabled before going into low power mode + return tu_fifo_empty(&qhdl->ff); +} + #ifdef __cplusplus } #endif diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h new file mode 100644 index 000000000..1c3366e01 --- /dev/null +++ b/src/osal/osal_pico.h @@ -0,0 +1,187 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_PICO_H_ +#define _TUSB_OSAL_PICO_H_ + +#include "pico/time.h" +#include "pico/sem.h" +#include "pico/mutex.h" +#include "pico/critical_section.h" + +#ifdef __cplusplus + extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) +{ + sleep_ms(msec); +} + +//--------------------------------------------------------------------+ +// Binary Semaphore API +//--------------------------------------------------------------------+ +typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t; + +static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) +{ + sem_init(semdef, 0, 255); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) +{ + (void) in_isr; + sem_release(sem_hdl); + return true; +} + +static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) +{ + return sem_acquire_timeout_ms(sem_hdl, msec); +} + +static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) +{ + sem_reset(sem_hdl, 0); +} + +//--------------------------------------------------------------------+ +// MUTEX API +// Within tinyusb, mutex is never used in ISR context +//--------------------------------------------------------------------+ +typedef struct mutex osal_mutex_def_t, *osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) +{ + mutex_init(mdef); + return mdef; +} + +static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec) +{ + return mutex_enter_timeout_ms(mutex_hdl, msec); +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) +{ + mutex_exit(mutex_hdl); + return true; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ +#include "common/tusb_fifo.h" + +#if TUSB_OPT_HOST_ENABLED +extern void hcd_int_disable(uint8_t rhport); +extern void hcd_int_enable(uint8_t rhport); +#endif + +typedef struct +{ + tu_fifo_t ff; + struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section +} osal_queue_def_t; + +typedef osal_queue_def_t* osal_queue_t; + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ + uint8_t _name##_buf[_depth*sizeof(_type)]; \ + osal_queue_def_t _name = { \ + .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \ + } + +// lock queue by disable USB interrupt +static inline void _osal_q_lock(osal_queue_t qhdl) +{ + critical_section_enter_blocking(&qhdl->critsec); +} + +// unlock queue +static inline void _osal_q_unlock(osal_queue_t qhdl) +{ + critical_section_exit(&qhdl->critsec); +} + +static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) +{ + critical_section_init(&qdef->critsec); + tu_fifo_clear(&qdef->ff); + return (osal_queue_t) qdef; +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void* data) +{ + // TODO: revisit... docs say that mutexes are never used from IRQ context, + // however osal_queue_recieve may be. therefore my assumption is that + // the fifo mutex is not populated for queues used from an IRQ context + //assert(!qhdl->ff.mutex); + + _osal_q_lock(qhdl); + bool success = tu_fifo_read(&qhdl->ff, data); + _osal_q_unlock(qhdl); + + return success; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) +{ + // TODO: revisit... docs say that mutexes are never used from IRQ context, + // however osal_queue_recieve may be. therefore my assumption is that + // the fifo mutex is not populated for queues used from an IRQ context + //assert(!qhdl->ff.mutex); + (void) in_isr; + + _osal_q_lock(qhdl); + bool success = tu_fifo_write(&qhdl->ff, data); + _osal_q_unlock(qhdl); + + TU_ASSERT(success); + + return success; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) +{ + // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single + // volatile read. + + // Skip queue lock/unlock since this function is primarily called + // with interrupt disabled before going into low power mode + return tu_fifo_empty(&qhdl->ff); +} + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_OSAL_PICO_H_ */ diff --git a/src/osal/osal_rtthread.h b/src/osal/osal_rtthread.h new file mode 100644 index 000000000..d5c062ac1 --- /dev/null +++ b/src/osal/osal_rtthread.h @@ -0,0 +1,130 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020 tfx2001 ([email protected]) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef _TUSB_OSAL_RTTHREAD_H_ +#define _TUSB_OSAL_RTTHREAD_H_ + +// RT-Thread Headers +#include "rtthread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ +static inline void osal_task_delay(uint32_t msec) { + rt_thread_mdelay(msec); +} + +//--------------------------------------------------------------------+ +// Semaphore API +//--------------------------------------------------------------------+ +typedef struct rt_semaphore osal_semaphore_def_t; +typedef rt_sem_t osal_semaphore_t; + +static inline osal_semaphore_t +osal_semaphore_create(osal_semaphore_def_t *semdef) { + rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_FIFO); + return semdef; +} + +static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; + return rt_sem_release(sem_hdl) == RT_EOK; +} + +static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { + return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; +} + +static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { + // TODO: implement +} + +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef struct rt_mutex osal_mutex_def_t; +typedef rt_mutex_t osal_mutex_t; + +static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { + rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_FIFO); + return mdef; +} + +static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { + return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK; +} + +static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { + return rt_mutex_release(mutex_hdl) == RT_EOK; +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +// role device/host is used by OS NONE for mutex (disable usb isr) only +#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \ + static _type _name##_##buf[_depth]; \ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; + +typedef struct { + uint16_t depth; + uint16_t item_sz; + void *buf; + + struct rt_messagequeue sq; +} osal_queue_def_t; + +typedef rt_mq_t osal_queue_t; + +static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) { + rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz, + qdef->item_sz * qdef->depth, RT_IPC_FLAG_FIFO); + return &(qdef->sq); +} + +static inline bool osal_queue_receive(osal_queue_t qhdl, void *data) { + return rt_mq_recv(qhdl, data, qhdl->msg_size, RT_WAITING_FOREVER) == RT_EOK; +} + +static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { + (void) in_isr; + return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK; +} + +static inline bool osal_queue_empty(osal_queue_t qhdl) { + return (qhdl->entry) == 0; +} + +#ifdef __cplusplus +} +#endif + +#endif /* _TUSB_OSAL_RTTHREAD_H_ */ |
