初始提交
This commit is contained in:
260
common/plc_lib/src/iot_plc_lib.c
Normal file
260
common/plc_lib/src/iot_plc_lib.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/****************************************************************************
|
||||
|
||||
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.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
/* common includes */
|
||||
#include "iot_errno.h"
|
||||
#include "iot_module.h"
|
||||
#include "iot_config.h"
|
||||
#include "iot_utils.h"
|
||||
#include "iot_ipc.h"
|
||||
#include "iot_plc_api.h"
|
||||
#include "iot_dbglog_api.h"
|
||||
#include "iot_task.h"
|
||||
#include "iot_oem_api.h"
|
||||
|
||||
/* plc lib internal includes */
|
||||
#include "plc_lib_internal.h"
|
||||
|
||||
#ifndef PLC_LIB_STANDALONE_TASK
|
||||
#define PLC_LIB_STANDALONE_TASK 0
|
||||
#endif
|
||||
|
||||
#ifndef PLC_LIB_TASK_PRIO
|
||||
#define PLC_LIB_TASK_PRIO 7
|
||||
#endif
|
||||
|
||||
plc_lib_global_t *p_plc_lib = NULL;
|
||||
|
||||
static inline void plc_lib_handle_ipc_event(plc_lib_global_t *glb,
|
||||
iot_pkt_t *buf)
|
||||
{
|
||||
iot_pkt_t *tmp_pkt = NULL;
|
||||
iot_plc_msg_header_t *header = NULL;
|
||||
iot_plc_app_t *app = NULL;
|
||||
uint8_t index = 0;
|
||||
uint32_t buf_len = 0;
|
||||
|
||||
|
||||
/* as the message is delivered from internal plc stack, so skip security
|
||||
* check to improve efficient.
|
||||
*/
|
||||
buf_len = iot_pkt_block_len(buf, IOT_PKT_BLOCK_ALL);
|
||||
header = (iot_plc_msg_header_t *)iot_pkt_block_ptr(buf, IOT_PKT_BLOCK_DATA);
|
||||
|
||||
os_acquire_mutex(glb->lock);
|
||||
if (header->app_id == IOT_PLC_APP_ID_BCAST) {
|
||||
/* if it's a broadcast message, broadcast it to all apps */
|
||||
for (index = 0; index < PLC_LIB_APP_SUPP_MAX; index++) {
|
||||
if (p_plc_lib->app[index].app_id) {
|
||||
tmp_pkt = iot_pkt_alloc(buf_len, IOT_PLC_LIB_MID);
|
||||
if (tmp_pkt) {
|
||||
/* allocate a new pkt to for each app broadcasting */
|
||||
iot_pkt_cpy(tmp_pkt, buf);
|
||||
p_plc_lib->app[index].recv(
|
||||
p_plc_lib->app[index].param, tmp_pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the original packet */
|
||||
iot_pkt_free(buf);
|
||||
} else {
|
||||
app = plc_lib_find_app(header->app_id);
|
||||
if (app) {
|
||||
app->recv(app->param, buf);
|
||||
} else {
|
||||
iot_pkt_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
os_release_mutex(glb->lock);
|
||||
}
|
||||
|
||||
/* ipc callback to receive packet from plc stack */
|
||||
static void plc_lib_ipc_recv(void *param, iot_ipc_addr_t *addr,
|
||||
iot_pkt_t *pkt)
|
||||
{
|
||||
(void)param;
|
||||
(void)addr;
|
||||
|
||||
if (PLC_LIB_STANDALONE_TASK) {
|
||||
iot_task_msg_t *msg = iot_task_alloc_msg(p_plc_lib->task_h);
|
||||
plc_lib_msg_t *plc_msg = (plc_lib_msg_t *)msg;
|
||||
if (msg) {
|
||||
plc_msg->data = pkt;
|
||||
msg->id = PLC_LIB_MSG_IPC_EVENT;
|
||||
iot_task_queue_msg(p_plc_lib->task_h, msg, PLC_LIB_MSG_QUEUE_HP);
|
||||
} else {
|
||||
iot_pkt_free(pkt);
|
||||
IOT_ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
plc_lib_handle_ipc_event(p_plc_lib, pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/* plc lib internal msg handling function */
|
||||
static void plc_lib_handle_msg(iot_task_h task_h, iot_task_msg_t *msg)
|
||||
{
|
||||
plc_lib_msg_t *plc_msg = (plc_lib_msg_t *)msg;
|
||||
|
||||
switch (msg->id) {
|
||||
case PLC_LIB_MSG_IPC_EVENT:
|
||||
plc_lib_handle_ipc_event(p_plc_lib, plc_msg->data);
|
||||
break;
|
||||
default:
|
||||
IOT_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
iot_task_free_msg(task_h, msg);
|
||||
}
|
||||
|
||||
/* plc lib internal msg cancel function */
|
||||
static void plc_lib_handle_msg_cancel(iot_task_h task_h,
|
||||
iot_task_msg_t *msg)
|
||||
{
|
||||
plc_lib_msg_t *plc_msg = (plc_lib_msg_t *)msg;
|
||||
|
||||
switch (msg->id) {
|
||||
case PLC_LIB_MSG_IPC_EVENT:
|
||||
iot_pkt_free((iot_pkt_t *)plc_msg->data);
|
||||
break;
|
||||
default:
|
||||
IOT_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
iot_task_free_msg(task_h, msg);
|
||||
}
|
||||
|
||||
iot_plc_app_t *plc_lib_find_app(uint8_t app_id)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < PLC_LIB_APP_SUPP_MAX; i++) {
|
||||
if (p_plc_lib->app[i].app_id == app_id)
|
||||
return &p_plc_lib->app[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iot_plc_app_t *plc_lib_find_free_app()
|
||||
{
|
||||
uint8_t i;
|
||||
iot_plc_app_t *ret = NULL;
|
||||
|
||||
for (i = 0; i < PLC_LIB_APP_SUPP_MAX; i++) {
|
||||
if (p_plc_lib->app[i].app_id == 0) {
|
||||
ret = &p_plc_lib->app[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t iot_plc_lib_init(uint8_t proto)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
iot_ipc_client_t client;
|
||||
|
||||
if (p_plc_lib)
|
||||
goto out;
|
||||
|
||||
p_plc_lib = os_mem_malloc(IOT_PLC_LIB_MID, sizeof(*p_plc_lib));
|
||||
if (p_plc_lib == NULL) {
|
||||
ret = ERR_NOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
p_plc_lib->lock = os_create_mutex(IOT_PLC_LIB_MID);
|
||||
if (p_plc_lib->lock == NULL) {
|
||||
ret = ERR_NOMEM;
|
||||
goto err;
|
||||
}
|
||||
p_plc_lib->proto = proto;
|
||||
|
||||
os_mem_set(&p_plc_lib->task_cfg, 0, sizeof(p_plc_lib->task_cfg));
|
||||
if (PLC_LIB_STANDALONE_TASK) {
|
||||
/* create plc lib task */
|
||||
p_plc_lib->task_cfg.stack_size = 0;
|
||||
p_plc_lib->task_cfg.task_prio = PLC_LIB_TASK_PRIO;
|
||||
p_plc_lib->task_cfg.msg_size = sizeof(plc_lib_msg_t);
|
||||
p_plc_lib->task_cfg.msg_cnt = PLC_LIB_MSG_POOL_SIZE;
|
||||
p_plc_lib->task_cfg.queue_cnt = PLC_LIB_MSG_QUEUE_MAX_PRIO;
|
||||
p_plc_lib->task_cfg.queue_cfg[PLC_LIB_MSG_QUEUE_HP].quota = 0;
|
||||
p_plc_lib->task_cfg.msg_exe_func = plc_lib_handle_msg;
|
||||
p_plc_lib->task_cfg.msg_cancel_func = plc_lib_handle_msg_cancel;
|
||||
|
||||
p_plc_lib->task_h = iot_task_create(IOT_PLC_LIB_MID,
|
||||
&p_plc_lib->task_cfg);
|
||||
|
||||
if (p_plc_lib->task_h == NULL)
|
||||
goto err_task;
|
||||
}
|
||||
|
||||
/* register ipc to communicate with plc stack */
|
||||
client.addr.f_id = IOT_IPC_FID_PLC;
|
||||
client.addr.c_id = IOT_IPC_CID_PLC_LIB;
|
||||
client.recv = plc_lib_ipc_recv;
|
||||
client.param = p_plc_lib;
|
||||
p_plc_lib->ipc_h = iot_ipc_register_client(&client);
|
||||
if (p_plc_lib->ipc_h == NULL) {
|
||||
ret = ERR_NOMEM;
|
||||
goto err_ipc;
|
||||
}
|
||||
|
||||
#if HW_PLATFORM == HW_PLATFORM_SIMU
|
||||
|
||||
extern uint8_t ucIsClientMode;
|
||||
p_plc_lib->client = ucIsClientMode;
|
||||
|
||||
#else /* HW_PLATFORM == HW_PLATFORM_SIMU */
|
||||
|
||||
iot_oem_base_cfg_t *oem_cfg = NULL;
|
||||
iot_oem_get_base_cfg(&oem_cfg);
|
||||
if (oem_cfg->module_type == MODULE_TYPE_CCO) {
|
||||
p_plc_lib->client = 0;
|
||||
} else {
|
||||
p_plc_lib->client = 1;
|
||||
}
|
||||
|
||||
#endif /* HW_PLATFORM == HW_PLATFORM_SIMU */
|
||||
|
||||
goto out;
|
||||
|
||||
err_ipc:
|
||||
if (p_plc_lib->task_h) {
|
||||
iot_task_delete(p_plc_lib->task_h);
|
||||
}
|
||||
err_task:
|
||||
os_delete_mutex(p_plc_lib->lock);
|
||||
err:
|
||||
os_mem_free(p_plc_lib);
|
||||
p_plc_lib = NULL;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iot_plc_lib_deinit()
|
||||
{
|
||||
if (p_plc_lib) {
|
||||
iot_ipc_deregister_client(p_plc_lib->ipc_h);
|
||||
iot_task_delete(p_plc_lib->task_h);
|
||||
os_delete_mutex(p_plc_lib->lock);
|
||||
os_mem_free(p_plc_lib);
|
||||
p_plc_lib = NULL;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user