在开发项目中有时候串口被占用,通过网络回传log进行调试。
ESP32端:
1.tcp_log_define.h
重定义ESP32 log 输出函数,在需要发送的模块文件内包含这个头文件即可回传log
#ifndef __tcp_log_define_h__
#define __tcp_log_define_h__
#include "tcp_log.h"
#define printf(format, ... ) {socketSend(__FUNCTION__,ESP_LOG_INFO,format, ##__VA_ARGS__);}
#ifdef ESP_LOGE
#undef ESP_LOGE
#endif
#ifdef ESP_LOGW
#undef ESP_LOGW
#endif
#ifdef ESP_LOGI
#undef ESP_LOGI
#endif
#ifdef ESP_LOGD
#undef ESP_LOGD
#endif
#ifdef ESP_LOGV
#undef ESP_LOGV
#endif
#define ESP_LOGE( tag, format, ... ) {socketSend(tag,ESP_LOG_ERROR,format, ##__VA_ARGS__);}
#define ESP_LOGW( tag, format, ... ) {socketSend(tag,ESP_LOG_WARN,format, ##__VA_ARGS__);}
#define ESP_LOGI( tag, format, ... ) {socketSend(tag,ESP_LOG_INFO,format, ##__VA_ARGS__);}
#define ESP_LOGD( tag, format, ... ) {socketSend(tag,ESP_LOG_DEBUG,format, ##__VA_ARGS__);}
#define ESP_LOGV( tag, format, ... ) {socketSend(tag,ESP_LOG_VERBOSE,format, ##__VA_ARGS__);}
#endif /*#ifndef __tcp_log_define_h__*/
2.tcp_log.h
#ifndef __tcp_log_h__
#define __tcp_log_h__
#include "esp_netif.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "esp_log.h"
#define DEBUG_SOCKET_LOG
void socketSend(const char *tag,const esp_log_level_t level,const char* format, ...) __attribute__ ((format (printf, 3, 4)));
void tcp_client_task(void *pvParameters);
void print_stacktrace();
#endif /*#ifndef __tcp_log_h__*/
3.tcp_log.c
#include "tcp_log.h"
static volatile int mSock=-1;
#ifndef CONFIG_EXAMPLE_IPV4
#define CONFIG_EXAMPLE_IPV4
#endif
#ifdef CONFIG_EXAMPLE_IPV4
//#define HOST_IP_ADDR "192.168.88.45"
#define HOST_IP_ADDR "192.168.137.1"
#else
#define HOST_IP_ADDR CONFIG_EXAMPLE_IPV6_ADDR
#endif
#define PORT 48569
#define POLLING_DELAY_MS (1000)
#define TX_BUF_LEN (256)
#include "sdkconfig.h"
#include "esp_types.h"
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_debug_helpers.h"
#include "soc/soc_memory_layout.h"
#include "soc/cpu.h"
void print_stacktrace()
{
//Initialize stk_frame with first frame of stack
esp_backtrace_frame_t stk_frame;
esp_backtrace_get_start(&(stk_frame.pc), &(stk_frame.sp), &(stk_frame.next_pc));
//esp_cpu_get_backtrace_start(&stk_frame);
socketSend(__FUNCTION__,ESP_LOG_ERROR,"\r\n\r\nBacktrace:");
socketSend(__FUNCTION__,ESP_LOG_ERROR,"0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
//Check if first frame is valid
bool corrupted = (esp_stack_ptr_is_sane(stk_frame.sp) &&
esp_ptr_executable((void*)esp_cpu_process_stack_pc(stk_frame.pc))) ?
false : true;
uint32_t i = (100 <= 0) ? INT32_MAX : 100;
while (i-- > 0 && stk_frame.next_pc != 0 && !corrupted) {
if (!esp_backtrace_get_next_frame(&stk_frame)) { //Get previous stack frame
corrupted = true;
}
socketSend(__FUNCTION__,ESP_LOG_ERROR,"0x%08X:0x%08X ", esp_cpu_process_stack_pc(stk_frame.pc), stk_frame.sp);
}
//Print backtrace termination marker
esp_err_t ret = ESP_OK;
if (corrupted) {
socketSend(__FUNCTION__,ESP_LOG_ERROR," |<-CORRUPTED");
ret = ESP_FAIL;
} else if (stk_frame.next_pc != 0) { //Backtrace continues
socketSend(__FUNCTION__,ESP_LOG_ERROR," |<-CONTINUES");
}
socketSend(__FUNCTION__,ESP_LOG_ERROR,"%d\r\n\r\n",ret);
}
void socketSend(const char *tag,const esp_log_level_t level,const char* format, ...)
{
char tx_buffer[TX_BUF_LEN];
memset(tx_buffer,0,TX_BUF_LEN);
va_list args;
int tx_buf_len;
va_start(args, format);
tx_buf_len = vsprintf(tx_buffer, format, args);
va_end(args);
if(tag==NULL){
ESP_LOGI(__FUNCTION__, "%s",tx_buffer);
}
else {
switch(level){
case ESP_LOG_ERROR:
ESP_LOGE(tag, "%s",tx_buffer);
break;
case ESP_LOG_WARN:
ESP_LOGW(tag, "%s",tx_buffer);
break;
case ESP_LOG_INFO:
ESP_LOGI(tag, "%s",tx_buffer);
break;
case ESP_LOG_DEBUG:
ESP_LOGD(tag, "%s",tx_buffer);
break;
case ESP_LOG_VERBOSE:
ESP_LOGV(tag, "%s",tx_buffer);
break;
default:
ESP_LOGI(tag, "%s",tx_buffer);
break;
}
}
if(mSock<=0)
return;
*(tx_buffer+tx_buf_len)='\n';
int err = send(mSock, tx_buffer, tx_buf_len+1, 0);
if (err < 0) {
ESP_LOGE(__FUNCTION__, "Error occurred during sending: errno %d", errno);
mSock=-1;
}
}
void tcp_client_task(void *pvParameters)
{
char rx_buffer[128];
char addr_str[128];
int addr_family;
int ip_protocol;
//void *mem,size_t len
void(*p)(void *,size_t)=pvParameters;
#ifdef CONFIG_EXAMPLE_IPV4
struct sockaddr_in dest_addr;
dest_addr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR);
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(PORT);
addr_family = AF_INET;
ip_protocol = IPPROTO_IP;
inet_ntoa_r(dest_addr.sin_addr, addr_str, sizeof(addr_str) - 1);
#else // IPV6
struct sockaddr_in6 dest_addr = { 0 };
inet6_aton(HOST_IP_ADDR, &dest_addr.sin6_addr);
dest_addr.sin6_family = AF_INET6;
dest_addr.sin6_port = htons(PORT);
// Setting scope_id to the connecting interface for correct routing if IPv6 Local Link supplied
dest_addr.sin6_scope_id = esp_netif_get_netif_impl_index(EXAMPLE_INTERFACE);
addr_family = AF_INET6;
ip_protocol = IPPROTO_IPV6;
inet6_ntoa_r(dest_addr.sin6_addr, addr_str, sizeof(addr_str) - 1);
#endif
vTaskDelay(pdMS_TO_TICKS(10000));
while (1) {
int sock = socket(addr_family, SOCK_STREAM, ip_protocol);
if (sock < 0) {
ESP_LOGE(__FUNCTION__, "Unable to create socket: errno %d", errno);
vTaskDelay(pdMS_TO_TICKS(POLLING_DELAY_MS));
continue;
}
ESP_LOGI(__FUNCTION__, "Socket created, connecting to %s:%d", HOST_IP_ADDR, PORT);
int err = connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
if (err != 0) {
shutdown(sock, 0);
close(sock);
vTaskDelay(pdMS_TO_TICKS(POLLING_DELAY_MS));
continue;
}
mSock = sock;
ESP_LOGI(__FUNCTION__, "Successfully connected");
while (1) {
// int err = send(sock, rx_buffer, 1, 0);
//
// if (err < 0) {
// ESP_LOGE(__FUNCTION__, "Error occurred during sending: errno %d", errno);
// break;
// }
int len = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);
if(p != NULL)
p(rx_buffer,len);
// Error occurred during receiving
if (len < 0) {
ESP_LOGE(__FUNCTION__, "recv failed: errno %d", errno);
break;
}
// Data received
else {
// rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
// ESP_LOGI(__FUNCTION__, "Received %d bytes from %s:", len, addr_str);
// ESP_LOGI(__FUNCTION__, "%s", rx_buffer);
}
vTaskDelay(pdMS_TO_TICKS(POLLING_DELAY_MS));
}
if (sock != -1) {
ESP_LOGE(__FUNCTION__, "Shutting down socket and restarting...");
shutdown(sock, 0);
close(sock);
}
mSock = -1;
vTaskDelay(pdMS_TO_TICKS(POLLING_DELAY_MS));
}
vTaskDelete(NULL);
}
//xTaskCreate(tcp_client_task, "tcp_client", 4096, &recFunc, 5, NULL);
PC端:
public static void ServerFunc(){
// TODO Auto-generated method stub
ServerSocket s = null;
try{
s = new ServerSocket(48569);
}
catch(IOException e)
{
System.out.println(e);
System.exit(1);
}
while(true)
{
try{
Socket cs = s.accept();
try{
InputStream in = cs.getInputStream();
DataInputStream din = new DataInputStream(in);
byte[] datas = new byte[1024];
while (true) {
int ret = din.read(datas);
if(ret<0)
continue;
String str = new String(datas,"utf-8");
//打印接收到的log信息
System.out.println(tmp);
}
}
catch(IOException e)
{
System.out.println(e);
}
}
catch(IOException e)
{
System.out.println(e);
}
}
}