EC600U_esp32_iap_uart/EC600U_uart1/uart1_modbus_master.c
2024-02-05 17:39:56 +08:00

427 lines
14 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ql_api_osi.h"
#include "ql_log.h"
#include "ql_uart.h"
#include "ql_gpio.h"
#include "drv_uart.h"
#include "osi_api.h"
#include "stdlib.h"
#include "../EC600U_t2n/include/t2n.h"
#include "../EC600U_t2n/include/ModbusS.h"
#include "./inc/esp32flash.h"
#include "./inc/EC600U_port.h"
#include "ql_api_datacall.h"
#include "ql_http_client.h"
#include "ql_fs.h"
#include "ql_api_fota.h"
#include "ql_power.h"
#include "ql_api_dev.h"
#include "ql_log.h"
#define LOGI(msg, ...) QL_LOG(QL_LOG_LEVEL_INFO, "uart1_modbus", msg, ##__VA_ARGS__)
osiThread_t *uart1_thread = NULL; //串口驱动modbus的线程句柄
drvUart_t *drvuart1 = NULL; //串口传输modbus的uart驱动句柄
static uint8_t uart_rxbuf[256 + 8];
extern uint16_t gWordVar[];
extern int com_poll_modbus_master_on_revice(int ch, uint8_t *rxbuf, int length);
extern void com_poll_init(void);
extern void com_poll_modbus_master_poll(int n);
extern uint8_t download_file_to_SD(void);
void Timeroutcallback(void *param)
{
//LOGI("enter Timeroutcallback");
osiEvent_t event;
event.id = 10;
if(uart1_thread != NULL){
if(osiEventSend(uart1_thread, &event)){
//LOGI("osiEventSend event id 10 sucess");
}
else{
//LOGI("osiEventSend event id 10 fail");
}
}
}
void uart1_modbus_event_cb(void *param, uint32_t evt)
{
//LOGI("enter uart1_event_cb");
if (evt & QL_UART_EVENT_TX_COMPLETE) // 发送完成
{
//LOGI("QL_UART_EVENT_TX_COMPLETE");
}
else if (evt & QL_UART_EVENT_RX_ARRIVED) // 接收完成
{
//LOGI("QL_UART_EVENT_RX_ARRIVED");
osiEvent_t event;
event.id = 9; //
if (uart1_thread != NULL)
{
if(osiEventSend(uart1_thread, &event)){
//LOGI("osiEventSend event id 9 sucess");
}
else{
//LOGI("osiEventSend event id 9 fail");
}
}
}
}
void uart1_task_thread(void *param)
{
LOGI("uart1_task_thread start");
// int ret = 0;
int run_loop = 1;
int rx_length = 0;
osiTimer_t *ptimer = NULL;
drvUartCfg_t uart_cfg = {
.baud = 115200,
.data_bits = DRV_UART_DATA_BITS_8,
.stop_bits = DRV_UART_STOP_BITS_1,
.parity = DRV_UART_NO_PARITY,
.event_cb = uart1_modbus_event_cb,
.event_mask = DRV_UART_EVENT_RX_OVERFLOW | DRV_UART_EVENT_TX_COMPLETE | DRV_UART_EVENT_RX_ARRIVED,
.rx_buf_size = 128,
.tx_buf_size = 128,
.event_cb_ctx = NULL,
.cts_enable = false,
.rts_enable = false,
};
uart1_thread = osiThreadCurrent();
restart:
if (drvuart1 == NULL)
{
drvuart1 = drvUartCreate(DRV_NAME_UART1, &uart_cfg);
if (drvuart1 == NULL){
LOGI("drvuart1 create faild!");
goto err1;
}
LOGI("drvuart1 create OK!");
if(drvUartOpen(drvuart1)){
LOGI("drvuart1 open OK");
}
else{
LOGI("drvuart1 open faild!");
goto err1;
}
}
LOGI("drvuart1 init end");
if (ptimer == NULL){
ptimer = osiTimerCreate(uart1_thread, Timeroutcallback, NULL);
}
if(ptimer != NULL){
LOGI("osiTimerCreate sucess");
}
else{
LOGI("osiTimerCreate fail");
}
if(osiTimerStart(ptimer, 10)){
LOGI("osiTimerStart ok");
}
else{
LOGI("osiTimerStart fail");
}
com_poll_init();
LOGI("com_poll_init end");
run_loop = 1;
while (run_loop)
{
//LOGI("enter while");
osiEvent_t waitevent;
if(osiEventTryWait(osiThreadCurrent(), &waitevent, 1000))
{
//LOGI("event happend"); // 响应到事件发生
switch (waitevent.id)
{
case 9:
{
//LOGI("event id = 9");
int len = drvUartReceive(drvuart1, &uart_rxbuf[rx_length], sizeof(uart_rxbuf) - rx_length);
if (len > 0)
{
//LOGI("receive data sucess, length is %d\n",len);
rx_length += len;
if (uart_rxbuf[1] == 0x03 || uart_rxbuf[1] == 0x04)//判断什么的?
{
//LOGI("uart_rxbuf[1] == 0x03 || uart_rxbuf[1] == 0x04");
if (rx_length >= uart_rxbuf[2] + 5)//判断依据?
{
com_poll_modbus_master_on_revice(0, uart_rxbuf, rx_length);
rx_length = 0;
}
}
else
{
com_poll_modbus_master_on_revice(0, uart_rxbuf, rx_length);
rx_length = 0;
}
}else{
//LOGI("receive data fail");
}
}
break;
case 10: // 10ms timmer
{
//LOGI("event id = 10");
if(osiTimerStart(ptimer, 10)){
//LOGI("osiTimerStart sucess");
}
else{
//LOGI("osiTimerStart fail");
}
com_poll_modbus_master_poll(0);
//LOGI("com_poll_modbus_master_poll end");
break;
}
#if 0
case 0x2000:
LOGI("event id = 0x2000");
ModbusSetLocalReg(waitevent.param1, waitevent.param2);
//error:intersection fail
//error:set boot/raet value fail
break;
#endif
case 0x3299:
{
LOGI("event id= 0x3299, http download");
uint8_t err = download_file_to_SD();
LOGI("download_file_to_SD err = %d",err);
break;
}
#if 0
//获取url通过url将代码下载到文件中
case 0x3299:
{
LOGI("event id = 0x3299");
if (waitevent.param1 != 0)
{
LOGI("waitevent.param1 != 0");
gWordVar[REG_UPDATE_STATUS] = 1;
setESP32BootValue(1);
//根据waitevent.param1获取url然后将bin文件下载到SD卡的指定文件中
http_dowload((char *)waitevent.param1,DOWNLOAD_FILENAME);
int fd = ql_fopen(DOWNLOAD_FILENAME, "r");
if (fd > 0){
LOGI("open file sucess");
}else{
LOGI("open file fail");
}
int file_size = ql_fsize(fd);
ql_fclose(fd);
free((void *)waitevent.param1);
gWordVar[REG_UPDATE_STATUS] = file_size;
waitevent.param1 = 0;
/*将本地bin文件刷写到esp32中*/
if (file_size > 0)
{
LOGI("file size = %d",file_size);
drvUartClose(drvuart1);
drvUartDestroy(drvuart1);
drvuart1 = NULL;
LOGI("drvUartDestroy drvuart1 end");
gWordVar[REG_UPDATE_STATUS] = 3;
uint8_t transmit_ret = ESP32DownloadFile("SD:EC600U_http_download.txt", 0x10000);
if(transmit_ret ==0 ){
LOGI("ESP32DownloadFile sucess\n");
}else{
LOGI("ESP32DownloadFile fail\n");
}
gWordVar[REG_UPDATE_STATUS] = transmit_ret;
setESP32BootValue(0);
loader_port_reset_target();
}else{
LOGI("file may be empty or no exist,file size = %d\n",file_size);
}
}else{
LOGI("no waitevent.param1");
}
run_loop = 0;
break;
}
#endif
#if 1
//通过本地文件刷写esp32s3程序
case 0x3203:
{
LOGI("event id = 0x3203");
gWordVar[REG_UPDATE_STATUS] = 1;
uint8_t res = 0;
/*关闭超时定时器*/
osiTimerStop(ptimer);
LOGI("osiTimerStop ptimer end");
/*关闭当前modbus串口*/
drvUartClose(drvuart1);
drvUartDestroy(drvuart1);
drvuart1 = NULL;
LOGI("drvUartDestroy drvuart1 end");
ql_rtos_task_sleep_ms(500);
/*初始化bootloader串口*/
res = bootloader_uart_init(115200);
LOGI("bootloader_uart_init res = %d",res);
ql_rtos_task_sleep_ms(500);
/*使esp32进入bootloader模式*/
res = esp32_enter_bootloader();
LOGI("esp32_enter_bootloader res = %d",res);
ql_rtos_task_sleep_ms(500);
/*刷写*/
res = flash_to_esp32();
gWordVar[REG_UPDATE_STATUS] = res;
LOGI("flash_to_esp32 res = %d",res);
/*使esp32退出bootloader模式*/
res = esp32_exit_bootloader();
LOGI("esp32_exit_bootloader res = %d",res);
ql_rtos_task_sleep_ms(500);
/*解初始化bootloader串口*/
res = bootloader_uart_deinit();
LOGI("bootloader_uart_deinit res = %d",res);
ql_rtos_task_sleep_ms(500);
run_loop = 0;
LOGI("case 0x3203 end");
break;
}
#endif
#if 0
//应用程序镜像升级
case 0x5700:
{
LOGI("event id = 0x5700");
if (strncmp((char *)waitevent.param1, "http://", 7) == 0)
{
LOGI("waitevent.param1: http://");
drvUartClose(drvuart1);
drvUartDestroy(drvuart1);
drvuart1 = NULL;
LOGI("drvUartDestroy drvuart1 end");
if(osiTimerStop(ptimer)){
LOGI("osiTimerStop sucess");
}
else{
LOGI("osiTimerStop fail");
}
if(AppImageUpgradeFotaEntry(waitevent.param1) == 0){
LOGI("AppImageUpgradeFotaEntry sucess");
}
else{
LOGI("AppImageUpgradeFotaEntry fail");
osiThreadSleep(6000);
/*重启*/
}
free((void *)waitevent.param1);
waitevent.param1 = 0;
}else{
LOGI("waitevent.param1 error");
}
break;
}
#endif
default:
break;
}
waitevent.id = 0;
}
else
{
LOGI("no event happend");
}
}
goto restart;
err1:
osiThreadExit();
}
ql_task_t uart1_task = NULL;
void uart1_app_init(void){
/*用于esp32的reset和boot*/
LOGI("ql_pin_set_func(33,0) err = %d",ql_pin_set_func(33,0));
LOGI("ql_pin_set_func(34,0) err = %d",ql_pin_set_func(34,0));
LOGI("ql_gpio_init GPIO_18 err = %d",ql_gpio_init(GPIO_18,GPIO_OUTPUT,PULL_DOWN,LVL_LOW));
LOGI("ql_gpio_init GPIO_19 err = %d",ql_gpio_init(GPIO_19,GPIO_OUTPUT,PULL_DOWN,LVL_LOW));
// ql_pin_set_func(33,0);
// ql_pin_set_func(34,0);
// ql_gpio_set_direction(GPIO_19,GPIO_OUTPUT);
// ql_gpio_set_direction(GPIO_18,GPIO_OUTPUT);
// ql_gpio_set_level(GPIO_19,LVL_LOW);
// ql_gpio_set_level(GPIO_18,LVL_LOW);
ql_rtos_task_create(&uart1_task, 4096, APP_PRIORITY_NORMAL, "uart1_task", uart1_task_thread, NULL, 5);
}
/**
* 测试:
* A:在连接modbus之前空测了一遍然后连接modbus连续测试
* B:上电后直接连接modbus进行连续测试
* 概率性问题:
* 1.连上modbus后进行测试系统卡死卡死后ec600的电源就不供电了esp32断电后ec600也断电
* 2.ec600的端口经常性检测不到怀疑端口松动
* 3.ec600正常工作log抓取不到多次重启cooltools也无效的现象只能重新插拔ec600重新抓取
* 4.程序执行串口读取不到规定次数,也没有返回值,但是程序又重新正常执行了
*
* 未卡死次数48读到非0数据次数11
*
* 1.将项目编译成功,并提交 ok
* 2.恢复数据结构体为紧凑型尝试接收到数据0xC0
* A:0x00,0x00,0xF9,0x00,0x00,0x00,0x9C,0x00,卡死
* B:0x00,0xEC,0x00,0x00,0x00,卡死
* 3.将sync_cmd的size属性由sizof(sync_command_t)->sizeof(sync_cmd)
* 烧录后屏幕不亮log能抓取到,又重新烧录了好几遍才恢复正常
* A:卡死
* A2:0x00,0x00,抓不到log
* A3:0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,卡死
* B:0x80,0x00,0x00,0x00,0x00,0xEC,卡死
* 4.将进入bootloader放到loader_port_start_timer之前紧挨着
* A:0x00,0x67,0x00,0x00,0x64,0x27,卡死
* A1:0x00,0x00,0x00,0x00,0x00,0x00,卡死
* B:卡死
* B2:抓不到log
* B3:0x77,0xff,0x00,0x00,0x00,0x00,0x03,0x00,0x96,0x00,0x00,卡死
* 5.读取次数改成300次
* 超过256就会系统卡死
* 6.test进行多次循环
* {0x20,0x20},{0x00,fail},{}
* 7.sync改成全局变量
*/
/*
* 修改bootloader模式的上电时序,
* 进入boot高100msreset高500msreset低500ms
* 退出boot低100msreset高500msreset低500ms
* 1.单次读取串口数据 & 进入bootloader后直接返回(原来是读取数据直到结束才返回)
* a1:卡死
* a2:0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x10,0x00,0x00,0x00,0x00,0x00,卡死
* 2.单次读取串口数据 & 进入bootloader后读取数据直到结束才返回打印数据
* a1:打印数据后系统卡死,可能是esp的连接松动问题
* a2:
*/