summaryrefslogtreecommitdiff
path: root/tinyusb
diff options
context:
space:
mode:
authorhathach <[email protected]>2013-04-24 17:53:43 +0700
committerhathach <[email protected]>2013-04-24 17:53:43 +0700
commitd4a2600ecc8cdeec26485f8ab564b12de41d6b9b (patch)
treebb30227f93c28506ca4a38ead6cf3a2dc3b7e251 /tinyusb
parent574710dde57a466d0fee6d8b3ccb0366eb64deba (diff)
- change OSAL_TASK_FUNCTION to have void* parameter (to be consistent with most popular RTOS)
- add new error enum TUSB_ERROR_OSAL_TASK_CREATE_FAILED - move usbh_enumeration_task prototype to usbh.h - change OSAL_SUBTASK_INVOKED_AND_WAIT behavior, will not "return" in calling task when subtask got error status. calling task need to do that after the call - osal_queue_receive signature from uint32_t* to void* - implement osal_freertos.h for FreeRTOS 7.3 --> able to compile & build host_freertos + OSAL_TASK_FUNCTION + turn on FPU for M4 in both host_os_none & host_freertos (freertos requires FPU to be on to compile) + osal_task_create + OSAL_SUBTASK_INVOKED_AND_WAIT + SUBTASK_ASSERT + osal_semaphore_reset + osal_queue_flush + adding heap_1.c for memory management
Diffstat (limited to 'tinyusb')
-rw-r--r--tinyusb/common/errors.h3
-rw-r--r--tinyusb/host/usbh.c40
-rw-r--r--tinyusb/host/usbh.h4
-rw-r--r--tinyusb/osal/osal.h9
-rw-r--r--tinyusb/osal/osal_freeRTOS.h64
-rw-r--r--tinyusb/osal/osal_none.h28
-rw-r--r--tinyusb/tusb.c2
7 files changed, 87 insertions, 63 deletions
diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h
index 41d8d43fe..0392865e1 100644
--- a/tinyusb/common/errors.h
+++ b/tinyusb/common/errors.h
@@ -68,8 +68,9 @@
ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND)\
ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG)\
ENTRY(TUSB_ERROR_OSAL_TIMEOUT)\
- ENTRY(TUSB_ERROR_OSAL_WAITING)\
+ ENTRY(TUSB_ERROR_OSAL_WAITING) /* only used by OSAL_NONE in the subtask */ \
ENTRY(TUSB_ERROR_OSAL_TASK_FAILED)\
+ ENTRY(TUSB_ERROR_OSAL_TASK_CREATE_FAILED)\
ENTRY(TUSB_ERROR_OSAL_QUEUE_FAILED)\
ENTRY(TUSB_ERROR_OSAL_SEMAPHORE_FAILED)\
ENTRY(TUSB_ERROR_EHCI_NOT_ENOUGH_QTD)\
diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c
index 8e525cdf5..55f3eb771 100644
--- a/tinyusb/host/usbh.c
+++ b/tinyusb/host/usbh.c
@@ -87,7 +87,6 @@ static host_class_driver_t const usbh_class_drivers[TUSB_CLASS_MAX_CONSEC_NUMBER
// INTERNAL OBJECT & FUNCTION DECLARATION
//--------------------------------------------------------------------+
usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1] TUSB_CFG_ATTR_USBRAM; // including zero-address
-OSAL_TASK_FUNCTION(usbh_enumeration_task);
//------------- Enumeration Task Data -------------//
OSAL_TASK_DEF(enum_task, usbh_enumeration_task, 128, OSAL_PRIO_HIGH);
@@ -254,7 +253,7 @@ tusb_error_t enumeration_body_subtask(void);
// To enable the TASK_ASSERT style (quick return on false condition) in a real RTOS, a task must act as a wrapper
// and is used mainly to call subtasks. Within a subtask return statement can be called freely, the task with
// forever loop cannot have any return at all.
-OSAL_TASK_FUNCTION(usbh_enumeration_task)
+OSAL_TASK_FUNCTION(usbh_enumeration_task) (void* p_task_para)
{
OSAL_TASK_LOOP_BEGIN
@@ -304,9 +303,10 @@ tusb_error_t enumeration_body_subtask(void)
.wValue = (TUSB_DESC_DEVICE << 8),
.wLength = 8
},
- enum_data_buffer
- )
+ enum_data_buffer ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error); // TODO some slow device is observed to fail the very fist controler xfer, can try more times
hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
@@ -323,9 +323,10 @@ tusb_error_t enumeration_body_subtask(void)
.bRequest = TUSB_REQUEST_SET_ADDRESS,
.wValue = new_addr
},
- NULL
- )
+ NULL ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error);
//------------- update port info & close control pipe of addr0 -------------//
usbh_devices[new_addr].core_id = usbh_devices[0].core_id;
@@ -351,9 +352,10 @@ tusb_error_t enumeration_body_subtask(void)
.wValue = (TUSB_DESC_DEVICE << 8),
.wLength = 18
},
- enum_data_buffer
- )
+ enum_data_buffer ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error);
// update device info TODO alignment issue
usbh_devices[new_addr].vendor_id = ((tusb_descriptor_device_t*) enum_data_buffer)->idVendor;
@@ -374,9 +376,10 @@ tusb_error_t enumeration_body_subtask(void)
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
.wLength = 9
},
- enum_data_buffer
- )
+ enum_data_buffer ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error);
SUBTASK_ASSERT_WITH_HANDLER( TUSB_CFG_HOST_ENUM_BUFFER_SIZE > ((tusb_descriptor_configuration_t*)enum_data_buffer)->wTotalLength,
tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG, NULL) );
@@ -391,9 +394,10 @@ tusb_error_t enumeration_body_subtask(void)
.wValue = (TUSB_DESC_CONFIGURATION << 8) | (configure_selected - 1),
.wLength = ((tusb_descriptor_configuration_t*) enum_data_buffer)->wTotalLength
},
- enum_data_buffer
- )
+ enum_data_buffer ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error);
// update configuration info
usbh_devices[new_addr].interface_count = ((tusb_descriptor_configuration_t*) enum_data_buffer)->bNumInterfaces;
@@ -408,9 +412,10 @@ tusb_error_t enumeration_body_subtask(void)
.bRequest = TUSB_REQUEST_SET_CONFIGURATION,
.wValue = configure_selected
},
- NULL
- )
+ NULL ),
+ error
);
+ SUBTASK_ASSERT_STATUS(error);
usbh_devices[new_addr].state = TUSB_DEVICE_STATE_CONFIGURED;
@@ -437,10 +442,11 @@ tusb_error_t enumeration_body_subtask(void)
uint16_t length=0;
OSAL_SUBTASK_INVOKED_AND_WAIT ( // parameters in task/sub_task must be static storage (static or global)
usbh_class_drivers[ ((tusb_descriptor_interface_t*) p_desc)->bInterfaceClass ].open_subtask(
- new_addr, (tusb_descriptor_interface_t*) p_desc, &length) );
+ new_addr, (tusb_descriptor_interface_t*) p_desc, &length),
+ error
+ );
- // TODO check class_open_subtask status
- if (length == 0) // Interface open failed, for example a subclass is not supported
+ if (error != TUSB_ERROR_NONE || length == 0) // Interface open failed, for example a subclass is not supported
{
p_desc += p_desc[DESCRIPTOR_OFFSET_LENGTH]; // skip this interface, the rest will be skipped by the above loop
// TODO can optimize the length --> open_subtask return a OPEN FAILED status
diff --git a/tinyusb/host/usbh.h b/tinyusb/host/usbh.h
index 6c4cce89b..39265857a 100644
--- a/tinyusb/host/usbh.h
+++ b/tinyusb/host/usbh.h
@@ -58,6 +58,7 @@
//--------------------------------------------------------------------+
// INCLUDE
//--------------------------------------------------------------------+
+#include "osal/osal.h" // TODO refractor move to common.h ?
#include "hcd.h"
//--------------------------------------------------------------------+
@@ -108,10 +109,11 @@ void tusbh_device_mount_failed_cb(tusb_error_t error, tusb_descriptor_de
#endif
//--------------------------------------------------------------------+
-// CLASS-USBD API
+// CLASS-USBD & INTERNAL API
//--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_
+OSAL_TASK_FUNCTION (usbh_enumeration_task) (void* p_task_para);
tusb_error_t usbh_init(void);
#endif
diff --git a/tinyusb/osal/osal.h b/tinyusb/osal/osal.h
index 8c33dc273..f0174c080 100644
--- a/tinyusb/osal/osal.h
+++ b/tinyusb/osal/osal.h
@@ -90,19 +90,20 @@ tusb_error_t osal_task_create(osal_task_t *task);
osal_task_t name
#define OSAL_TASK_FUNCTION(task_name) \
- void task_name(void)
+ void task_name
#define OSAL_TASK_LOOP_BEGIN
#define OSAL_TASK_LOOP_END
//------------- Sub Task -------------//
-#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask) SUBTASK_ASSERT_STATUS(subtask)
+#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask, status) \
+ status = subtask
#define OSAL_SUBTASK_BEGIN
#define OSAL_SUBTASK_END \
return TUSB_ERROR_NONE;
-//------------- Sub Task Assert (like Task but return error) -------------//
+//------------- Sub Task Assert -------------//
#define _SUBTASK_ASSERT_ERROR_HANDLER(error, func_call)\
func_call; return error
@@ -153,7 +154,7 @@ typedef osal_queue_t * osal_queue_handle_t;
osal_queue_t name
osal_queue_handle_t osal_queue_create (osal_queue_t *p_queue);
-void osal_queue_receive (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error);
+void osal_queue_receive (osal_queue_handle_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error);
tusb_error_t osal_queue_send (osal_queue_handle_t const queue_hdl, const void * data);
void osal_queue_flush(osal_queue_handle_t const queue_hdl);
diff --git a/tinyusb/osal/osal_freeRTOS.h b/tinyusb/osal/osal_freeRTOS.h
index 53986ad97..d92cb374c 100644
--- a/tinyusb/osal/osal_freeRTOS.h
+++ b/tinyusb/osal/osal_freeRTOS.h
@@ -57,7 +57,7 @@
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
-//#include "task.h"
+#include "task.h"
#ifdef __cplusplus
extern "C" {
@@ -71,6 +71,9 @@ extern "C" {
//--------------------------------------------------------------------+
// TASK API
//--------------------------------------------------------------------+
+#define OSAL_TASK_FUNCTION(task_func) \
+ void task_func
+
typedef struct {
signed portCHAR const * name;
pdTASK_CODE code;
@@ -86,9 +89,12 @@ typedef struct {
.prio = task_prio \
};
-#define OSAL_TASK_FUNCTION(task_name) \
- void task_name(void *p_task_para)
-
+static inline tusb_error_t osal_task_create(osal_task_t *task) ATTR_ALWAYS_INLINE;
+static inline tusb_error_t osal_task_create(osal_task_t *task)
+{
+ return pdPASS == xTaskCreate(task->code, task->name, task->stack_depth, NULL, task->prio, NULL) ?
+ TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TASK_CREATE_FAILED;
+}
#define OSAL_TASK_LOOP_BEGIN \
while(1) {
@@ -100,26 +106,24 @@ typedef struct {
#define OSAL_SUBTASK_BEGIN // TODO refractor move
#define OSAL_SUBTASK_END
-//------------- Task Assert -------------//
-#define TASK_RESTART
+#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask, status) \
+ status = subtask
-// TODO FreeRTOS TASK_ASSERT need to omit do while to get continue statement works.
-#define _TASK_ASSERT_ERROR_HANDLER(error, func_call) \
- func_call; TASK_RESTART;
+//------------- Sub Task Assert -------------//
-#define TASK_ASSERT(condition)
-#define TASK_ASSERT_STATUS(sts)
+#define SUBTASK_ASSERT_STATUS(sts) ASSERT_STATUS(sts)
+#define SUBTASK_ASSERT(condition) ASSERT(condition, TUSB_ERROR_OSAL_TASK_FAILED)
-#define TASK_ASSERT_WITH_HANDLER(condition, func_call) \
- ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, ,\
- condition, TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
+#define _SUBTASK_ASSERT_ERROR_HANDLER(error, func_call)\
+ func_call; return error
+#define SUBTASK_ASSERT_STATUS_WITH_HANDLER(sts, func_call) \
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, tusb_error_t status = (tusb_error_t)(sts),\
+ TUSB_ERROR_NONE == status, status, "%s", TUSB_ErrorStr[status])
-//------------- Sub Task Assert -------------//
-#define SUBTASK_ASSERT_STATUS TASK_ASSERT_STATUS
-#define SUBTASK_ASSERT_STATUS_WITH_HANDLER TASK_ASSERT_STATUS_WITH_HANDLER
-#define SUBTASK_ASSERT TASK_ASSERT
-#define SUBTASK_ASSERT_WITH_HANDLER TASK_ASSERT_WITH_HANDLER
+#define SUBTASK_ASSERT_WITH_HANDLER(condition, func_call) \
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, ,\
+ condition, TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
//--------------------------------------------------------------------+
// Semaphore API
@@ -131,11 +135,12 @@ typedef xSemaphoreHandle osal_semaphore_handle_t;
#define osal_semaphore_create(x) \
xQueueGenericCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
+// TODO add timeout (with instant return from ISR option) for semaphore post & queue send
static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t const sem_hdl) ATTR_ALWAYS_INLINE;
static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t const sem_hdl)
{
- portBASE_TYPE taskWaken;
- return (xSemaphoreGiveFromISR(sem_hdl, &taskWaken) == pdTRUE) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_SEMAPHORE_FAILED;
+ portBASE_TYPE task_waken;
+ return (xSemaphoreGiveFromISR(sem_hdl, &task_waken) == pdTRUE) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_SEMAPHORE_FAILED;
}
static inline void osal_semaphore_wait(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
@@ -144,6 +149,13 @@ static inline void osal_semaphore_wait(osal_semaphore_handle_t const sem_hdl, ui
(*p_error) = ( xSemaphoreTake(sem_hdl, osal_tick_from_msec(msec)) == pdPASS ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT;
}
+static inline void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl) ATTR_ALWAYS_INLINE;
+static inline void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl)
+{
+ portBASE_TYPE task_waken;
+ xSemaphoreTakeFromISR(sem_hdl, &task_waken);
+}
+
//--------------------------------------------------------------------+
// QUEUE API
//--------------------------------------------------------------------+
@@ -161,8 +173,8 @@ typedef xQueueHandle osal_queue_handle_t;
#define osal_queue_create(p_queue) \
xQueueCreate((p_queue)->depth, sizeof(uint32_t))
-static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
-static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, uint32_t *p_data, uint32_t msec, tusb_error_t *p_error)
+static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error) ATTR_ALWAYS_INLINE;
+static inline void osal_queue_receive (osal_queue_handle_t const queue_hdl, void *p_data, uint32_t msec, tusb_error_t *p_error)
{
(*p_error) = ( xQueueReceive(queue_hdl, p_data, osal_tick_from_msec(msec)) == pdPASS ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_TIMEOUT;
}
@@ -174,6 +186,12 @@ static inline tusb_error_t osal_queue_send(osal_queue_handle_t const queue_hdl,
return ( xQueueSendFromISR(queue_hdl, data, &taskWaken) == pdTRUE ) ? TUSB_ERROR_NONE : TUSB_ERROR_OSAL_QUEUE_FAILED;
}
+static inline void osal_queue_flush(osal_queue_handle_t const queue_hdl) ATTR_ALWAYS_INLINE;
+static inline void osal_queue_flush(osal_queue_handle_t const queue_hdl)
+{
+ xQueueReset(queue_hdl);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/tinyusb/osal/osal_none.h b/tinyusb/osal/osal_none.h
index 2aaa9b784..66b2bd0ca 100644
--- a/tinyusb/osal/osal_none.h
+++ b/tinyusb/osal/osal_none.h
@@ -90,10 +90,10 @@ static inline volatile uint32_t osal_tick_get(void)
#define OSAL_TASK_DEF(name, code, stack_depth, prio)
#define osal_task_create(x) TUSB_ERROR_NONE
-#define OSAL_TASK_FUNCTION(task_name) \
- tusb_error_t task_name(void)
-
-#define TASK_RESTART state = 0
+#define OSAL_TASK_FUNCTION(task_func) \
+ tusb_error_t task_func
+#define TASK_RESTART \
+ state = 0
#define OSAL_TASK_LOOP_BEGIN \
static uint32_t timeout = 0;\
@@ -108,41 +108,37 @@ static inline volatile uint32_t osal_tick_get(void)
return TUSB_ERROR_NONE;
//------------- Sub Task -------------//
-#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask) \
+#define OSAL_SUBTASK_INVOKED_AND_WAIT(subtask, status) \
do {\
state = __LINE__; case __LINE__:\
{\
- tusb_error_t status = subtask; /* invoke sub task */\
+ status = subtask; /* invoke sub task */\
if (TUSB_ERROR_OSAL_WAITING == status) /* sub task not finished -> continue waiting */\
return TUSB_ERROR_OSAL_WAITING;\
- else if (TUSB_ERROR_NONE != status) { /* sub task failed -> restart task*/\
- TASK_RESTART;\
- return status;\
- }/* sub task finished ok --> continue */\
}\
}while(0)
#define OSAL_SUBTASK_BEGIN OSAL_TASK_LOOP_BEGIN
#define OSAL_SUBTASK_END OSAL_TASK_LOOP_END
-//------------- Task Assert -------------//
-#define _TASK_ASSERT_ERROR_HANDLER(error, func_call) \
+//------------- Sub Task Assert -------------//
+#define _SUBTASK_ASSERT_ERROR_HANDLER(error, func_call) \
func_call; TASK_RESTART; return error
#define SUBTASK_ASSERT_STATUS(sts) \
- ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, , tusb_error_t status = (tusb_error_t)(sts),\
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, , tusb_error_t status = (tusb_error_t)(sts),\
TUSB_ERROR_NONE == status, status, "%s", TUSB_ErrorStr[status])
#define SUBTASK_ASSERT_STATUS_WITH_HANDLER(sts, func_call) \
- ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, tusb_error_t status = (tusb_error_t)(sts),\
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, tusb_error_t status = (tusb_error_t)(sts),\
TUSB_ERROR_NONE == status, status, "%s", TUSB_ErrorStr[status])
#define SUBTASK_ASSERT(condition) \
- ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, , , \
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, , , \
(condition), TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
#define SUBTASK_ASSERT_WITH_HANDLER(condition, func_call) \
- ASSERT_DEFINE_WITH_HANDLER(_TASK_ASSERT_ERROR_HANDLER, func_call, ,\
+ ASSERT_DEFINE_WITH_HANDLER(_SUBTASK_ASSERT_ERROR_HANDLER, func_call, ,\
condition, TUSB_ERROR_OSAL_TASK_FAILED, "%s", "evaluated to false")
//--------------------------------------------------------------------+
diff --git a/tinyusb/tusb.c b/tinyusb/tusb.c
index 6e7662aa9..fe61c105d 100644
--- a/tinyusb/tusb.c
+++ b/tinyusb/tusb.c
@@ -72,7 +72,7 @@ void tusb_isr(uint8_t controller_id)
void tusb_task_runner(void)
{
#if MODE_HOST_SUPPORTED
- usbh_enumeration_task(); // TODO prototype
+ usbh_enumeration_task(NULL);
#endif
}
#endif