561 lines
15 KiB
C
561 lines
15 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_ship header files */
|
|
#include "os_task_api.h"
|
|
#include "os_event_api.h"
|
|
#include "os_timer_api.h"
|
|
#include "os_utils_api.h"
|
|
|
|
/* iot common header files */
|
|
#include "iot_io_api.h"
|
|
#include "iot_module_api.h"
|
|
#include "iot_errno_api.h"
|
|
#include "iot_task_api.h"
|
|
#include "iot_pkt_api.h"
|
|
#include "iot_ipc_api.h"
|
|
#include "iot_sg_ext_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "iot_oem_api.h"
|
|
#include "iot_plc_api.h"
|
|
|
|
#include "iot_grapp.h"
|
|
#include "iot_proto_common.h"
|
|
#include "iot_cus_task.h"
|
|
#include "iot_cus_ports.h"
|
|
#include "iot_proto_ge.h"
|
|
|
|
#if IOT_GE_EXT_TASK_ENABLE
|
|
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
#define IOT_CUS_TASK_PORT_BUF_SIZE 200
|
|
#endif
|
|
|
|
#define IOT_CUS_TASK_MSG_QUEUE 0
|
|
|
|
#if (IOT_PSRAM_ENABLE)
|
|
#define IOT_CUS_TASK_UART_BUF_SIZE (2048 + 64)
|
|
#else
|
|
#define IOT_CUS_TASK_UART_BUF_SIZE (128 + 64)
|
|
#endif
|
|
|
|
typedef struct _iot_cus_task_t {
|
|
/* task handle */
|
|
iot_task_h task;
|
|
iot_uart_h uart_h;
|
|
/* timer handle */
|
|
timer_id_t timer;
|
|
/* local mac address. */
|
|
uint8_t local_mac[IOT_MAC_ADDR_LEN];
|
|
/* cco mac */
|
|
uint8_t cco_mac[IOT_MAC_ADDR_LEN];
|
|
/* module joined network */
|
|
uint32_t module_ready;
|
|
/* module started */
|
|
bool_t module_started;
|
|
} iot_cus_task_t;
|
|
|
|
static iot_cus_task_t cus_task;
|
|
|
|
#define IOT_CUS_TASK_DATA_DUMP
|
|
|
|
#ifdef IOT_CUS_TASK_DATA_DUMP
|
|
#if (IOT_PSRAM_ENABLE)
|
|
static char dump_buf[1024 + 16];
|
|
void iot_cus_task_data_dump_inner(void * buf, uint32_t len, uint32_t line)
|
|
{
|
|
char *p = buf, *q = dump_buf;
|
|
uint32_t i, buf_len;
|
|
|
|
buf_len = iot_sprintf(q, "DUMP(%03d):", len);
|
|
|
|
for(i = 0; (i < len) && (buf_len < 1024); i++, p++) {
|
|
buf_len += iot_sprintf(q + buf_len, " %02X", ((int)*p) & 0xFF);
|
|
}
|
|
|
|
iot_cus_printf("\n[cus_task@%04d]:%s\n", line, dump_buf);
|
|
|
|
return;
|
|
}
|
|
|
|
#define iot_cus_task_data_dump(buf, len) \
|
|
iot_cus_task_data_dump_inner(buf, len, __LINE__)
|
|
#else
|
|
extern void iot_common_bin_dump(uint8_t *data, uint32_t dlen);
|
|
#define iot_cus_task_data_dump(buf, len) iot_common_bin_dump(buf,len)
|
|
#endif /* end IOT_PSRAM_ENABLE */
|
|
#else
|
|
#define iot_cus_task_data_dump(buf, len)
|
|
#endif /* end IOT_CUS_TASK_DATA_DUMP */
|
|
|
|
/* check frame and change to ge command */
|
|
void iot_cus_task_frame_check(iot_pkt_t *pkt_data)
|
|
{
|
|
/* trans to GE command */
|
|
iot_cus_task_message_to_ge(iot_pkt_data(pkt_data),
|
|
iot_pkt_data_len(pkt_data));
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_uart_send_func() - send data to uart port.
|
|
* @param p_pkt_frame: pointer of pkt frame data buffer.
|
|
* @return ERR_OK
|
|
*/
|
|
uint32_t iot_cus_task_msg_post_to_uart(iot_pkt_t *p_pkt_frame)
|
|
{
|
|
iot_cus_printf("[cus_task]post to uart.\n");
|
|
iot_uart_send(cus_task.uart_h, p_pkt_frame, NULL);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint32_t iot_cus_task_ports_data_get_pid(uint8_t *data, uint32_t len)
|
|
{
|
|
uint32_t pid = PID_MAX;
|
|
ge_frame_data_send_set_subfn160_t *f_fea0;
|
|
|
|
f_fea0 = (ge_frame_data_send_set_subfn160_t *)data;
|
|
|
|
if (len < sizeof(ge_extend_fn_hdr_t) ||
|
|
f_fea0->hdr.hdr.preamble != GE_FRM_PREAMBLE_CODE) {
|
|
goto out;
|
|
}
|
|
|
|
if ((PROTO_GE_PLC_SET_CMD != f_fea0->hdr.hdr.fn)
|
|
|| (PROTO_GE_DATA_CMD != f_fea0->hdr.subfn)) {
|
|
pid = PID_UART;
|
|
goto out;
|
|
}
|
|
|
|
if (port_valid(f_fea0->port_id)) {
|
|
pid = f_fea0->port_id;
|
|
}
|
|
out:
|
|
return pid;
|
|
}
|
|
|
|
uint32_t iot_cus_task_msg_msg_from_ge(iot_pkt_t *p_pkt_frame)
|
|
{
|
|
iot_cus_task_msg_post(IOT_CUS_TASK_MT_GE, 0, p_pkt_frame);
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_uart_msg_process() - process the data from uart.
|
|
* @param p_cus_msg: message received from uart. p_cus_msg->data will be
|
|
* freed by this handle but p_cus_msg will not.
|
|
*/
|
|
static void iot_cus_task_uart_msg_process(iot_cus_task_msg_t *p_cus_msg)
|
|
{
|
|
iot_cus_task_frame_check((iot_pkt_t*)p_cus_msg->data);
|
|
|
|
iot_pkt_free((iot_pkt_t*)p_cus_msg->data);
|
|
|
|
return;
|
|
}
|
|
|
|
static void iot_cus_task_ge_msg_process(iot_cus_task_msg_t *p_cus_msg)
|
|
{
|
|
iot_pkt_t *p_pkt = (iot_pkt_t *)p_cus_msg->data;
|
|
|
|
iot_cus_printf("[cus_task]frame receive from GE.\n");
|
|
|
|
iot_cus_task_data_dump(iot_pkt_data(p_pkt),
|
|
iot_pkt_data_len(p_pkt));
|
|
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
uint32_t port = iot_cus_task_ports_data_get_pid(iot_pkt_data(p_pkt),
|
|
iot_pkt_data_len(p_pkt));
|
|
|
|
if ((PID_UART == port)) {
|
|
iot_cus_task_msg_post_to_uart(p_pkt);
|
|
} else if (port_valid(port)) {
|
|
iot_cus_ports_send(port, iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt));
|
|
iot_pkt_free(p_pkt);
|
|
} else {
|
|
iot_cus_all_ports_write(iot_pkt_data(p_pkt), iot_pkt_data_len(p_pkt));
|
|
iot_pkt_free(p_pkt);
|
|
}
|
|
#else
|
|
iot_cus_task_msg_post_to_uart(p_pkt);
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_handle_timer_msg() - process data from local timer.
|
|
* @msg : message.
|
|
*/
|
|
static void iot_cus_task_handle_timer_msg(iot_cus_task_msg_t *msg)
|
|
{
|
|
switch (msg->task_msg.id) {
|
|
case IOT_CUS_TASK_MSG_ID_TMR_TIMEOUT:
|
|
{
|
|
if (!cus_task.module_started) {
|
|
if (iot_grapp_init_success()) {
|
|
cus_task.module_started = true;
|
|
iot_grapp_reg_fn_receive_from_ge(HOST_PORT_CUSTOM_TASK,
|
|
iot_cus_task_msg_msg_from_ge);
|
|
iot_grapp_set_uart_config(cus_task.uart_h);
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
if (ERR_OK != iot_cus_ports_init()) {
|
|
iot_cus_printf("[cus_task]ports init failed.\n");
|
|
}
|
|
#endif
|
|
}
|
|
} else {
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
iot_cus_ports_timer_handle(IOT_CUS_PORT_TIMER_PERIOD);
|
|
#endif
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_cus_printf("[cus_task]unknown timer message id #%d.\n",
|
|
msg->task_msg.id);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_internal_msg_process() - process the data from cus-task.
|
|
* @param p_cus_msg: message received from cus-task. p_cus_msg->data
|
|
* will be freed by this handle but p_cus_msg will not.
|
|
*/
|
|
static void iot_cus_task_internal_msg_process(iot_cus_task_msg_t *p_cus_msg)
|
|
{
|
|
switch (p_cus_msg->task_msg.id) {
|
|
default:
|
|
{
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_msg_exe_func() - messages handle function.
|
|
* @param task_h: handle of task.
|
|
* @param p_msg: message that will be processed.
|
|
*/
|
|
void iot_cus_task_msg_exe_func(iot_task_h task_h, iot_task_msg_t *p_msg)
|
|
{
|
|
iot_cus_task_msg_t *p_cus_msg = (iot_cus_task_msg_t *)p_msg;
|
|
|
|
switch (p_cus_msg->task_msg.type)
|
|
{
|
|
case IOT_CUS_TASK_MT_UART:
|
|
{
|
|
iot_cus_task_uart_msg_process(p_cus_msg);
|
|
break;
|
|
}
|
|
case IOT_CUS_TASK_MT_TIMER:
|
|
{
|
|
iot_cus_task_handle_timer_msg(p_cus_msg);
|
|
break;
|
|
}
|
|
case IOT_CUS_TASK_MT_INTERNAL:
|
|
{
|
|
iot_cus_task_internal_msg_process(p_cus_msg);
|
|
break;
|
|
}
|
|
case IOT_CUS_TASK_MT_GE:
|
|
{
|
|
iot_cus_task_ge_msg_process(p_cus_msg);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
iot_pkt_free(p_cus_msg->data);
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iot_task_free_msg(task_h, p_msg);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_cus_task_event_exe_func(iot_task_h task_h, uint32_t events)
|
|
{
|
|
(void)task_h;
|
|
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
if (IOT_CUS_TASK_EID_EXT_PORTS & events) {
|
|
iot_cus_ports_event_handle();
|
|
}
|
|
#endif
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_msg_cancel_func() - pull back messages that sent to this
|
|
* task.
|
|
* @param task_h: handle of task.
|
|
* @param p_msg: message that will be pull back.
|
|
*/
|
|
void iot_cus_task_msg_cancel_func(iot_task_h task_h, iot_task_msg_t *p_msg)
|
|
{
|
|
iot_cus_task_msg_t *p_cus_msg = (iot_cus_task_msg_t *)p_msg;
|
|
|
|
switch(p_cus_msg->task_msg.type)
|
|
{
|
|
case IOT_CUS_TASK_MT_UART:
|
|
case IOT_CUS_TASK_MT_TIMER:
|
|
case IOT_CUS_TASK_MT_INTERNAL:
|
|
{
|
|
iot_pkt_free(p_cus_msg->data);
|
|
}
|
|
default:
|
|
{
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
iot_task_free_msg(task_h, p_msg);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_cus_task_ports_data_patch_pid(uint32_t port,
|
|
uint8_t* data, uint32_t len)
|
|
{
|
|
ge_frame_data_send_set_subfn160_t *f_fea0;
|
|
uint16_t crc = 0xff;
|
|
|
|
f_fea0 = (ge_frame_data_send_set_subfn160_t *)data;
|
|
|
|
if ((PROTO_GE_PLC_SET_CMD != f_fea0->hdr.hdr.fn)
|
|
|| (PROTO_GE_DATA_CMD != f_fea0->hdr.subfn)) {
|
|
/* Do nothing. */
|
|
return;
|
|
}
|
|
|
|
if (iot_proto_get_cco_mac(cus_task.cco_mac)) {
|
|
/* didn't get the cco mac address, do nothing */
|
|
return;
|
|
}
|
|
|
|
if (port_valid(port)) {
|
|
f_fea0->port_id = port;
|
|
os_mem_cpy(f_fea0->dest_mac, cus_task.cco_mac, IOT_MAC_ADDR_LEN);
|
|
} else {
|
|
f_fea0->port_id = PID_UART;
|
|
}
|
|
|
|
crc = ge_frm_checksum_calc(data, len - 3);
|
|
os_mem_cpy(&data[len - 3], &crc, sizeof(uint8_t) * 2);
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_send_data_to_ge() - recveived command from ports, send to
|
|
* common proto
|
|
* @param data: command data.
|
|
* @param len : command data length.
|
|
* @param pid : Port ID.
|
|
* @return : ERR_OK - send successfully.
|
|
* ERR_FAIL - send failed.
|
|
*/
|
|
uint8_t iot_cus_task_ports_data_send_to_ge(uint8_t * data, uint32_t len,
|
|
uint32_t pid)
|
|
{
|
|
iot_pkt_t* send_pkt = NULL;
|
|
|
|
send_pkt = iot_pkt_alloc(len, IOT_CUS_TASK_ID);
|
|
|
|
if (send_pkt) {
|
|
/* copy data from buf to data packet */
|
|
os_mem_cpy(iot_pkt_put(send_pkt, len), data, len);
|
|
#if IOT_CUS_APP_MULTI_PORTS
|
|
/* filter FE A0, rewrite the PORTID */
|
|
iot_cus_task_ports_data_patch_pid(pid, iot_pkt_data(send_pkt), len);
|
|
#endif
|
|
/* alloc message to insert proto task msg queue */
|
|
iot_cus_task_msg_post(IOT_CUS_TASK_MT_UART,
|
|
IOT_CUS_TASK_MSG_ID_CMD_HANDLE, send_pkt);
|
|
return ERR_OK;
|
|
} else {
|
|
iot_cus_printf("[cus_task][err]no mem, frame len:%d\n", len);
|
|
return ERR_FAIL;
|
|
}
|
|
}
|
|
|
|
void iot_cus_task_ports_data_receive(uint32_t port, uint8_t *buf, uint32_t blen)
|
|
{
|
|
void *send_fn = iot_cus_task_ports_data_send_to_ge;
|
|
|
|
if ((NULL != buf) && (0 < blen)) {
|
|
iot_proto_data_parse_and_post(buf, blen, send_fn, port);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_uart_receive_func() - Uart driver callback function
|
|
* when data received.
|
|
* @param buffer: pointer of data buffer.
|
|
* @param buffer_len: length of data received.
|
|
* @param is_full_frame: tell if this is a whole frame in this buffer.
|
|
* @param invalid_data_len: length of invalid data received. we ignore this.
|
|
*/
|
|
void iot_cus_task_uart_receive_func(uint8_t* p_buffer, uint32_t buffer_len,
|
|
bool_t is_full_frame, uint32_t invalid_data_len)
|
|
{
|
|
(void)is_full_frame;
|
|
(void)invalid_data_len;
|
|
|
|
iot_cus_printf("uart recv buf_len=%d\n", buffer_len);
|
|
iot_cus_task_ports_data_receive(PID_UART, p_buffer, buffer_len);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_cus_task_msg_post(uint16_t msg_type, uint16_t msg_id, iot_pkt_t *data)
|
|
{
|
|
iot_task_msg_t *msg;
|
|
iot_cus_task_msg_t *task_msg;
|
|
msg = iot_task_alloc_msg_with_reserved(cus_task.task, 0);
|
|
if (NULL == msg) {
|
|
if (NULL != data) {
|
|
iot_pkt_free(data);
|
|
}
|
|
IOT_ASSERT(0);
|
|
return;
|
|
}
|
|
|
|
task_msg = (iot_cus_task_msg_t*)msg;
|
|
task_msg->task_msg.type = msg_type;
|
|
task_msg->task_msg.id = msg_id;
|
|
task_msg->data = data;
|
|
task_msg->data2 = 0;
|
|
iot_task_queue_msg(cus_task.task, &task_msg->task_msg, 0);
|
|
|
|
return;
|
|
}
|
|
|
|
void iot_cus_task_event_post(uint32_t events)
|
|
{
|
|
os_set_task_event_with_v(iot_task_get_os_task_h(cus_task.task),
|
|
events);
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_led_ctrl_task_timer_exe() - timer timeout callback function.
|
|
* @timer_id : timer id with that timer who causes this api-call.
|
|
* @arg : param past to this callback api.
|
|
*/
|
|
void iot_cus_task_task_timer_exe(timer_id_t timer_id, void * arg)
|
|
{
|
|
(void)timer_id;
|
|
(void)arg;
|
|
|
|
iot_cus_task_msg_post(IOT_CUS_TASK_MT_TIMER,
|
|
IOT_CUS_TASK_MSG_ID_TMR_TIMEOUT, NULL);
|
|
|
|
return;
|
|
}
|
|
|
|
uint32_t iot_cus_task_uart_send(iot_pkt_t *p_pkt)
|
|
{
|
|
uint32_t ret;
|
|
|
|
ret = iot_uart_send(cus_task.task, p_pkt, NULL);
|
|
|
|
return (ERR_OK == ret) ? ERR_OK : ERR_FAIL;
|
|
}
|
|
|
|
/**
|
|
* @brief iot_cus_task_init() - The main entry to initialize our customer task.
|
|
*/
|
|
uint32_t iot_cus_task_init(void)
|
|
{
|
|
iot_task_config_t task_cfg;
|
|
|
|
os_mem_set(&cus_task, 0, sizeof(iot_cus_task_t));
|
|
/* TODO : set unready. */
|
|
cus_task.module_ready = false;
|
|
|
|
/* create task */
|
|
os_mem_set(&task_cfg, 0x0, sizeof(task_cfg));
|
|
task_cfg.stack_size = IOT_CUS_TASK_TASK_STACK_SIZE;
|
|
task_cfg.task_prio = IOT_CUS_TASK_PROTO_TASK_PRIO;
|
|
task_cfg.msg_size = sizeof(iot_cus_task_msg_t);
|
|
task_cfg.msg_cnt = IOT_CUS_TASK_TASK_POOL_SIZE;
|
|
task_cfg.queue_cnt = 1;
|
|
task_cfg.queue_cfg[0].quota = 0;
|
|
task_cfg.msg_exe_func = iot_cus_task_msg_exe_func;
|
|
task_cfg.msg_cancel_func = iot_cus_task_msg_cancel_func;
|
|
task_cfg.task_event_func = iot_cus_task_event_exe_func;
|
|
|
|
cus_task.uart_h = iot_uart_open(iot_board_get_uart(UART_METER_PORT),
|
|
iot_cus_task_uart_receive_func, IOT_CUS_TASK_UART_BUF_SIZE, NULL);
|
|
|
|
iot_uart_set_threshold(cus_task.uart_h, UART_THR_RXTIMEOUT,
|
|
IOT_UART_DEFAULT_THDVALUE);
|
|
iot_uart_set_threshold(cus_task.uart_h, UART_THR_NO_FMT_TIMEOUT,
|
|
IOT_UART_DEFAULT_THDVALUE);
|
|
cus_task.task = iot_task_create(IOT_CUS_TASK_ID, &task_cfg);
|
|
|
|
if (NULL == cus_task.task) {
|
|
iot_cus_printf("[cus_task]create task failed.\n");
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
cus_task.timer = os_create_timer(IOT_CUS_TASK_ID, true,
|
|
iot_cus_task_task_timer_exe, NULL);
|
|
|
|
if (0 == cus_task.timer) {
|
|
iot_cus_printf("[cus_task]create timer failed.\n");
|
|
iot_task_delete(cus_task.task);
|
|
return ERR_FAIL;
|
|
}
|
|
|
|
os_start_timer(cus_task.timer, IOT_CUS_TASK_TIMER_PERIOD);
|
|
|
|
iot_cus_printf("[cus_task]task create successfully.\n");
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint32_t app_cus_task_entry()
|
|
{
|
|
uint32_t ret = ERR_PENDING;
|
|
|
|
if (ERR_OK == iot_cus_task_init())
|
|
{
|
|
ret = ERR_OK;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif /* IOT_GE_EXT_TASK_ENABLE */
|