Files
kunlun/import/lwip/ports/sys_arch.c
2024-09-28 14:24:04 +08:00

347 lines
7.9 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim inlcude */
#include "os_event_api.h"
#include "os_task_api.h"
#include "os_lock_api.h"
#include "os_mem_api.h"
#include "os_utils_api.h"
/* common inlcude */
#include "iot_config_api.h"
#include "iot_mem_pool_api.h"
#include "iot_queue_api.h"
/* lwip internal includes */
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/tcpip.h"
/* internal includes */
#include "netif/netif_plc.h"
#include "netif/netif_eth.h"
#include "netif/netif_msvc_pcap.h"
#include "netif/netif_uart.h"
typedef struct _iot_mbox_msg {
/* link of the message queue */
iot_msg_entry_t msg;
/* message data */
void *data;
} iot_mbox_msg_t;
typedef struct _iot_mbox {
/* message queue */
iot_msg_queue_t q;
/* free message pool */
iot_mem_pool_t *msg_p;
/* event for free message pool not empty */
os_event_h not_empty;
/* event for message queue not empty */
os_event_h has_msg;
} iot_mbox_t;
/*----------------------------------------------------------------------------*/
/* Threads */
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function,
void *arg, int stacksize, int prio)
{
(void)prio;
return os_create_task_ext(function, arg, OS_TASK_PRIO_7, stacksize/4, name);
}
/*----------------------------------------------------------------------------*/
/* Mailbox */
err_t sys_mbox_new(sys_mbox_t *mb, int size)
{
iot_mbox_t *m_box = NULL;
if (size > 255) {
goto err;
}
m_box = (iot_mbox_t *)os_mem_malloc(IOT_LWIP_MID, sizeof(iot_mbox_t));
if (m_box == NULL) {
goto err;
}
if (iot_mem_pool_new(IOT_LWIP_MID, size,
sizeof(iot_mbox_msg_t), &m_box->msg_p, 1)) {
goto err;
}
m_box->not_empty = os_create_event(IOT_LWIP_MID, 1);
if (m_box->not_empty == NULL) {
goto err;
}
m_box->has_msg = os_create_event(IOT_LWIP_MID, 0);
if (m_box->has_msg == NULL) {
goto err;
}
if (iot_msg_queue_init(&m_box->q)) {
/* must be the last error */
goto err;
}
*mb = m_box;
return ERR_OK;
err:
if (m_box) {
if (m_box->has_msg) {
os_delete_event(m_box->has_msg);
}
if (m_box->not_empty) {
os_delete_event(m_box->not_empty);
}
if (m_box->msg_p) {
iot_mem_pool_destroy(m_box->msg_p);
}
os_mem_free(m_box);
}
*mb = NULL;
return -1;
}
void sys_mbox_free(sys_mbox_t *mb)
{
iot_mbox_t *m_box;
if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
m_box = *mb;
iot_msg_queue_deinit(&m_box->q);
if (m_box->has_msg) {
os_delete_event(m_box->has_msg);
}
if (m_box->not_empty) {
os_delete_event(m_box->not_empty);
}
if (m_box->msg_p) {
iot_mem_pool_destroy(m_box->msg_p);
}
os_mem_free(m_box);
*mb = NULL;
}
}
err_t sys_mbox_trypost(sys_mbox_t *mb, void *msg)
{
iot_mbox_t *m_box = *mb;
iot_mbox_msg_t *box_msg;
box_msg = iot_mem_pool_alloc(m_box->msg_p);
if (!box_msg) {
return -1;
}
iot_msg_entry_init(&box_msg->msg);
box_msg->data = msg;
iot_msg_queue_put(&m_box->q, &box_msg->msg);
os_set_event(m_box->has_msg);
return 0;
}
void sys_mbox_post(sys_mbox_t *mb, void *msg)
{
iot_mbox_t *m_box = *mb;
while (sys_mbox_trypost(mb, msg)) {
os_wait_event(m_box->not_empty, MAX_TIME);
}
}
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mb, void **msg)
{
iot_mbox_t *m_box = *mb;
iot_mbox_msg_t *box_msg;
box_msg = (iot_mbox_msg_t *)iot_msg_queue_get(&m_box->q);
if (box_msg) {
*msg = box_msg->data;
iot_mem_pool_free(m_box->msg_p, box_msg);
os_set_event(m_box->not_empty);
return 0;
} else {
*msg = NULL;
return SYS_MBOX_EMPTY;
}
}
u32_t sys_arch_mbox_fetch(sys_mbox_t *mb, void **msg, u32_t timeout)
{
uint32_t ts = 0, ts_to_wait = 0, tmp;
iot_mbox_t *m_box = *mb;
if (timeout) {
if (timeout == MAX_TIME) {
timeout--;
}
ts_to_wait = timeout;
ts = os_boot_time32();
}
while (sys_arch_mbox_tryfetch(mb, msg)) {
if (timeout == 0) {
os_wait_event(m_box->has_msg, MAX_TIME);
} else {
tmp= os_boot_time32() - ts;
if (tmp >= ts_to_wait)
return SYS_ARCH_TIMEOUT;
ts_to_wait -= tmp;
os_wait_event(m_box->has_msg, ts_to_wait);
}
}
return 0;
}
/*----------------------------------------------------------------------------*/
/* Semaphore */
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
{
IOT_ASSERT(count < 2);
*sem = os_create_event(IOT_LWIP_MID, !!count);
if (*sem == NULL) {
return -1;
}
return 0;
}
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
u32_t time_needed;
if (timeout == 0) {
timeout = MAX_TIME;
}
time_needed = os_boot_time32();
if (!os_wait_event(*sem, timeout)) {
time_needed = SYS_ARCH_TIMEOUT;
} else {
time_needed = os_boot_time32() - time_needed;
}
return time_needed;
}
void sys_sem_signal(sys_sem_t *sem)
{
os_set_event(*sem);
}
void sys_sem_free(sys_sem_t *sem)
{
os_delete_event(*sem);
*sem = NULL;
}
/*----------------------------------------------------------------------------*/
/* Mutex */
err_t sys_mutex_new(sys_mutex_t *mutex)
{
*mutex = os_create_mutex(IOT_LWIP_MID);
if (*mutex != NULL) {
return 0;
} else {
return -1;
}
}
void sys_mutex_lock(sys_mutex_t *mutex)
{
os_acquire_mutex(*mutex);
}
void sys_mutex_unlock(sys_mutex_t *mutex)
{
os_release_mutex(*mutex);
}
void sys_mutex_free(sys_mutex_t *mutex)
{
os_delete_mutex(*mutex);
*mutex = NULL;
}
/*----------------------------------------------------------------------------*/
/* Time */
u32_t sys_now(void)
{
return os_boot_time32();
}
u32_t sys_jiffies(void)
{
/* TBD. to use a more precision timestamp later */
return os_boot_time32();
}
/*----------------------------------------------------------------------------*/
/* Init */
static os_mutex_h g_critical_mutex = NULL;
void sys_init(void)
{
g_critical_mutex = os_create_mutex(IOT_LWIP_MID);
}
void iot_lwip_init_done(void *arg)
{
sys_sem_t *init_sem = arg;
/* initialize network interfaces */
/* plc interface */
netif_plc_init();
/* uart interface */
netif_uart_init();
/* eth interface */
netif_eth_init();
/* msvc pcap interface */
netif_msvc_eth_init();
iot_printf("%s\n", __FUNCTION__);
sys_sem_signal(init_sem);
}
void iot_lwip_init()
{
#if IOT_LWIP_SUPPORT
err_t err;
sys_sem_t init_sem;
err = sys_sem_new(&init_sem, 0);
LWIP_ASSERT("failed to create init_sem", err == ERR_OK);
tcpip_init(iot_lwip_init_done, &init_sem);
sys_sem_wait(&init_sem);
sys_sem_free(&init_sem);
#endif /* IOT_LWIP_SUPPORT */
}
sys_prot_t sys_arch_protect(void)
{
os_acquire_mutex(g_critical_mutex);
return 1;
}
void sys_arch_unprotect(sys_prot_t pval)
{
(void)pval;
os_release_mutex(g_critical_mutex);
}