From 3bca56665cb802e6e599fb4a1a2be5dd6e64b70b Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 27 Jun 2013 16:19:22 +0700 Subject: [PATCH] add mutex support for osal add test for mutex in test_osal_none.c implement usbh_control_xfer using mutex to get access to queue xfer on control pipe (while semaphore is used to sync with hcd DMA) failed to issue control xfer: set idle & get report descriptor in hidh_open_subtask (more to work on) --- tests/support/descriptor_test.c | 2 +- tests/test/test/host/host_helper.h | 1 + tests/test/test/host/usbh/test_enum_task.c | 11 ++- tests/test/test/host/usbh/test_usbh.c | 57 +++++++++++++- tests/test/test/test_osal_none.c | 91 +++++++++++++++++++++- tinyusb/class/hid_host.c | 19 +++++ tinyusb/common/errors.h | 1 + tinyusb/host/usbh.c | 32 +++++--- tinyusb/host/usbh_hcd.h | 12 ++- tinyusb/osal/osal.h | 24 +++++- tinyusb/osal/osal_none.h | 49 ++++++++++-- 11 files changed, 270 insertions(+), 29 deletions(-) diff --git a/tests/support/descriptor_test.c b/tests/support/descriptor_test.c index a972da03e..725baa841 100644 --- a/tests/support/descriptor_test.c +++ b/tests/support/descriptor_test.c @@ -151,7 +151,7 @@ const app_configuration_desc_t desc_configuration = .bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION, .wTotalLength = sizeof(app_configuration_desc_t) - 1, // exclude termination - .bNumInterfaces = 1, + .bNumInterfaces = 3, .bConfigurationValue = 1, .iConfiguration = 0x00, diff --git a/tests/test/test/host/host_helper.h b/tests/test/test/host/host_helper.h index f4fdf62d4..97102c565 100644 --- a/tests/test/test/host/host_helper.h +++ b/tests/test/test/host/host_helper.h @@ -58,6 +58,7 @@ static inline void helper_usbh_init_expect(void) osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234); osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE); osal_queue_create_IgnoreAndReturn( (osal_queue_handle_t) 0x4566 ); + osal_mutex_create_IgnoreAndReturn((osal_mutex_handle_t) 0x789a); } static inline void helper_usbh_device_emulate(uint8_t dev_addr, uint8_t hub_addr, uint8_t hub_port, uint8_t hostid, tusb_speed_t speed) diff --git a/tests/test/test/host/usbh/test_enum_task.c b/tests/test/test/host/usbh/test_enum_task.c index 3d0f9f193..ae3fe34c5 100644 --- a/tests/test/test/host/usbh/test_enum_task.c +++ b/tests/test/test/host/usbh/test_enum_task.c @@ -50,7 +50,6 @@ extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; extern uint8_t enum_data_buffer[TUSB_CFG_HOST_ENUM_BUFFER_SIZE]; -uint8_t dev_addr; usbh_enumerate_t const enum_connect = { .core_id = 0, @@ -70,12 +69,15 @@ void setUp(void) osal_queue_receive_StubWithCallback(queue_recv_stub); osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub); + osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub); + osal_mutex_release_IgnoreAndReturn(TUSB_ERROR_NONE); hcd_pipe_control_xfer_StubWithCallback(control_xfer_stub); hcd_port_connect_status_ExpectAndReturn(enum_connect.core_id, true); hcd_port_reset_Expect(enum_connect.core_id); hcd_port_speed_get_ExpectAndReturn(enum_connect.core_id, device_speed); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(0, 8, TUSB_ERROR_NONE); } @@ -172,6 +174,7 @@ tusb_error_t hidh_install_stub(uint8_t dev_addr, tusb_descriptor_interface_t con void test_addr0_failed_dev_desc(void) { osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(0)); + tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); @@ -199,6 +202,7 @@ void test_enum_failed_get_full_dev_desc(void) hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); @@ -218,6 +222,8 @@ void test_enum_failed_get_9byte_config_desc(void) hcd_port_reset_Expect( usbh_devices[0].core_id ); hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); + hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); @@ -235,6 +241,7 @@ void test_enum_failed_get_full_config_desc(void) hcd_port_reset_Expect( usbh_devices[0].core_id ); hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); @@ -253,6 +260,7 @@ void test_enum_parse_config_desc(void) hcd_port_reset_Expect( usbh_devices[0].core_id ); hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); @@ -269,6 +277,7 @@ void test_enum_set_configure(void) hcd_port_reset_Expect( usbh_devices[0].core_id ); hcd_pipe_control_close_ExpectAndReturn(0, TUSB_ERROR_NONE); osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); + osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); class_install_expect(); diff --git a/tests/test/test/host/usbh/test_usbh.c b/tests/test/test/host/usbh/test_usbh.c index b72fd2966..30f4a4dfc 100644 --- a/tests/test/test/host/usbh/test_usbh.c +++ b/tests/test/test/host/usbh/test_usbh.c @@ -90,7 +90,6 @@ void test_usbh_init_hcd_failed(void) void test_usbh_init_enum_task_create_failed(void) { hcd_init_ExpectAndReturn(TUSB_ERROR_NONE); - osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234); osal_task_create_IgnoreAndReturn(TUSB_ERROR_OSAL_TASK_FAILED); TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TASK_FAILED, usbh_init()); } @@ -98,12 +97,30 @@ void test_usbh_init_enum_task_create_failed(void) void test_usbh_init_enum_queue_create_failed(void) { hcd_init_ExpectAndReturn(TUSB_ERROR_NONE); - osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234); osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE); osal_queue_create_IgnoreAndReturn(NULL); TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_QUEUE_FAILED, usbh_init()); } +void test_usbh_init_semaphore_create_failed(void) +{ + hcd_init_ExpectAndReturn(TUSB_ERROR_NONE); + osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE); + osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234); + osal_semaphore_create_IgnoreAndReturn(NULL); + TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_SEMAPHORE_FAILED, usbh_init()); +} + +void test_usbh_init_mutex_create_failed(void) +{ + hcd_init_ExpectAndReturn(TUSB_ERROR_NONE); + osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE); + osal_queue_create_IgnoreAndReturn((osal_queue_handle_t) 0x1234); + osal_semaphore_create_IgnoreAndReturn((osal_semaphore_handle_t) 0x1234); + osal_mutex_create_IgnoreAndReturn(NULL); + TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_MUTEX_FAILED, usbh_init()); +} + void test_usbh_init_ok(void) { hcd_init_ExpectAndReturn(TUSB_ERROR_NONE); @@ -151,3 +168,39 @@ void test_usbh_device_unplugged_isr(void) TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, usbh_devices[dev_addr].state); } + +void semaphore_wait_success_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) +{ + (*p_error) = TUSB_ERROR_NONE; +} + +static void mutex_wait_failed_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) +{ + (*p_error) = TUSB_ERROR_OSAL_TIMEOUT; +} + +void test_usbh_control_xfer_mutex_failed(void) +{ + tusb_std_request_t a_request; + + osal_mutex_wait_StubWithCallback(mutex_wait_failed_stub); + osal_mutex_release_ExpectAndReturn(usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE); + + //------------- Code Under Test -------------// + usbh_control_xfer_subtask(dev_addr, &a_request, NULL); +} + +void test_usbh_control_xfer_ok(void) +{ + tusb_std_request_t a_request; + + osal_mutex_wait_StubWithCallback(semaphore_wait_success_stub); + + hcd_pipe_control_xfer_ExpectAndReturn(dev_addr, &a_request, NULL, TUSB_ERROR_NONE); + osal_semaphore_wait_StubWithCallback(semaphore_wait_success_stub); + + osal_mutex_release_ExpectAndReturn(usbh_devices[dev_addr].control.mutex_hdl, TUSB_ERROR_NONE); + + //------------- Code Under Test -------------// + usbh_control_xfer_subtask(dev_addr, &a_request, NULL); +} diff --git a/tests/test/test/test_osal_none.c b/tests/test/test/test_osal_none.c index 814a8602c..46e7d090d 100644 --- a/tests/test/test/test_osal_none.c +++ b/tests/test/test/test_osal_none.c @@ -54,11 +54,15 @@ osal_semaphore_handle_t sem_hdl; OSAL_QUEUE_DEF(queue, QUEUE_DEPTH, uint32_t); osal_queue_handle_t queue_hdl; +OSAL_MUTEX_DEF(mutex); +osal_mutex_handle_t mutex_hdl; + void setUp(void) { memset(statements, 0, sizeof(statements)); sem_hdl = osal_semaphore_create(OSAL_SEM_REF(sem)); queue_hdl = osal_queue_create(&queue); + mutex_hdl = osal_mutex_create(OSAL_MUTEX_REF(mutex)); } void tearDown(void) @@ -82,6 +86,21 @@ void test_semaphore_post(void) } // blocking service such as semaphore wait need to be invoked within a task's loop +//--------------------------------------------------------------------+ +// Mutex +//--------------------------------------------------------------------+ +void test_mutex_create(void) +{ + TEST_ASSERT_EQUAL_PTR(&mutex, mutex_hdl); + TEST_ASSERT_EQUAL(1, mutex); +} + +void test_mutex_release(void) +{ + osal_mutex_release(mutex_hdl); + TEST_ASSERT_EQUAL(1, mutex); +} + //--------------------------------------------------------------------+ // Queue //--------------------------------------------------------------------+ @@ -163,6 +182,76 @@ void test_task_with_semaphore(void) TEST_ASSERT_EQUAL(2, statements[0]); } +//--------------------------------------------------------------------+ +// TASK MUTEX +//--------------------------------------------------------------------+ +tusb_error_t mutex_sample_task1(void) // occupy mutex and not release it +{ + tusb_error_t error = TUSB_ERROR_NONE; + + OSAL_TASK_LOOP_BEGIN + + statements[0]++; + + osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error); + statements[2]++; + + OSAL_TASK_LOOP_END +} + +tusb_error_t mutex_sample_task2(void) +{ + tusb_error_t error = TUSB_ERROR_NONE; + + OSAL_TASK_LOOP_BEGIN + + statements[1]++; + + osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_WAIT_FOREVER, &error); + statements[3]++; + + osal_mutex_wait(mutex_hdl, OSAL_TIMEOUT_NORMAL, &error); + statements[5]++; + + TEST_ASSERT_EQUAL(TUSB_ERROR_OSAL_TIMEOUT, error); + + OSAL_TASK_LOOP_END +} + +void test_task_with_mutex(void) +{ + // several invoke before mutex is available + mutex_sample_task1(); + for(uint32_t i=0; i<10; i++) { + mutex_sample_task2(); + } + + TEST_ASSERT_EQUAL(1, statements[0]); + TEST_ASSERT_EQUAL(1, statements[2]); + + TEST_ASSERT_EQUAL(1, statements[1]); + TEST_ASSERT_EQUAL(0, statements[3]); + + // invoke after posting mutex + osal_mutex_release(mutex_hdl); + for(uint32_t i=0; i<10; i++) { + mutex_sample_task2(); + } + TEST_ASSERT_EQUAL(1, statements[3]); + TEST_ASSERT_EQUAL(0, statements[5]); + + // timeout + for(uint32_t i=0; i<(OSAL_TIMEOUT_NORMAL*TUSB_CFG_OS_TICKS_PER_SECOND)/1000 ; i++){ // one tick less + osal_tick_tock(); + } + mutex_sample_task2(); + TEST_ASSERT_EQUAL(0, statements[5]); + osal_tick_tock(); + + mutex_sample_task2(); + TEST_ASSERT_EQUAL(1, statements[5]); +} + //--------------------------------------------------------------------+ // TASK QUEUE //--------------------------------------------------------------------+ @@ -205,7 +294,7 @@ void test_task_with_queue(void) sample_task_with_queue(); TEST_ASSERT_EQUAL(1, statements[0]); - // invoke after posting semaphore + // invoke after sending to queue item = 0x1111; osal_queue_send(queue_hdl, &item); sample_task_with_queue(); diff --git a/tinyusb/class/hid_host.c b/tinyusb/class/hid_host.c index bdadc5666..5d780a819 100644 --- a/tinyusb/class/hid_host.c +++ b/tinyusb/class/hid_host.c @@ -197,6 +197,7 @@ void hidh_init(void) #endif } +//uint8_t report_descriptor[256] TUSB_CFG_ATTR_USBRAM; tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) { tusb_error_t error; @@ -215,6 +216,8 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con OSAL_SUBTASK_BEGIN //------------- SET IDLE request -------------// + // TODO this request can be stalled by device (indicate not supported), + // until we have clear stall handler, temporarily disable it. // OSAL_SUBTASK_INVOKED_AND_WAIT( // usbh_control_xfer_subtask( // dev_addr, @@ -230,6 +233,22 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con // ); //------------- TODO skip Get Report Descriptor -------------// +// memclr_(report_descriptor, 256); + +// OSAL_SUBTASK_INVOKED_AND_WAIT( +// usbh_control_xfer_subtask( +// dev_addr, +// &(tusb_std_request_t) +// { +// .bmRequestType = { .direction = TUSB_DIR_DEV_TO_HOST, .type = TUSB_REQUEST_TYPE_STANDARD, .recipient = TUSB_REQUEST_RECIPIENT_INTERFACE }, +// .bRequest = TUSB_REQUEST_GET_DESCRIPTOR, +// .wValue = HID_DESC_TYPE_REPORT, +// .wIndex = p_interface_desc->bInterfaceNumber, +// .wLength = p_desc_hid->wReportLength, +// }, +// report_descriptor ), +// error +// ); // uint8_t *p_report_desc = NULL; // report descriptor has to be global & in USB RAM if ( HID_SUBCLASS_BOOT == p_interface_desc->bInterfaceSubClass ) diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h index 9017d99f4..dc9908bfd 100644 --- a/tinyusb/common/errors.h +++ b/tinyusb/common/errors.h @@ -74,6 +74,7 @@ ENTRY(TUSB_ERROR_OSAL_TASK_CREATE_FAILED )\ ENTRY(TUSB_ERROR_OSAL_QUEUE_FAILED )\ ENTRY(TUSB_ERROR_OSAL_SEMAPHORE_FAILED )\ + ENTRY(TUSB_ERROR_OSAL_MUTEX_FAILED )\ ENTRY(TUSB_ERROR_EHCI_NOT_ENOUGH_QTD )\ ENTRY(TUSB_ERROR_USBD_DESCRIPTOR_STRING )\ ENTRY(TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE )\ diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 419b1a534..90ee096cd 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -144,23 +144,30 @@ tusb_error_t usbh_init(void) ASSERT_STATUS( hcd_init() ); - //------------- Semaphore for Control Pipe -------------// - for(uint8_t i=0; icontrol.sem_hdl = osal_semaphore_create( OSAL_SEM_REF(p_device->control.semaphore) ); + ASSERT_PTR(p_device->control.sem_hdl, TUSB_ERROR_OSAL_SEMAPHORE_FAILED); + + p_device->control.mutex_hdl = osal_mutex_create ( OSAL_SEM_REF(p_device->control.mutex) ); + ASSERT_PTR(p_device->control.mutex_hdl, TUSB_ERROR_OSAL_MUTEX_FAILED); + } + //------------- class init -------------// for (uint8_t class_index = 1; class_index < TUSB_CLASS_MAPPED_INDEX_END; class_index++) { if (usbh_class_drivers[class_index].init) + { usbh_class_drivers[class_index].init(); + } } return TUSB_ERROR_NONE; @@ -174,11 +181,17 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, tusb_std_request_t cons OSAL_SUBTASK_BEGIN - usbh_devices[dev_addr].control.pipe_status = TUSB_INTERFACE_STATUS_BUSY; + osal_mutex_wait(usbh_devices[dev_addr].control.mutex_hdl, OSAL_TIMEOUT_NORMAL, &error); + SUBTASK_ASSERT_STATUS_WITH_HANDLER(error, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl)); + usbh_devices[dev_addr].control.request = *p_request; - SUBTASK_ASSERT_STATUS( hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data) ); + /*SUBTASK_ASSERT_STATUS*/ (void) ( hcd_pipe_control_xfer(dev_addr, &usbh_devices[dev_addr].control.request, data) ); + usbh_devices[dev_addr].control.pipe_status = TUSB_INTERFACE_STATUS_BUSY; osal_semaphore_wait(usbh_devices[dev_addr].control.sem_hdl, OSAL_TIMEOUT_NORMAL, &error); // careful of local variable without static + + osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl); + // TODO make handler for this function general purpose SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error && usbh_devices[dev_addr].control.pipe_status != TUSB_INTERFACE_STATUS_ERROR, tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) ); @@ -190,6 +203,7 @@ tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) A tusb_error_t usbh_pipe_control_open(uint8_t dev_addr, uint8_t max_packet_size) { osal_semaphore_reset( usbh_devices[dev_addr].control.sem_hdl ); + osal_mutex_reset( usbh_devices[dev_addr].control.mutex_hdl ); ASSERT_STATUS( hcd_pipe_control_open(dev_addr, max_packet_size) ); diff --git a/tinyusb/host/usbh_hcd.h b/tinyusb/host/usbh_hcd.h index fa676dfc9..fbb7379a7 100644 --- a/tinyusb/host/usbh_hcd.h +++ b/tinyusb/host/usbh_hcd.h @@ -92,15 +92,19 @@ typedef struct { // TODO internal structure, re-order members uint8_t interface_count; // bNumInterfaces alias //------------- device -------------// - volatile uint8_t state; // device state, value from enum tusbh_device_state_t - uint32_t flag_supported_class; // a bitmap of supported class + volatile uint8_t state; // device state, value from enum tusbh_device_state_t + uint32_t flag_supported_class; // a bitmap of supported class //------------- control pipe -------------// struct { volatile uint8_t pipe_status; tusb_std_request_t request; - OSAL_SEM_DEF(semaphore); // TODO move to semaphore pool - osal_semaphore_handle_t sem_hdl; + + OSAL_SEM_DEF(semaphore); // TODO move to semaphore pool ? + osal_semaphore_handle_t sem_hdl; // used to synchronize with HCD when control xfer complete + + OSAL_MUTEX_DEF(mutex); // TODO move to mutex pool ? + osal_mutex_handle_t mutex_hdl; // used to exclusively occupy control pipe } control; } usbh_device_info_t; diff --git a/tinyusb/osal/osal.h b/tinyusb/osal/osal.h index c28bc4790..f40900919 100644 --- a/tinyusb/osal/osal.h +++ b/tinyusb/osal/osal.h @@ -133,11 +133,27 @@ typedef osal_semaphore_t * osal_semaphore_handle_t; #define OSAL_SEM_REF(name)\ &name -osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * const sem); -void osal_semaphore_wait(osal_semaphore_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error); -tusb_error_t osal_semaphore_post(osal_semaphore_handle_t const sem_hdl); -void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl); +osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * p_sem); +void osal_semaphore_wait(osal_semaphore_handle_t sem_hdl, uint32_t msec, tusb_error_t *p_error); +tusb_error_t osal_semaphore_post(osal_semaphore_handle_t sem_hdl); +void osal_semaphore_reset(osal_semaphore_handle_t sem_hdl); +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +#define OSAL_MUTEX_DEF(name)\ + osal_mutex_t name + +#define OSAL_MUTEX_REF(name)\ + &name + +typedef osal_semaphore_t osal_mutex_t; +typedef osal_semaphore_handle_t osal_mutex_handle_t; + +osal_mutex_handle_t osal_mutex_create(osal_mutex_t * p_mutex); +void osal_mutex_wait(osal_mutex_handle_t mutex_hdl, uint32_t msec, tusb_error_t *p_error); +tusb_error_t osal_mutex_release(osal_mutex_handle_t mutex_hdl); +void osal_mutex_reset(osal_mutex_handle_t mutex_hdl); //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+ diff --git a/tinyusb/osal/osal_none.h b/tinyusb/osal/osal_none.h index 936513d1b..5090d14f5 100644 --- a/tinyusb/osal/osal_none.h +++ b/tinyusb/osal/osal_none.h @@ -166,23 +166,23 @@ typedef osal_semaphore_t * osal_semaphore_handle_t; #define OSAL_SEM_REF(name)\ &name -static inline osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * const p_sem) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; -static inline osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * const p_sem) +static inline osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * p_sem) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; +static inline osal_semaphore_handle_t osal_semaphore_create(osal_semaphore_t * p_sem) { - (*p_sem) = 0; + (*p_sem) = 0; // TODO consider to have initial count parameter return (osal_semaphore_handle_t) p_sem; } -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) +static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t sem_hdl) ATTR_ALWAYS_INLINE; +static inline tusb_error_t osal_semaphore_post(osal_semaphore_handle_t sem_hdl) { (*sem_hdl)++; return TUSB_ERROR_NONE; } -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) +static inline void osal_semaphore_reset(osal_semaphore_handle_t sem_hdl) ATTR_ALWAYS_INLINE; +static inline void osal_semaphore_reset(osal_semaphore_handle_t sem_hdl) { (*sem_hdl) = 0; } @@ -202,6 +202,41 @@ static inline void osal_semaphore_reset(osal_semaphore_handle_t const sem_hdl) }\ }while(0) +//--------------------------------------------------------------------+ +// MUTEX API (priority inheritance) +//--------------------------------------------------------------------+ +typedef osal_semaphore_t osal_mutex_t; +typedef osal_semaphore_handle_t osal_mutex_handle_t; + +#define OSAL_MUTEX_DEF(name)\ + osal_mutex_t name + +#define OSAL_MUTEX_REF(name)\ + &name + +static inline osal_mutex_handle_t osal_mutex_create(osal_mutex_t * p_mutex) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; +static inline osal_mutex_handle_t osal_mutex_create(osal_mutex_t * p_mutex) +{ + (*p_mutex) = 1; + return (osal_mutex_handle_t) p_mutex; +} + +static inline tusb_error_t osal_mutex_release(osal_mutex_handle_t mutex_hdl) ATTR_ALWAYS_INLINE; +static inline tusb_error_t osal_mutex_release(osal_mutex_handle_t mutex_hdl) +{ + (*mutex_hdl) = 1; // mutex is a binary semaphore + + return TUSB_ERROR_NONE; +} + +static inline void osal_mutex_reset(osal_mutex_handle_t mutex_hdl) ATTR_ALWAYS_INLINE; +static inline void osal_mutex_reset(osal_mutex_handle_t mutex_hdl) +{ + (*mutex_hdl) = 1; +} + +#define osal_mutex_wait osal_semaphore_wait + //--------------------------------------------------------------------+ // QUEUE API //--------------------------------------------------------------------+