TCP UART Bridge for HM-MOD-RPI-PCB challenge
Posted: Sun Jun 24, 2018 1:30 pm
Hello Forum,
I try to make a solution sending Homematic data over WLan.
After struggeling around with configurations and serveral examples,
this code do basicly this function.
Unfortunately I'm faced with sporatic "Illagal Instruction" unhanled exceptions
after seconds or some minutes on CPU0 which leads to a hanging system or reboot.
I think I need something like a flow control but in which manner?
Events? Interrupt? SW flowcontrol? What is the common way in this case?
Maybe with a little example?
regards,
linuxpaul
I try to make a solution sending Homematic data over WLan.
After struggeling around with configurations and serveral examples,
this code do basicly this function.
Code: Select all
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "lwip/sockets.h"
#define PORT_NUMBER 23
#define WIFI_PW CONFIG_WIFI_PASSWORD
#define WIFI_SSID CONFIG_WIFI_SSID
#define EX_UART_NUM UART_NUM_1
#define BUF_SIZE 128
#define TXD_IO (GPIO_NUM_10)
#define RXD_IO (GPIO_NUM_9)
static struct sockaddr_in serverAddress;
static struct sockaddr_in clientAddress;
static char tag[] = "socket_server";
static int sock = -1;
static int clientSock = 0;
static uint8_t init_socket(void)
{
int ret = 0;
u32_t optlen = sizeof(ret);
socklen_t clientAddressLength = sizeof(clientAddress);
clientSock = accept(sock, (struct sockaddr *)&clientAddress, &clientAddressLength);
if (clientSock < 1) {
ESP_LOGE(tag, "NOT accept: %d %s", clientSock, strerror(errno));
return 0;
}
getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
ESP_LOGI(tag, "accept: %d %s ", clientSock, strerror(ret));
return 1;
}
static void uart_tx_Task(void *pvParameters)
{
static const char *TX_TAG = "TX_TASK";
esp_log_level_set(TX_TAG, ESP_LOG_INFO);
static const char *RX_TAG = "RX_TASK";
esp_log_level_set(RX_TAG, ESP_LOG_INFO);
uint8_t* txdata = (uint8_t*)malloc(10*BUF_SIZE);
uint8_t* rxdata = (uint8_t*)malloc(10*BUF_SIZE);
ssize_t socketRead;
ssize_t socketWrite;
int uartWrite;
int uartRead;
int ret = 0;
u32_t optlen = sizeof(ret);
uint8_t stateRead = 1;
uint8_t stateWrite = 0;
uint8_t client_connected = (uint8_t)init_socket();
while (1) {
if(! client_connected)
{
if(init_socket())
{
stateRead = 1;
stateWrite = 0;
client_connected = 1;
}
}
else if(client_connected && stateRead) {
socketRead = recv(clientSock, txdata, 10*BUF_SIZE, 0);
if (socketRead <= 0) {
getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
ESP_LOGE(tag, "Socket Closed: %d %s", clientSock, strerror(ret));
close(clientSock);
stateRead = 0;
stateWrite = 0;
client_connected = 0;
}
else {
uartWrite = uart_write_bytes(EX_UART_NUM, (const char*) txdata, socketRead);
ESP_LOGI(TX_TAG, "uart data Sent: %s, bytes: %d,", txdata,uartWrite);
// ESP_LOG_BUFFER_HEX(TX_TAG,txdata,uartWrite );
stateRead = 0;
stateWrite = 1;
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
else if(client_connected && stateWrite) {
uartRead = uart_read_bytes(EX_UART_NUM, rxdata, 10*BUF_SIZE, 100 / portTICK_PERIOD_MS);
if(uartRead > 0) {
ESP_LOGI(RX_TAG, "Uart Data receive:d %s, bytes: %d", rxdata,uartRead);
socketWrite = send(clientSock, rxdata, uartRead, 0);
if (socketWrite <= 0) {
getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &ret, &optlen);
ESP_LOGE(tag, "Socket Closed: %d %s", clientSock, strerror(ret));
close(clientSock);
stateRead = 0;
stateWrite = 0;
client_connected = 0;
}
else {
ESP_LOGI(RX_TAG, "Data sent Socket: %s, bytes: %d, socket %d", rxdata, socketWrite,clientSock);
// ESP_LOG_BUFFER_HEX(RX_TAG,rxdata,socketWrite );
stateRead = 1;
stateWrite = 0;
}
}
}
}
vTaskDelete(NULL);
}
static void tcp_sock_init(void)
{
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock < 0) {
ESP_LOGE(tag, "socket: %d %s", sock, strerror(errno));
exit(1);
}
ESP_LOGI(tag, "socket created");
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddress.sin_port = htons(PORT_NUMBER);
int rc = bind(sock, (struct sockaddr *)&serverAddress, sizeof(serverAddress));
if (rc < 0) {
ESP_LOGE(tag, "bind: %d %s", rc, strerror(errno));
exit(1);
}
ESP_LOGI(tag, "socket bound");
rc = listen(sock,1);
if (rc < 0) {
ESP_LOGE(tag, "listen: %d %s", rc, strerror(errno));
exit(1);
}
ESP_LOGI(tag, "socket listen");
xTaskCreate(uart_tx_Task, "uart_tx_Task", 4000, NULL, 5, NULL);
}
esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id){
case SYSTEM_EVENT_STA_GOT_IP:
printf("Our IP address is " IPSTR "\n", IP2STR(&event->event_info.got_ip.ip_info.ip));
printf("Starting TCP Socket Init...\n");
tcp_sock_init();
break;
case SYSTEM_EVENT_WIFI_READY:
printf("Wifi ready\n");
break;
case SYSTEM_EVENT_STA_START:
printf("Station started\n");
break;
case SYSTEM_EVENT_STA_CONNECTED:
printf("Station connected\n");
break;
default:
printf("Other Event\n");
break;
}
return ESP_OK;
}
static void wifi_init(void)
{
ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
wifi_config_t sta_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PW,
.bssid_set = false
}
};
ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_STA, &sta_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
ESP_ERROR_CHECK( esp_wifi_connect() );
}
static void uart_init(void)
{
/* Configure parameters of an UART driver,
* communication pins and install the driver */
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(EX_UART_NUM, &uart_config);
uart_set_pin(EX_UART_NUM, TXD_IO, RXD_IO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0);
}
void app_main(void)
{
nvs_flash_init();
tcpip_adapter_init();
wifi_init();
uart_init();
gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
int level = 0;
while (true) {
gpio_set_level(GPIO_NUM_2, level);
level = !level;
vTaskDelay(500 / portTICK_PERIOD_MS);
}
}
after seconds or some minutes on CPU0 which leads to a hanging system or reboot.
I think I need something like a flow control but in which manner?
Events? Interrupt? SW flowcontrol? What is the common way in this case?
Maybe with a little example?
regards,
linuxpaul