347 lines
7.9 KiB
C
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);
|
|
}
|