123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2020-06-24 thread-liu first version
- */
- #include <board.h>
- #ifdef BSP_USING_OPENAMP
- #include <finsh.h>
- #include <drv_openamp.h>
- #include <openamp.h>
- #include <virt_uart.h>
- #include <openamp/rpmsg_virtio.h>
- //#define DRV_DEBUG
- #define LOG_TAG "drv.openamp"
- #include <drv_log.h>
- IPCC_HandleTypeDef hipcc;
- static VIRT_UART_HandleTypeDef huart0;
- static rt_uint8_t rx_buffer[MAX_BUFFER_SIZE];
- static rt_uint8_t tx_buffer[MAX_BUFFER_SIZE];
- struct rthw_openamp
- {
- struct rt_device parent;
- struct rt_openamp serial;
- struct rt_semaphore sema;
- };
- static struct rthw_openamp dev_openamp;
- void IPCC_RX1_IRQHandler(void)
- {
- rt_interrupt_enter();
- HAL_IPCC_RX_IRQHandler(&hipcc);
- rt_interrupt_leave();
- }
- void IPCC_TX1_IRQHandler(void)
- {
- rt_interrupt_enter();
- HAL_IPCC_TX_IRQHandler(&hipcc);
- rt_interrupt_leave();
- }
- void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart)
- {
- rt_uint16_t rx_size = 0, i = 0;
- rt_size_t count, size, offset;
- rt_uint8_t *buf = RT_NULL;
- struct rthw_openamp *device;
- device = (struct rthw_openamp *)rt_device_find("openamp");
- RT_ASSERT(device != RT_NULL);
- buf = device->serial.rbuf;
- count = device->serial.rbuf_count;
- size = device->serial.rbuf_size;
- offset = device->serial.rbuf_start + count;
- rt_sem_take(&device->sema, RT_WAITING_FOREVER);
- rx_size = (huart->RxXferSize < MAX_BUFFER_SIZE) ? huart->RxXferSize : MAX_BUFFER_SIZE - 1;
- if (count < size)
- {
- if (offset >= size)
- {
- offset -= size;
- }
- for (i = 0; i < rx_size; i++)
- {
- buf[offset++] = huart->pRxBuffPtr[i];
- count++;
- }
- }
- device->serial.rbuf_count = count;
- rt_sem_release(&device->sema);
- }
- static rt_err_t _init(struct rt_device *dev)
- {
- struct rthw_openamp *device;
- device = (struct rthw_openamp *)dev;
- RT_ASSERT(device != RT_NULL);
- device->serial.rbuf_start = 0;
- device->serial.rbuf_count = 0;
- device->serial.tbuf_start = 0;
- device->serial.tbuf_count = 0;
- device->serial.rbuf_size = MAX_BUFFER_SIZE;
- device->serial.tbuf_size = MAX_BUFFER_SIZE;
- device->serial.rbuf = rx_buffer;
- device->serial.tbuf = tx_buffer;
- if (rt_sem_init(&device->sema, "openamplock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
- {
- return RT_ERROR;
- }
- return RT_EOK;
- }
- static rt_size_t _read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
- {
- rt_size_t count, rbsize, offset;
- rt_uint8_t *buf = RT_NULL;
- rt_uint8_t *pBuffer = RT_NULL;
- rt_uint16_t i = 0;
- struct rthw_openamp *device;
- device = (struct rthw_openamp *)dev;
- RT_ASSERT(device != RT_NULL);
- pBuffer = (unsigned char*)buffer;
- count = device->serial.rbuf_count;
- buf = device->serial.rbuf;
- if (count == 0)
- {
- return -RT_ERROR;
- }
- rt_sem_take(&device->sema, RT_WAITING_FOREVER);
- if (count >= size)
- {
- count = size;
- }
- offset = device->serial.rbuf_start;
- rbsize = device->serial.rbuf_size;
- for (i = 0; i < count; i++)
- {
- *pBuffer++ = buf[offset++];
- if (offset > rbsize)
- {
- offset = 0;
- }
- }
- device->serial.rbuf_start = offset;
- device->serial.rbuf_count -= count;
- rt_sem_release(&device->sema);
- return count;
- }
- static rt_size_t _write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
- {
- rt_err_t result = VIRT_UART_OK;
- struct rthw_openamp *device;
- device = (struct rthw_openamp *)dev;
- RT_ASSERT(device != RT_NULL);
- rt_sem_take(&device->sema, RT_WAITING_FOREVER);
- result = VIRT_UART_Transmit(&huart0, (uint8_t *)buffer, size);
- rt_sem_release(&device->sema);
- if (result != VIRT_UART_OK)
- {
- return -RT_ERROR;
- }
- return size;
- }
- static rt_err_t rt_hw_openamp_register(struct rthw_openamp *openamp, const char *name, rt_uint32_t flag, void *data)
- {
- struct rt_device *device;
- RT_ASSERT(openamp != RT_NULL);
- device = &(openamp->parent);
- device->type = RT_Device_Class_Char;
- device->rx_indicate = RT_NULL;
- device->tx_complete = RT_NULL;
- device->init = _init;
- device->open = RT_NULL;
- device->close = RT_NULL;
- device->read = _read;
- device->write = _write;
- device->control = RT_NULL;
- device->user_data = data;
- /* register a character device */
- return rt_device_register(device, name, flag);
- }
- static int openamp_init(void)
- {
- extern int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb);
- /* IPCC init */
- hipcc.Instance = IPCC;
- if (HAL_IPCC_Init(&hipcc) != HAL_OK)
- {
- return RT_ERROR;
- }
- /* openamp slave device */
- MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
- if (VIRT_UART_Init(&huart0) != VIRT_UART_OK)
- {
- return RT_ERROR;
- }
- if (VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK)
- {
- return RT_ERROR;
- }
- return RT_EOK;
- }
- int rt_hw_openamp_init(void)
- {
- openamp_init();
- rt_hw_openamp_register(&dev_openamp, "openamp", 0, NULL);
- if (RT_CONSOLE_DEVICE_NAME == "openamp")
- {
- rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
- }
- return RT_EOK;
- }
- INIT_PREV_EXPORT(rt_hw_openamp_init);
- static void openamp_thread_entry(void *parameter)
- {
- rt_size_t size = 0;
- struct rthw_openamp *device = RT_NULL;
- device = (struct rthw_openamp *)rt_device_find("openamp");
- RT_ASSERT(device != RT_NULL);
- for (;;)
- {
- OPENAMP_check_for_message();
- size = device->serial.rbuf_count;
- if (size > 0)
- {
- if (device->parent.rx_indicate != RT_NULL)
- {
- device->parent.rx_indicate(&device->parent, size);
- }
- }
- rt_thread_mdelay(1);
- }
- }
- static int creat_openamp_thread(void)
- {
- rt_thread_t tid = RT_NULL;
- tid = rt_thread_create("OpenAMP",
- openamp_thread_entry,
- RT_NULL,
- OPENAMP_THREAD_STACK_SIZE,
- OPENAMP_THREAD_PRIORITY,
- OPENAMP_THREAD_TIMESLICE);
- if (tid == RT_NULL)
- {
- LOG_E("openamp thread create failed!");
- return RT_ERROR;
- }
- rt_thread_startup(tid);
- return RT_EOK;
- }
- INIT_APP_EXPORT(creat_openamp_thread);
- #ifdef FINSH_USING_MSH
- static int console(int argc, char **argv)
- {
- rt_err_t result = RT_EOK;
- if (argc > 1)
- {
- if (!strcmp(argv[1], "set"))
- {
- rt_kprintf("console change to %s\n", argv[2]);
- rt_console_set_device(argv[2]);
- finsh_set_device(argv[2]);
- }
- else
- {
- rt_kprintf("Unknown command. Please enter 'console' for help\n");
- result = -RT_ERROR;
- }
- }
- else
- {
- rt_kprintf("Usage: \n");
- rt_kprintf("console set <name> - change console by name\n");
- result = -RT_ERROR;
- }
- return result;
- }
- MSH_CMD_EXPORT(console, set console name);
- #endif /* FINSH_USING_MSH */
- #endif
|