EC600U_esp32_iap_uart/EC600U_uart1/uart1_modbus_master.c

427 lines
14 KiB
C
Raw Normal View History

2024-02-05 17:39:56 +08:00
#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.
*
* 48011
*
* 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:
*/