diff --git a/CMakeLists.txt b/CMakeLists.txt index a44c0dac..9bad52e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,14 +133,21 @@ elseif(ZEPHYR_BASE) set(CONFIG_CHERRYUSB_OSAL "zephyr") include(${CMAKE_CURRENT_LIST_DIR}/cherryusb.cmake) + if (CONFIG_SHELL) + list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/zephyr/usb_cmd.c) + endif () + zephyr_library() if(cherryusb_incs) zephyr_include_directories(${cherryusb_incs}) endif() - zephyr_include_directories(${cherryusb_incs}) if(cherryusb_srcs) zephyr_library_sources(${cherryusb_srcs}) endif() + + if (CONFIG_CHERRYUSB_HOST) + zephyr_linker_sources(SECTIONS zephyr/usbh_class_info.ld) + endif() elseif(HPM_SDK_BASE) set(CONFIG_CHERRYUSB_DEVICE_CDC_ACM 1) set(CONFIG_CHERRYUSB_DEVICE_HID 1) diff --git a/osal/usb_osal_zephyr.c b/osal/usb_osal_zephyr.c index 92fcb253..a4ddfcb2 100644 --- a/osal/usb_osal_zephyr.c +++ b/osal/usb_osal_zephyr.c @@ -7,43 +7,71 @@ #include "usb_errno.h" #include "usb_config.h" #include "usb_log.h" -#include -#ifndef CONFIG_THREAD_CUSTOM_DATA -#error CONFIG_THREAD_CUSTOM_DATA must be enabled +#include +#if (KERNELVERSION >= 0x3020000) +#include +#else +#include #endif -struct k_thread_ext { - struct k_thread thread; - k_thread_stack_t *thread_stack; +struct release_thread_work { + struct k_work work; + usb_osal_thread_t thread; }; usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args) { - struct k_thread_ext *new_thread; + k_tid_t tid = NULL; + struct k_thread *thread = (struct k_thread *)k_aligned_alloc(8, sizeof(struct k_thread) + stack_size); + k_thread_stack_t *stack = (k_thread_stack_t *)thread; - new_thread = k_malloc(sizeof(struct k_thread_ext)); - new_thread->thread_stack = k_malloc(stack_size); - k_thread_create(&new_thread->thread, new_thread->thread_stack, stack_size, entry, args, NULL, NULL, prio, 0, K_NO_WAIT); - k_thread_custom_data_set((void *)new_thread); - k_thread_name_set(&new_thread->thread, name); + if (thread == NULL) { + USB_LOG_ERR("Create thread faild\r\n"); + return NULL; + } - return (usb_osal_thread_t)new_thread; + tid = k_thread_create(thread, (k_thread_stack_t *)&stack[sizeof(struct k_thread)], + stack_size, + (k_thread_entry_t)entry, + args, NULL, NULL, + prio, + 0, + K_NO_WAIT); + +#if defined(CONFIG_THREAD_NAME) + k_thread_name_set(tid, name); +#endif + + return (usb_osal_thread_t)tid; +} + +static void release_thread_handler(struct k_work *work) +{ + struct release_thread_work *release_work = (struct release_thread_work *)work; + k_free(release_work->thread); + k_work_cancel(work); + k_free(release_work); } void usb_osal_thread_delete(usb_osal_thread_t thread) { - struct k_thread_ext *new_thread; - + struct release_thread_work *release_work; if (thread == NULL) { - new_thread = (struct k_thread_ext *)k_thread_custom_data_get(); - } else { - new_thread = (struct k_thread_ext *)thread; +#if (KERNELVERSION >= 0x3070000) + thread = k_sched_current_thread_query(); +#else + thread = z_current_get(); +#endif + release_work = k_malloc(sizeof(struct release_thread_work)); + release_work->thread = thread; + k_work_init(&release_work->work, release_thread_handler); + k_work_submit(&release_work->work); + k_thread_abort(thread); + return; } - - k_thread_abort(&new_thread->thread); - k_free(new_thread->thread_stack); - k_free(new_thread); + k_thread_abort(thread); + k_free(thread); } usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) @@ -51,6 +79,10 @@ usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count) struct k_sem *sem; sem = k_malloc(sizeof(struct k_sem)); + if (sem == NULL) { + USB_LOG_ERR("Create semaphore faild\r\n"); + return NULL; + } k_sem_init(sem, initial_count, 1); return (usb_osal_sem_t)sem; @@ -90,6 +122,10 @@ usb_osal_mutex_t usb_osal_mutex_create(void) struct k_mutex *mutex; mutex = k_malloc(sizeof(struct k_mutex)); + if (mutex == NULL) { + USB_LOG_ERR("Create mutex faild\r\n"); + return NULL; + } k_mutex_init(mutex); return (usb_osal_mutex_t)mutex; @@ -116,9 +152,13 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs) char *buffer; msgq = k_malloc(sizeof(struct k_msgq)); - buffer = k_calloc(max_msgs, sizeof(uintptr_t)); - - k_msgq_init(msgq, buffer, sizeof(uintptr_t), max_msgs); + if (msgq == NULL) { + USB_LOG_ERR("Create message queue faild\r\n"); + return NULL; + } + if (k_msgq_alloc_init(msgq, sizeof(uintptr_t), max_msgs) != 0) { + return NULL; + } return (usb_osal_mq_t)msgq; } @@ -126,13 +166,10 @@ usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs) void usb_osal_mq_delete(usb_osal_mq_t mq) { struct k_msgq *msgq; - uintptr_t addr; msgq = (struct k_msgq *)mq; - while (k_msgq_get(msgq, &addr, K_NO_WAIT) != 0) { - break; - } + k_msgq_purge(msgq); k_free(msgq->buffer_start); k_free(msgq); } @@ -159,7 +196,11 @@ int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout) if (k_is_in_isr()) { return (k_msgq_get(msgq, addr, K_NO_WAIT) == 0) ? 0 : -USB_ERR_TIMEOUT; } else { - return (k_msgq_get(msgq, addr, K_FOREVER) == 0) ? 0 : -USB_ERR_TIMEOUT; + if (timeout == USB_OSAL_WAITING_FOREVER) { + return (k_msgq_get(msgq, addr, K_FOREVER) == 0) ? 0 : -USB_ERR_TIMEOUT; + } else { + return (k_msgq_get(msgq, addr, K_MSEC(timeout)) == 0) ? 0 : -USB_ERR_TIMEOUT; + } } } @@ -177,7 +218,17 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ (void)name; timer = k_malloc(sizeof(struct usb_osal_timer)); + if (timer == NULL) { + USB_LOG_ERR("Create timer faild\r\n"); + return NULL; + } + memset(timer, 0, sizeof(struct usb_osal_timer)); + timer->timer = k_malloc(sizeof(struct k_timer)); + if (timer->timer == NULL) { + USB_LOG_ERR("Create timer faild\r\n"); + return NULL; + } timer->handler = handler; timer->argument = argument; @@ -213,12 +264,12 @@ void usb_osal_timer_stop(struct usb_osal_timer *timer) size_t usb_osal_enter_critical_section(void) { - return arch_irq_lock(); + return irq_lock(); } void usb_osal_leave_critical_section(size_t flag) { - arch_irq_unlock(flag); + irq_unlock(flag); } void usb_osal_msleep(uint32_t delay) diff --git a/platform/README.md b/platform/README.md index d225b68e..639b9efe 100644 --- a/platform/README.md +++ b/platform/README.md @@ -31,6 +31,10 @@ lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl61 - filx support with usb host msc. +## Zephyr + +- shell support with lsusb + ## LVGL - lvgl indev support with usb host mouse and keyboard. support both LVGL8.x.x and LVGL9.x.x diff --git a/platform/zephyr/usb_cmd.c b/platform/zephyr/usb_cmd.c new file mode 100644 index 00000000..402b5741 --- /dev/null +++ b/platform/zephyr/usb_cmd.c @@ -0,0 +1,12 @@ +#include + +#if CONFIG_CHERRYUSB_HOST +#include "usbh_core.h" +static void shell_lsusb_handle(const struct shell *sh, size_t argc, char **argv) +{ + ARG_UNUSED(sh); + lsusb(argc, argv); +} + +SHELL_CMD_REGISTER(lsusb, NULL, "Usage: lsusb [options]...\r\n", shell_lsusb_handle); +#endif \ No newline at end of file diff --git a/zephyr/usbh_class_info.ld b/zephyr/usbh_class_info.ld new file mode 100644 index 00000000..88b53470 --- /dev/null +++ b/zephyr/usbh_class_info.ld @@ -0,0 +1,7 @@ +SECTION_DATA_PROLOGUE(usbh_class_info,,) +{ + . = ALIGN(4); + __usbh_class_info_start__ = .; + KEEP(*(.usbh_class_info)) + __usbh_class_info_end__ = .; +} GROUP_LINK_IN(ROMABLE_REGION) \ No newline at end of file