diff options
| author | hathach <[email protected]> | 2013-04-24 17:53:43 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-04-24 17:53:43 +0700 |
| commit | d4a2600ecc8cdeec26485f8ab564b12de41d6b9b (patch) | |
| tree | bb30227f93c28506ca4a38ead6cf3a2dc3b7e251 /tinyusb | |
| parent | 574710dde57a466d0fee6d8b3ccb0366eb64deba (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.h | 3 | ||||
| -rw-r--r-- | tinyusb/host/usbh.c | 40 | ||||
| -rw-r--r-- | tinyusb/host/usbh.h | 4 | ||||
| -rw-r--r-- | tinyusb/osal/osal.h | 9 | ||||
| -rw-r--r-- | tinyusb/osal/osal_freeRTOS.h | 64 | ||||
| -rw-r--r-- | tinyusb/osal/osal_none.h | 28 | ||||
| -rw-r--r-- | tinyusb/tusb.c | 2 |
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 |
