| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- /*
- * Copyright (c) 2025 Evlers
- *
- * 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.
- *
- * Change Logs:
- * Date Author Notes
- * 2025-01-01 Evlers first implementation
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include "esp_log_level.h"
- #include "esp_hosted_config.h"
- #include "esp_hosted_log.h"
- #include "os_wrapper.h"
- /* Wi-Fi headers are reused at ESP-Hosted */
- #include "esp_wifi_crypto_types.h"
- // #include "esp_private/wifi_os_adapter.h"
- #ifdef CONFIG_ESP_SDIO_HOST_INTERFACE
- #include "sdio_wrapper.h"
- #endif
- #ifdef CONFIG_ESP_SPI_HOST_INTERFACE
- #include "spi_wrapper.h"
- #endif
- #ifdef CONFIG_ESP_SPI_HD_HOST_INTERFACE
- #include "spi_hd_wrapper.h"
- #endif
- #ifdef CONFIG_ESP_UART_HOST_INTERFACE
- #include "uart_wrapper.h"
- #endif
- DEFINE_LOG_TAG(os_wrapper_esp);
- struct hosted_config_t g_h = HOSTED_CONFIG_INIT_DEFAULT();
- /* -------- Memory ---------- */
- void *hosted_memcpy(void* dest, const void* src, uint32_t size)
- {
- if (size && (!dest || !src)) {
- if (!dest)
- ESP_LOGE(TAG, "%s:%u dest is NULL\n", __func__, __LINE__);
- if (!src)
- ESP_LOGE(TAG, "%s:%u dest is NULL\n", __func__, __LINE__);
- assert(dest);
- assert(src);
- return NULL;
- }
- return memcpy(dest, src, size);
- }
- void *hosted_memset(void* buf, int val, size_t len)
- {
- return memset(buf, val, len);
- }
- void *hosted_malloc(size_t size)
- {
- return rt_malloc(size);
- }
- void* hosted_calloc(size_t blk_no, size_t size)
- {
- return rt_calloc(blk_no, size);
- }
- void hosted_free(void* ptr)
- {
- rt_free(ptr);
- }
- void *hosted_realloc(void *mem, size_t newsize)
- {
- void *p = NULL;
- if (newsize == 0) {
- HOSTED_FREE(mem);
- return NULL;
- }
- p = hosted_malloc(newsize);
- if (p) {
- /* zero the memory */
- if (mem != NULL) {
- hosted_memcpy(p, mem, newsize);
- HOSTED_FREE(mem);
- }
- }
- return p;
- }
- void *hosted_malloc_align(size_t size, size_t align)
- {
- return rt_malloc_align(size, align);
- }
- void hosted_free_align(void* ptr)
- {
- rt_free_align(ptr);
- }
- void hosted_init_hook(void)
- {
- /* This is hook to initialize port specific contexts, if any */
- }
- /* -------- Threads ---------- */
- void *hosted_thread_create(char *tname, uint32_t tprio, uint32_t tstack_size, void (*start_routine)(void const *), void *sr_arg)
- {
- if (!start_routine) {
- ESP_LOGE(TAG, "start_routine is mandatory for thread create\n");
- return NULL;
- }
- thread_handle_t thread = rt_thread_create(tname, (void (*)(void *))start_routine, sr_arg, tstack_size, tprio, 10);
- if (!thread) {
- ESP_LOGE(TAG, "Failed to allocate thread handle");
- return NULL;
- }
- if (rt_thread_startup(thread) != RT_EOK) {
- ESP_LOGE(TAG, "Failed to create ctrl path task");
- rt_thread_delete(thread);
- return NULL;
- }
- return thread;
- }
- int hosted_thread_cancel(void *thread_handle)
- {
- return rt_thread_suspend(thread_handle);
- }
- /* -------- Sleeps -------------- */
- unsigned int hosted_msleep(unsigned int mseconds)
- {
- rt_thread_mdelay(mseconds);
- return 0;
- }
- unsigned int hosted_usleep(unsigned int useconds)
- {
- rt_thread_delay(useconds);
- return 0;
- }
- unsigned int hosted_sleep(unsigned int seconds)
- {
- return hosted_msleep(seconds * 1000UL);
- }
- /* Non sleepable delays - BLOCKING dead wait */
- unsigned int hosted_for_loop_delay(unsigned int number)
- {
- volatile int idx = 0;
- for (idx=0; idx<100*number; idx++) {
- }
- return 0;
- }
- /* -------- Queue --------------- */
- void * hosted_create_queue(uint32_t qnum_elem, uint32_t qitem_size)
- {
- return rt_mq_create("esp-hosted", qitem_size, qnum_elem, RT_IPC_FLAG_PRIO);
- }
- int hosted_queue_item(void * queue_handle, void *item, int timeout)
- {
- queue_handle_t mq = queue_handle;
- return rt_mq_send_wait((queue_handle_t)queue_handle, item, mq->msg_size, rt_tick_from_millisecond(timeout) * 1000);
- }
- int hosted_dequeue_item(void * queue_handle, void *item, int timeout)
- {
- queue_handle_t mq = queue_handle;
- return (rt_mq_recv(mq, item, mq->msg_size, rt_tick_from_millisecond(timeout) * 1000) <= 0) ? RET_FAIL_TIMEOUT : RET_OK;
- }
- int hosted_queue_msg_waiting(void * queue_handle)
- {
- return RET_FAIL;
- }
- int hosted_destroy_queue(void * queue_handle)
- {
- return rt_mq_delete((queue_handle_t)queue_handle);
- }
- int hosted_reset_queue(void * queue_handle)
- {
- return rt_mq_control((queue_handle_t)queue_handle, RT_IPC_CMD_RESET, NULL);
- }
- /* -------- Mutex --------------- */
- void * hosted_create_mutex(void)
- {
- return rt_mutex_create("esp_hosted", RT_IPC_FLAG_PRIO);
- }
- int hosted_unlock_mutex(void * mutex_handle)
- {
- return rt_mutex_release((mutex_handle_t)mutex_handle);
- }
- int hosted_lock_mutex(void * mutex_handle, int timeout)
- {
- return rt_mutex_take((mutex_handle_t)mutex_handle, rt_tick_from_millisecond(timeout) * 1000);
- }
- int hosted_destroy_mutex(void * mutex_handle)
- {
- return rt_mutex_delete((mutex_handle_t)mutex_handle);
- }
- /* -------- Semaphores ---------- */
- void * hosted_create_semaphore(int maxCount)
- {
- semaphore_handle_t semaphore_handle = rt_sem_create("esp-hosted", 0, RT_IPC_FLAG_PRIO);
- if (semaphore_handle != NULL)
- {
- rt_sem_release(semaphore_handle);
- }
- return semaphore_handle;
- }
- int hosted_post_semaphore(void * semaphore_handle)
- {
- return rt_sem_release((semaphore_handle_t)semaphore_handle);
- }
- FAST_RAM_ATTR int hosted_post_semaphore_from_isr(void * semaphore_handle)
- {
- return rt_sem_release((semaphore_handle_t)semaphore_handle);
- }
- int hosted_get_semaphore(void * semaphore_handle, int timeout)
- {
- return rt_sem_take((semaphore_handle_t)semaphore_handle, rt_tick_from_millisecond(timeout) * 1000);
- }
- int hosted_destroy_semaphore(void * semaphore_handle)
- {
- return rt_sem_delete((semaphore_handle_t)semaphore_handle);
- }
- #ifdef CONFIG_USE_MEMPOOL
- static void * hosted_create_spinlock(void)
- {
- RT_DEFINE_SPINLOCK(spin_dummy);
- spinlock_handle_t *spin_id = NULL;
- spin_id = (spinlock_handle_t*)hosted_malloc(
- sizeof(spinlock_handle_t));
- if (!spin_id) {
- ESP_LOGE(TAG, "mut allocation failed\n");
- return NULL;
- }
- spin_id->lock = spin_dummy;
- rt_spin_lock_init(spin_id);
- return spin_id;
- }
- void* hosted_create_lock_mempool(void)
- {
- return hosted_create_spinlock();
- }
- void hosted_lock_mempool(void *lock_handle)
- {
- assert(lock_handle);
- rt_spin_lock((spinlock_handle_t)lock_handle);
- }
- void hosted_unlock_mempool(void *lock_handle)
- {
- assert(lock_handle);
- rt_spin_unlock((spinlock_handle_t)lock_handle);
- }
- #endif
- /* -------- Timers ---------- */
- void *hosted_timer_start(int duration, int type, void (*timeout_handler)(void *), void *arg)
- {
- rt_timer_t timer_handle = rt_timer_create("esp-hosted", (void (*)(void *))timeout_handler, arg,
- rt_tick_from_millisecond(duration) * 1000,
- type);
- if (timer_handle == NULL)
- {
- ESP_LOGE(TAG, "Failed to allocate timer handle");
- return NULL;
- }
- if (rt_timer_start(timer_handle) != RT_EOK)
- {
- ESP_LOGE(TAG, "Failed to start timer, destroying timer");
- rt_timer_delete(timer_handle);
- return NULL;
- }
- return timer_handle;
- }
- int hosted_timer_stop(void *timer_handle)
- {
- if (!timer_handle) {
- ESP_LOGE(TAG, "Uninitialized timer handle");
- return ESP_FAIL;
- }
- if (rt_timer_stop(timer_handle) != RT_EOK)
- {
- ESP_LOGE(TAG, "Unable to stop timer");
- return ESP_FAIL;
- }
- if (rt_timer_delete(timer_handle) != RT_EOK)
- {
- ESP_LOGE(TAG, "Unable to delete timer");
- return ESP_FAIL;
- }
- return ESP_OK;
- }
- /* GPIO */
- int hosted_config_gpio(void* gpio_port, uint32_t gpio_num, uint32_t mode)
- {
- rt_pin_mode(gpio_num, mode);
- return 0;
- }
- int hosted_config_gpio_as_interrupt(void* gpio_port, uint32_t gpio_num, uint32_t intr_type, void (*new_gpio_isr_handler)(void* arg))
- {
- rt_pin_mode(gpio_num, PIN_MODE_INPUT);
- rt_pin_attach_irq(gpio_num, intr_type, new_gpio_isr_handler, NULL);
- rt_pin_irq_enable(gpio_num, RT_TRUE);
- return 0;
- }
- int hosted_read_gpio(void*gpio_port, uint32_t gpio_num)
- {
- return rt_pin_read(gpio_num);
- }
- int hosted_write_gpio(void* gpio_port, uint32_t gpio_num, uint32_t value)
- {
- rt_pin_write(gpio_num, value);
- return 0;
- }
- rt_weak int hosted_wifi_event_post(int32_t event_id, void* event_data, size_t event_data_size, int32_t ticks_to_wait)
- {
- ESP_LOGI(TAG, "wifi event: %d", event_id);
- return 0;
- }
- void hosted_log_write(int level, const char *tag, const char *format, ...)
- {
- va_list args;
- rt_size_t length = 0;
- static char rt_log_buf[RT_CONSOLEBUF_SIZE];
- esp_log_level_t level_for_tag = esp_log_level_get(tag);
- if ((ESP_LOG_NONE != level_for_tag) && (level <= level_for_tag))
- {
- va_start(args, format);
- length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, format, args);
- if (length > RT_CONSOLEBUF_SIZE - 1)
- {
- length = RT_CONSOLEBUF_SIZE - 1;
- }
- #ifdef RT_USING_ULOG
- #include "rtdbg.h"
- #undef LOG_TAG
- #define LOG_TAG tag
- switch (level)
- {
- default: LOG_D("%.*s", length, rt_log_buf); break;
- case ESP_LOG_INFO: LOG_I("%.*s", length, rt_log_buf); break;
- case ESP_LOG_WARN: LOG_W("%.*s", length, rt_log_buf); break;
- case ESP_LOG_ERROR: LOG_E("%.*s", length, rt_log_buf); break;
- }
- #undef LOG_TAG
- #else
- char level_char;
- switch (level)
- {
- case ESP_LOG_INFO: level_char = 'I'; break;
- case ESP_LOG_WARN: level_char = 'W'; break;
- case ESP_LOG_ERROR: level_char = 'E'; break;
- default: level_char = 'D'; break;
- }
- rt_kprintf("[%c/%s] %.*s\n", level_char, tag, length, rt_log_buf);
- #endif /* RT_USING_ULOG */
- va_end(args);
- }
- }
- /* newlib hooks */
- hosted_osi_funcs_t g_hosted_osi_funcs = {
- ._h_memcpy = hosted_memcpy ,
- ._h_memset = hosted_memset ,
- ._h_malloc = hosted_malloc ,
- ._h_calloc = hosted_calloc ,
- ._h_free = hosted_free ,
- ._h_realloc = hosted_realloc ,
- ._h_malloc_align = hosted_malloc_align ,
- ._h_free_align = hosted_free_align ,
- ._h_thread_create = hosted_thread_create ,
- ._h_thread_cancel = hosted_thread_cancel ,
- ._h_msleep = hosted_msleep ,
- ._h_usleep = hosted_usleep ,
- ._h_sleep = hosted_sleep ,
- ._h_blocking_delay = hosted_for_loop_delay ,
- ._h_queue_item = hosted_queue_item ,
- ._h_create_queue = hosted_create_queue ,
- ._h_queue_msg_waiting = hosted_queue_msg_waiting ,
- ._h_dequeue_item = hosted_dequeue_item ,
- ._h_destroy_queue = hosted_destroy_queue ,
- ._h_reset_queue = hosted_reset_queue ,
- ._h_unlock_mutex = hosted_unlock_mutex ,
- ._h_create_mutex = hosted_create_mutex ,
- ._h_lock_mutex = hosted_lock_mutex ,
- ._h_destroy_mutex = hosted_destroy_mutex ,
- ._h_post_semaphore = hosted_post_semaphore ,
- ._h_post_semaphore_from_isr = hosted_post_semaphore_from_isr ,
- ._h_create_semaphore = hosted_create_semaphore ,
- ._h_get_semaphore = hosted_get_semaphore ,
- ._h_destroy_semaphore = hosted_destroy_semaphore ,
- ._h_timer_stop = hosted_timer_stop ,
- ._h_timer_start = hosted_timer_start ,
- #ifdef CONFIG_USE_MEMPOOL
- ._h_create_lock_mempool = hosted_create_lock_mempool ,
- ._h_lock_mempool = hosted_lock_mempool ,
- ._h_unlock_mempool = hosted_unlock_mempool ,
- #endif
- ._h_config_gpio = hosted_config_gpio ,
- ._h_config_gpio_as_interrupt = hosted_config_gpio_as_interrupt,
- ._h_read_gpio = hosted_read_gpio ,
- ._h_write_gpio = hosted_write_gpio ,
- #ifdef CONFIG_ESP_SPI_HOST_INTERFACE
- ._h_bus_init = hosted_spi_init ,
- ._h_do_bus_transfer = hosted_do_spi_transfer ,
- #endif
- ._h_event_wifi_post = hosted_wifi_event_post ,
- ._h_printf = hosted_log_write ,
- ._h_hosted_init_hook = hosted_init_hook ,
- #ifdef CONFIG_ESP_SDIO_HOST_INTERFACE
- ._h_bus_init = hosted_sdio_init ,
- ._h_sdio_card_init = hosted_sdio_card_init ,
- ._h_sdio_read_reg = hosted_sdio_read_reg ,
- ._h_sdio_write_reg = hosted_sdio_write_reg ,
- ._h_sdio_read_block = hosted_sdio_read_block ,
- ._h_sdio_write_block = hosted_sdio_write_block ,
- ._h_sdio_wait_slave_intr = hosted_sdio_wait_slave_intr ,
- #endif
- #ifdef CONFIG_ESP_SPI_HD_HOST_INTERFACE
- ._h_bus_init = hosted_spi_hd_init ,
- ._h_spi_hd_read_reg = hosted_spi_hd_read_reg ,
- ._h_spi_hd_write_reg = hosted_spi_hd_write_reg ,
- ._h_spi_hd_read_dma = hosted_spi_hd_read_dma ,
- ._h_spi_hd_write_dma = hosted_spi_hd_write_dma ,
- ._h_spi_hd_set_data_lines = hosted_spi_hd_set_data_lines ,
- ._h_spi_hd_send_cmd9 = hosted_spi_hd_send_cmd9 ,
- #endif
- #ifdef CONFIG_ESP_UART_HOST_INTERFACE
- ._h_bus_init = hosted_uart_init ,
- ._h_uart_read = hosted_uart_read ,
- ._h_uart_write = hosted_uart_write ,
- ._h_uart_wait_rx_data = hosted_wait_rx_data ,
- #endif
- };
|