Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
2 / 2 / 1
Регистрация: 10.11.2016
Сообщений: 94
1

LwIP Raw API отправка данных

29.01.2019, 07:54. Просмотров 2132. Ответов 1

Добрый день. Я реализовал TCP эхо сервер на своей stm32 nucleo, прием и передача работает как надо, т.е. при отправки чего-либо с ПК на плату данные принимаются платой и отправляются сразу обратно.

Подскажите, пожалуйста, как реализовать отправку данных с платы на ПК, например, по нажатию кнопки, вместо отправки той же команды в ответ.

Прилагаю код реализации эхо сервера, основа взята из примера к LwIP:
Файл net.c
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/tcp.h"
 
extern char tcp_buffer[1024];
extern char user_data[1024];
struct tcp_pcb *tcp_pcb;
 
static void close_conn (struct tcp_pcb *pcb )
{
    tcp_arg(pcb, NULL);
    tcp_sent(pcb, NULL);
    tcp_recv(pcb, NULL);
    tcp_close(pcb);
}
static err_t echo_recv( void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err )
{
    int i;
    int len;
    char *pc;
    int n = 0;
    
    if ( err == ERR_OK && p != NULL )
    {
        tcp_recved( pcb, p->tot_len );
        pc = (char *)p->payload;
        len =p->tot_len;
                
        for( i=0; i<len; i++ )
        {
            tcp_buffer[i] = pc[i];
        }
 
        if( tcp_buffer[0] == 'X' )
            close_conn( pcb );
 
        pbuf_free( p );
 
        if( len > tcp_sndbuf( pcb ) )
            len= tcp_sndbuf( pcb );
 
    for (int i = 0; i<1024; i++)
    {
        user_data[i] = 0;
    }
 
    for (int i = 0; i<len; i++)
    {
        user_data[i] = tcp_buffer[i];
    }
 
    //начало обработчика
    if (user_data[0] == 0x01) /если пришла команда 1
    {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);  // включаем светодиод
    }
    else //если другая
    {
            HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
    }
    // конец обработчика
                
    tcp_write( pcb, tcp_buffer, len, 0 ); //отправляем данные обратно
    tcp_sent( pcb, NULL );
    }
    else
    {
        pbuf_free( p );
    }
 
    if( err == ERR_OK && p == NULL )
    {
        close_conn( pcb );
    }
 
    return ERR_OK;
}
 
static err_t echo_accept(void *arg, struct tcp_pcb *pcb, err_t err )
{
    LWIP_UNUSED_ARG( arg );
    LWIP_UNUSED_ARG( err );
    tcp_setprio( pcb, TCP_PRIO_MIN );
    tcp_recv( pcb, echo_recv );
    tcp_err( pcb, NULL );
    tcp_poll( pcb, NULL, 4 );
    return ERR_OK;
}
 
void tcp_ini( void )
{
    tcp_pcb = tcp_new();
    tcp_bind(tcp_pcb, IP_ADDR_ANY, 80);
    tcp_pcb = tcp_listen( tcp_pcb );
    tcp_accept( tcp_pcb, echo_accept );
}

Файл main.c
Кликните здесь для просмотра всего текста

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "main.h"
#include "stm32f7xx_hal.h"
#include "lwip.h"
#include "gpio.h"
#include "net.h"
#include "stdbool.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/tcp.h"
#include "math.h"
 
extern struct netif gnetif;
extern struct tcp_pcb *tcp_pcb;
char user_data[1024] = {0}; //массивы данных, полученных по ethernet
char tcp_buffer[1024]; 
 
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_LWIP_Init();
 
  tcp_ini(); //инициализация tcp 
 
  while (1)
  {
    ethernetif_input(&gnetif);
    sys_check_timeouts();
  }
}


Я пробовал реализовать это так:
Убрал строки
C
1
2
  tcp_write( pcb, tcp_buffer, len, 0 ); //отправляем данные обратно
  tcp_sent( pcb, NULL );
