Files
kunlun/app/iot_ge_ext_app/iot_cus_task.c
2024-09-28 14:24:04 +08:00

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 */