330 lines
7.6 KiB
C
330 lines
7.6 KiB
C
/*
|
|
* ne_device.c -- provide iot-system device layer operation interface.
|
|
*
|
|
*
|
|
* ORIGINAL AUTHOR:
|
|
*
|
|
* Copyright (c) 2018 Netease Corporation
|
|
*/
|
|
#include "c_types.h"
|
|
#include "ne_device.h"
|
|
#include "user_main.h"
|
|
#include "cfg.h"
|
|
#include "log.h"
|
|
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "freertos/semphr.h"
|
|
#include "freertos/timers.h"
|
|
|
|
#include "ne_sweeper.h"
|
|
#include "ne_general.h"
|
|
|
|
|
|
|
|
#define THIS_NE_DEVICE_CTX &ne_device_ctx
|
|
#define NE_DEVICE_INIT_MAGIC 0xaabbccdd
|
|
#define NE_DEVICE_MAX_QUEUE_COUNT 10
|
|
#define CONFIG_YANXUAN_SWEEPER_DEVICE
|
|
#define CONFIG_NE_GENERAL_DEVICE
|
|
#define NE_DEVICE_MSG_DELAY 5
|
|
|
|
#define NE_DEVICE_HEALTH_TIME 20*1000 //ms
|
|
#define NE_DEVICE_INTERVAL_TIME 1 //sec
|
|
|
|
|
|
|
|
enum{
|
|
NE_DEVICE_YANXUAN_SWEEPER,
|
|
NE_DEVICE_GENERAL,
|
|
};
|
|
|
|
typedef struct {
|
|
uint8 *rbuf;
|
|
uint32 rlen;
|
|
uint8 *sbuf;
|
|
uint32 slen;
|
|
}ne_device_frame_t;
|
|
|
|
typedef struct ne_device_ctx{
|
|
|
|
uint32 init;
|
|
void * timer_handle;
|
|
void * task_handle;
|
|
void * queue_handle;
|
|
ne_device_frame_t frame;
|
|
ne_device_handler_t *ne_device_handler;
|
|
|
|
}ne_device_ctx_t;
|
|
|
|
static ne_device_ctx_t ne_device_ctx;
|
|
|
|
static ne_device_handler_t ne_device_list[] = {
|
|
#ifdef CONFIG_YANXUAN_SWEEPER_DEVICE
|
|
[0] = {
|
|
.device_init = yanxuan_sweeper_init,
|
|
.device_deinit = yanxuan_sweeper_deinit,
|
|
.device_read = yanxuan_sweeper_read,
|
|
.device_write = yanxuan_sweeper_write,
|
|
.device_parse = yanxuan_sweeper_process,
|
|
.device_split = yanxuan_sweeper_split
|
|
},
|
|
#endif
|
|
#ifdef CONFIG_NE_GENERAL_DEVICE
|
|
[1] = {
|
|
.device_init = ne_general_init,
|
|
.device_deinit = ne_general_deinit,
|
|
.device_read = ne_general_read,
|
|
.device_write = ne_general_write,
|
|
.device_parse = ne_general_process,
|
|
.device_split = ne_general_split
|
|
},
|
|
#endif
|
|
|
|
|
|
};
|
|
|
|
|
|
static uint32 ne_device_health_value;
|
|
|
|
|
|
/*
|
|
* system thread monitor check.
|
|
*/
|
|
static int32 ne_device_thread_check(uint32 cur_msec)
|
|
{
|
|
if (cur_msec > ne_device_health_value + NE_DEVICE_HEALTH_TIME) {
|
|
LOG_EX(LOG_Error, "thread is sick! and system restart!\r\n");
|
|
system_restart();
|
|
|
|
return -ERR_FAIL;
|
|
}
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
/*
|
|
* system set msec.
|
|
*/
|
|
static void ne_device_set_last_msec(uint32 msec)
|
|
{
|
|
ne_device_health_value = msec;
|
|
}
|
|
|
|
/*
|
|
* system register thread monitor.
|
|
*/
|
|
static int32 ne_device_thread_monitor_init(void *handle_name)
|
|
{
|
|
ne_device_health_value = ne_os_ticks_ms(xTaskGetTickCount());
|
|
|
|
return ne_thread_monitor_register(handle_name, NE_DEVICE_INTERVAL_TIME, ne_device_thread_check);
|
|
}
|
|
|
|
|
|
/*
|
|
* netease get device handle.
|
|
*/
|
|
ne_device_handler_t * ne_get_device_handler(uint32 device_id)
|
|
{
|
|
|
|
return &ne_device_list[device_id];
|
|
|
|
}
|
|
|
|
/*
|
|
* netease queue send.
|
|
*/
|
|
int ne_device_send_queue(uint8 *data, uint32 len, uint8 msg_dir)
|
|
{
|
|
int ret;
|
|
ne_device_ctx_t *ctx = THIS_NE_DEVICE_CTX;
|
|
ne_device_msgtype_t msg;
|
|
|
|
if (data == NULL || len == 0) {
|
|
LOG_EX(LOG_Error,"Message Notify bad len, dir %x\r\n", msg_dir);
|
|
return;
|
|
}
|
|
|
|
/* get datas */
|
|
msg.data = malloc(len);
|
|
if (msg.data) {
|
|
memcpy(msg.data, data, len);
|
|
}
|
|
msg.len = len;
|
|
msg.msg_dir = msg_dir;
|
|
{
|
|
int i, len;
|
|
LOG_EX(LOG_Info,"data len=%d msg_dir=%d\r\n", msg.len, msg_dir);
|
|
len = msg.len;
|
|
if (len > 32)
|
|
len = 32;
|
|
for(i=0;i<len;i++){
|
|
printf(" 0x%x",msg.data[i]);
|
|
}
|
|
printf("\r\n");
|
|
}
|
|
|
|
/* send queue */
|
|
ret = xQueueSend(ctx->queue_handle, &msg, 0);
|
|
if(ret != pdTRUE){
|
|
LOG_EX(LOG_Error,"send esp_msg_queue fail!\r\n");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* netease device frame process.
|
|
*/
|
|
void ne_device_frame_process(ne_device_ctx_t *ctx, uint8 *input, uint32 in_len)
|
|
{
|
|
int32 msgdir;
|
|
uint32 offset = 0;
|
|
|
|
IHW_LOG_BUF(LOG_Debug, "Receive", input, in_len);
|
|
|
|
while(in_len > offset){
|
|
/* frame filter */
|
|
msgdir = ctx->ne_device_handler->device_split(NULL, &offset, input , in_len, ctx->frame.rbuf, &ctx->frame.rlen);
|
|
|
|
if(msgdir == MSG_DIRECTION_UART_UP || msgdir == MSG_DIRECTION_BDATA_UP){
|
|
//LOG_EX(LOG_Debug, "Send Protocol\n");
|
|
/* frame send queue */
|
|
ne_device_send_queue(ctx->frame.rbuf, ctx->frame.rlen, msgdir);
|
|
}
|
|
LOG_EX(LOG_Info, "device_split offset=%d in_len=%d\r\n", offset, in_len);
|
|
}
|
|
ne_adjust_recv_info(offset);
|
|
}
|
|
|
|
/*
|
|
* netease device timer polling cb.
|
|
*/
|
|
void ne_device_polling_cb(void *arg)
|
|
{
|
|
uint8_t *tbuf;
|
|
int32 ret;
|
|
uint32 tlen;
|
|
ne_device_ctx_t *ctx = THIS_NE_DEVICE_CTX;
|
|
|
|
/* read uart datas */
|
|
ret = ctx->ne_device_handler->device_read(NULL, &tbuf, &tlen);
|
|
if(ret == ERR_OK){
|
|
//LOG_EX(LOG_Info, "polling data tlen=%d\r\n", tlen);
|
|
if(tbuf == NULL || tlen <= 0)
|
|
return;
|
|
|
|
/* uart filter and process */
|
|
ne_device_frame_process(ctx, tbuf, tlen);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* netease device process.
|
|
*/
|
|
void ne_device_process(void * arg)
|
|
{
|
|
ne_device_ctx_t *ctx = THIS_NE_DEVICE_CTX;
|
|
ne_device_msgtype_t msg;
|
|
|
|
/* thread monitor */
|
|
ne_device_thread_monitor_init("device_thread");
|
|
|
|
while(1){
|
|
|
|
if(xQueueReceive(ctx->queue_handle, &msg, NE_DEVICE_MSG_DELAY) == pdPASS){
|
|
|
|
/* device parse */
|
|
ctx->frame.slen = ctx->ne_device_handler->device_parse(NULL, msg.msg_dir, msg.data, msg.len, ctx->frame.sbuf, NE_DEVICE_BUF_SIZE);
|
|
if(ctx->frame.slen > 0){
|
|
|
|
/* send to mcu */
|
|
ctx->ne_device_handler->device_write(NULL, ctx->frame.sbuf, ctx->frame.slen);
|
|
}
|
|
|
|
free(msg.data);
|
|
}
|
|
ne_device_set_last_msec(ne_os_ticks_ms(xTaskGetTickCount()));
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* netease device process init.
|
|
*/
|
|
int32 ne_device_init(void)
|
|
{
|
|
uint32 device_type;
|
|
ne_device_ctx_t *ctx = THIS_NE_DEVICE_CTX;
|
|
ne_device_handler_t *handle;
|
|
|
|
#if DEVICE_YANXUAN_SWEEPER
|
|
device_type = NE_DEVICE_YANXUAN_SWEEPER;
|
|
LOG_EX(LOG_Info, "device init for YANXUAN SWEEPER!\r\n");
|
|
#else
|
|
device_type = NE_DEVICE_GENERAL;
|
|
LOG_EX(LOG_Info, "device init for NETEASE GENERAL!\r\n");
|
|
#endif
|
|
|
|
handle = ne_get_device_handler(device_type);
|
|
/* interface check */
|
|
if(ctx->init == NE_DEVICE_INIT_MAGIC || handle == NULL)
|
|
return -ERR_FAIL;
|
|
|
|
if(handle->device_init == NULL || handle->device_deinit == NULL || handle->device_read == NULL \
|
|
|| handle->device_read == NULL || handle->device_parse == NULL || handle->device_split == NULL)
|
|
|
|
return -ERR_FAIL;
|
|
|
|
/* get device driver handle */
|
|
memset(ctx, 0 , sizeof(ne_device_ctx_t));
|
|
ctx->ne_device_handler = handle;
|
|
ctx->frame.rbuf = (uint8 *)malloc(NE_DEVICE_BUF_SIZE);
|
|
ctx->frame.sbuf = (uint8 *)malloc(NE_DEVICE_BUF_SIZE);
|
|
|
|
|
|
if(ctx->ne_device_handler->device_init(NULL) != ERR_OK)
|
|
goto ERR_INIT;
|
|
|
|
ctx->timer_handle = xTimerCreate("uart_time", 40 / portTICK_RATE_MS, pdTRUE, NULL, ne_device_polling_cb);
|
|
if(ctx->timer_handle != NULL)
|
|
xTimerStart(ctx->timer_handle, 0);
|
|
|
|
ctx->queue_handle = xQueueCreate(NE_DEVICE_MAX_QUEUE_COUNT, sizeof(ne_device_msgtype_t));
|
|
if(ctx->queue_handle == NULL)
|
|
goto ERR_INIT;
|
|
|
|
xTaskCreate(ne_device_process, "device_process", 256, NULL, tskIDLE_PRIORITY + 6, NULL);
|
|
|
|
goto OK_INIT;
|
|
|
|
ERR_INIT:
|
|
if(ctx->timer_handle != NULL){
|
|
xTimerStop(ctx->timer_handle, 0);
|
|
xTimerDelete(ctx->timer_handle, 0);
|
|
}
|
|
|
|
if(ctx->queue_handle != NULL)
|
|
vQueueDelete(ctx->queue_handle);
|
|
|
|
if(ctx->ne_device_handler->device_deinit != NULL)
|
|
ctx->ne_device_handler->device_deinit(NULL);
|
|
|
|
LOG_EX(LOG_Info, "device init fail!\r\n");
|
|
|
|
return -ERR_FAIL;
|
|
|
|
OK_INIT:
|
|
ctx->init = NE_DEVICE_INIT_MAGIC;
|
|
LOG_EX(LOG_Info, "device init success.\r\n");
|
|
|
|
return ERR_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|