из файла net.c и перенес в main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool button = 0;
bool flag = 0;
char d[64];
 while (1)
 {
    button = HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13); //опрашиваем кнопку
    if (button == 1)
    {
        flag = 1;
    }
    if (flag == 1)
    {
          for (int i = 0; i<64; i++) //формируем данные
          {
          d[i] = (char)i;
          }
          tcp_write(tcp_pcb, d, 64, 0); //ставим данные в очередь на отправку.
          tcp_output(tcp_pcb); //tcp_sent( pcb, NULL ); заменил на tcp_output(tcp_pcb); чтобы отправлять данные немедленно
          flag = 0;
    }
    ethernetif_input(&gnetif);
    sys_check_timeouts();
 }
Структуру tcp_pcb создавал глобально. Передача по кнопке не работает.

Буду рад любой помощи, спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.01.2019, 07:54
Ответы с готовыми решениями:

lwIP +httpd + отправка файла?
Доброго времени суток! Не так давно начал разбираться с lwIP стеком и примером Web-сервера под...

Можно ли на netconn api LwIP сделать сервер с несколькими подключениями на один порт
Добрый вечер, целый день сегодня потратил в поисках решения такой задачи На один порт может...

LwIP http без LwIP стека
Всем доброго дня! А кто нибудь пробовал отделить LwIP http веб сервер от самого LwIP стека,...

STM32F437 + lwIP 1.4.1(netcon), прием большого кол-ва данных
Отправляю файл в 200 кбайт на МК. По логам вижу, как летят мелкие пакеты по 20-1450 байт. Вопрос в...

1
35 / 29 / 10
Регистрация: 22.09.2017
Сообщений: 94
29.01.2019, 20:51 2
Вот рабочий код, правда на netconn и UDP, но это легко переделать на TCP.


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
static struct netconn *conn;
static struct netbuf  *buf;
static struct ip_addr *addr;
static unsigned short port;
 
 
static void udp_thread(void *arg)
{
  err_t err;
  u16_t i = 0;
  u8_t *p = 0 ;
  
  LWIP_UNUSED_ARG(arg);
 
  conn = netconn_new(NETCONN_UDP);
  if (conn!= NULL)
  {
    err = netconn_bind(conn, IP_ADDR_ANY, 5001);
    if (err == ERR_OK)
    {
      while (1) 
      {
        buf = netconn_recv(conn);
      
        if (buf!= NULL) 
        {
          p = buf->p->payload;
          for(i = 0; i < buf->p->len; i++)
            err = xQueueSend(ReceiveQ[UDP], (const void *)&p[i], 0);
        }
      }
    }
    else
    {
      printf("can not bind netconn");
    }
  }
  else
  {
    printf("can create new UDP netconn");
  }
}
 
 
// отправка пакета
void UDP_SendPacket(u8_t *data, u16_t len)
{
  addr = netbuf_fromaddr(buf);
  port = netbuf_fromport(buf);
  netconn_connect(conn, addr, port);
  buf->addr = NULL;
            
  buf->p->len = len;
  buf->p->tot_len = len;
  buf->p->payload = data;
  
  netconn_send(conn, buf);
  netbuf_delete(buf);
}
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.01.2019, 20:51

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Отправка документов VK API
Добрый день, подскажите пожалуйста, в чем может быть проблема, хочу загрузить документ в сообщения...

VK.API - Отправка фото
Доброго времени суток! Столкнулся с проблемой при отправке картинки в CURL на api.vk Есть код:...

Отправка СМС в API 15
Здравствуйте. Столкнулся с проблемой в API 15. При попытке отправки СМС сообщения из приложения оно...

Преобразование Raw-данных в AIFF
Пытаюсь считать Raw дату, и сформировать из него AIFF файл с заголовком и датой. Тоже самое делал с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.