esp8266-std/driver/ne_device.c

330 lines
7.6 KiB
C
Raw Normal View History

2018-11-23 01:43:17 +00:00
/*
* 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;
2019-01-10 07:18:39 +00:00
IHW_LOG_BUF(LOG_Debug, "Receive", input, in_len);
2018-11-23 01:43:17 +00:00
while(in_len > offset){
/* frame filter */
msgdir = ctx->ne_device_handler->device_split(NULL, &offset, input , in_len, ctx->frame.rbuf, &ctx->frame.rlen);
2018-11-23 01:43:17 +00:00
if(msgdir == MSG_DIRECTION_UART_UP || msgdir == MSG_DIRECTION_BDATA_UP){
//LOG_EX(LOG_Debug, "Send Protocol\n");
2018-11-23 01:43:17 +00:00
/* 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);
2018-11-23 01:43:17 +00:00
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);
2018-11-23 01:43:17 +00:00
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;
}