реклама на сайте
подробности

 
 
> LwIP стек в STM32F217
Acvarif
сообщение Jan 12 2012, 09:42
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



На st имеется демка под LwIP на stm32f207 для PHY DP83848C (режим MII) (в демке реализованы почти все возможные варианты серверов и клиентов).
Поскольку у меня на столе имеется платка с stm32f217 + phy ks8721bl (режим RMII) пришлось демку LwIP переделать под нее (не поленился переделал все демки в том числе и под FREE RTOS). Все приложения работают без проблем. Вот ссылка на архив (большой ~47м ). (переделаны проекты для Keil, проекты под IAR переделываюся только сменой камня. Все работает также без проблем) Но остался вопрос.
Нормального понимания как работать с LwIP + stm32 пока нет. Дока на стек и демку не проясняет.
У кого есть опыт работы с LwIP + stm32 подсобите please для старта простым примером LwIP как принять одни данные по UDP и отправить другие.
В демке имеется UDP эхо сервер. Поможет даже подсказка как сделать так, чтобы сервер отправлял не эхо, а конкретные данные из конкретного буфера типа *my_buf.

Спасибо.

В main все начинается так:

Код
    /* check if any packet received */
    if (ETH_CheckFrameReceived())
    {
      /* process received ethernet packet */
      LwIP_Pkt_Handle();
    }


Функция ETH_CheckFrameReceived делает это:
CODE
/**
* @brief This function polls for a frame reception
* @param None
* @retval Returns 1 when a frame is received, 0 if none.
*/
uint32_t ETH_CheckFrameReceived(void)
{
/* check if last segment */
if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) != (uint32_t)RESET))
{
DMA_RX_FRAME_infos->LS_Rx_Desc = DMARxDescToGet;
DMA_RX_FRAME_infos->Seg_Count++;
return 1;
}

/* check if first segment */
else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) != (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
{
DMA_RX_FRAME_infos->FS_Rx_Desc = DMARxDescToGet;
DMA_RX_FRAME_infos->LS_Rx_Desc = NULL;
DMA_RX_FRAME_infos->Seg_Count = 1;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}

/* check if intermediate segment */
else if(((DMARxDescToGet->Status & ETH_DMARxDesc_OWN) == (uint32_t)RESET) &&
((DMARxDescToGet->Status & ETH_DMARxDesc_FS) == (uint32_t)RESET)&&
((DMARxDescToGet->Status & ETH_DMARxDesc_LS) == (uint32_t)RESET))
{
(DMA_RX_FRAME_infos->Seg_Count) ++;
DMARxDescToGet = (ETH_DMADESCTypeDef*) (DMARxDescToGet->Buffer2NextDescAddr);
}
return 0;
}

Я так понимаю, что функция проверяет имеется ли что-то в DMA В частности если имеется фрейм и сегмент в фрейме последний, то возвращается 1.
Что такое последний сегмент? Понимаю, что можно послать меня на очередной мануал. Но мануалы меня уже сильно достали из за их непоследовательности и часто бесполезности.
Ответьте пожалуйста на русском коротко работу функции ETH_CheckFrameReceived(void) (функция почемуто всегда, послал я фрейм или нет, возвращает 1)
Дальше начинается кошмар по имени
Код
      /* process received ethernet packet */
      LwIP_Pkt_Handle();
который далее переходит в
Код
  /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */
  ethernetif_input(&netif);

и куда дальше попадают собственно данные посланного из компа UDP пакета, так, чтобы с ними можно было -бы поработать и как послать компу ответ в виде своего пакета (а не того же самого) не допираю.
Подсобите, кто сталкивался с этим.
Нашел пока это http://lwip.wikia.com/wiki/Raw/UDP
Всеравно не понятно как на базе LwIP послать на комп UDP пакет Ну допустим так:

Код
   struct udp_pcb *upcb;
   /* Create a new UDP control block  */
   upcb = udp_new();    
   /* Bind the upcb to the UDP_PORT port */
   /* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
   udp_bind(upcb, IP_ADDR_ANY, 23);
  /* Connect to the remote client */
  udp_connect(upcb, addr, 23);

В каком виде нужно записать addr?
Похоже, что дальше можно
Код
udp_send(struct udp_pcb * pcb, struct pbuf * p)

тоесть
Код
udp_send(upcb, p);

Что такое struct pbuf * p

Сообщение отредактировал Acvarif - Jan 12 2012, 14:48
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 58)
kan35
сообщение Jan 12 2012, 15:49
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Дока на lwIP существует, она вполне полезная, по крайней мере описание API нужно там изучить.
Я советую пользоваться только под FreeRTOS в силу того, что в ней как мне кажется существенно проще работать.

Создать дескриптор и соединение TCP (или UDP - по аналогии):
Код
struct netconn * conn;
conn = netconn_new(NETCONN_TCP);
struct ip_addr addr;
addr.addr = inet_addr("193.193.165.165");
unsigned short server_port = 45321;
if (netconn_connect(conn, &addr, server_port) == ERR_OK)
...

Отправить данные
Код
netconn_write(conn, "Hello...", strlen("Hello..."), NETCONN_NOCOPY);// передача данных

Принять данные в netbuf
Код
struct netbuf * in_buf = netconn_recv(conn)
..../// сделал что нужно с данными и удалил буфер
netbuf_delete(in_buf);

Еще можно добавить что netbuf это структура, описывающая склейку некоторого количества маленьких буферов, в ней храняться указатели на предыдущий буфер и на последующий и проч, работать напрямую не удобно, да и не нужно, так как в stm памяти достаточно чтобы с помощью API вытащить из буфера данные в линейный массив:
Код
unsigned long buflen = netbuf_len(in_buf);
incoming_data = (char *)pvPortMalloc(buflen);
netbuf_copy(in_buf, incoming_data, buflen);

Здесь и везде по стеку используется куча, потому не забываем удалять выделенные области после изспользования. Все примеры на функциях из доки на lwIP.
Конечно можно перейти на нижний уровень или на верхний - с сокетами, но я рекомендую начать netconn API.

Сообщение отредактировал kan35 - Jan 12 2012, 16:01
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 13 2012, 06:43
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Спасибо. Начало проясняться.

Удалось послать строку по UDP на комп. Смутно понимаю (придется таки почитать мануал на LwIP), как стек это делает, в коде это достаточно просто.

CODE
struct udp_pcb *upcb;
struct pbuf *p;
struct ip_addr DestIPaddr;
char tdata[] = {"Test"};
char *data = tdata;

/* Create a new UDP control block */
upcb = udp_new();
/*assign destination IP address */
IP4_ADDR( &DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
/* configure destination IP address and port */
udp_connect(upcb, &DestIPaddr, UDP_SERVER_PORT);
/* allocate pbuf from pool*/
p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)data), PBUF_POOL);
/* copy data to pbuf */
pbuf_take(p, (char*)data, strlen((char*)data));
/* send udp data */
udp_send(upcb, p);

После этого очевидно нужно еще разорвать соединение и освободить занятую память
Код
/* Reset the upcb */
   udp_disconnect(upcb);
/* Free the p buffer */
   pbuf_free(p);


Сообщение отредактировал Acvarif - Jan 13 2012, 06:43
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 13 2012, 07:33
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Вы продолжаете работать на уровне pcb, я же предлагаю использовать netbuf API и netconn интерфейс или socket интерфейс и будет работать не сложнее чем с сериальным портом.
Вот пример из доки в полной мере делающий то же что и ваш код
CODE
int
main()
{
struct netconn *conn;
struct netbuf *buf;
struct ip_addr addr;
char *data;
char text[] = "A static text";
int i;
/* create a new connection */
conn = netconn_new(NETCONN_UDP);
/* set up the IP address of the remote host */
addr.addr = htonl(0x0a000001);
/* connect the connection to the remote host */
netconn_connect(conn, &addr, 7000);
/* create a new netbuf */
buf = netbuf_new();
data = netbuf_alloc(buf, 10);
/* create some arbitrary data */
for(i = 0; i < 10; i++)
data[i] = i;
/* send the arbitrary data */
netconn_send(conn, buf);
/* reference the text into the netbuf */
netbuf_ref(buf, text, sizeof(text));
/* send the text */
netconn_send(conn, buf);
/* deallocate connection and netbuf */
netconn_delete(conn);
netconn_delete(buf);
}
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 13 2012, 11:39
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата
Вы продолжаете работать на уровне pcb, я же предлагаю использовать netbuf API и netconn интерфейс или socket интерфейс и будет работать не сложнее чем с сериальным портом.

Нет. Просто меня пробило как передать пакет на уровне pcb (без глубокого копания).

Конечно же я попробую Ваше предложение, тем более, если это не сложнее Com.
Спасибо за пример. В доке действительно все расписано. Но...

Пытаюсь откомпилировать...Не хватает нужных #include для вызываемых функций. Попробую поискать в файлах стека где они спрятаны.

Сообщение отредактировал Acvarif - Jan 13 2012, 12:02
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 13 2012, 13:03
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(Acvarif @ Jan 13 2012, 15:39) *
Пытаюсь откомпилировать...Не хватает нужных #include для вызываемых функций. Попробую поискать в файлах стека где они спрятаны.


К проекту из LwIP подключена папка api где имеются файлы netbuf.c, api_lib.c

При компиляции выскакивает:

compiling main.c...
..\src\main.c(134): warning: #223-D: function "netconn_new" declared implicitly
..\src\main.c(134): error: #20: identifier "NETCONN_UDP" is undefined
..\src\main.c(134): error: #513: a value of type "int" cannot be assigned to an entity of type "struct netconn *"
..\src\main.c(138): warning: #223-D: function "netconn_connect" declared implicitly
..\src\main.c(146): warning: #223-D: function "netconn_send" declared implicitly
..\src\main.c(152): warning: #223-D: function "netconn_delete" declared implicitly
..\src\main.c - 2 Error(s), 4 Warning(s).

Например NETCONN_UDP находится в api.h который в свою очередь подключен к api_lib.c

Пока непонятно что не так.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 13 2012, 14:51
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Все прояснилось. Мануал 2001 года подходит для LwIP 1.1.0, а в демках применен LwIP 1.3.2 (хотя заголовок демки именуется как STM32F2x7_ETH_LwIP_V1.1.0)
В новой версии стека нет netconn_new(NETCONN_UDP); и т. д.

Там есть struct netconn * netconn_new_with_proto_and_callback (enum netconn_type t, u8_t proto, netconn_callback callback)
Что это и с чем его едят придется разбираться. Примеров использования пока не нашел.

Сообщение отредактировал Acvarif - Jan 13 2012, 14:52
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 13 2012, 16:34
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Чтобы активировать те или иные Api кроме того, чтобы включить файлы надо настроить стек. Делается это в файле lwipopt.h
У вас должно быть так:
Код
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN                    1

и пока что мануал актуален на все 100

Сообщение отредактировал kan35 - Jan 13 2012, 16:37
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 13 2012, 18:58
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Спасибо. Почти получилось...
Портит картину netconn_delete(buf);
..\src\main.c(154): error: #167: argument of type "struct netbuf *" is incompatible with parameter of type "struct netconn *"
Очевидно в мануале ошибка
Нужно так
Код
netconn_delete(conn);
netbuf_delete(buf);

В понедельник проверю на железе.
Спасибо kan35
Удачного Старого Нового Года!

Сообщение отредактировал IgorKossak - Jan 14 2012, 16:56
Причина редактирования: Бездумное цитирование
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 14 2012, 13:40
Сообщение #10


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Таки не выдержал. Попытался откомпилировать весь проект. Для удобства поиска в файлах перешел с Keil на IAR (принципиально ничего не меняется) Напоролся на недопонимание в файлах api_lib.c, api_msg.c
api_lib.c - выскочила куча ошибок и предупреждений. Интуиция подсказала, что в файле не хватает
#include "lwip/api_msg.h" После компиляции количество непоняток уменьшилось но не совсем...
CODE
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 82
Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_lib.c 86
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_lib.c 87
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_lib.c 88
Warning[Pe223]: function "tcpip_apimsg" declared implicitly \src\api\api_lib.c 118
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 151
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 177
Warning[Pe223]: function "tcpip_apimsg" declared implicitly \src\api\api_lib.c 201
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 220
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 247
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_lib.c 263
Warning[Pe223]: function "sys_arch_mbox_fetch" declared implicitly \src\api\api_lib.c 270
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_lib.c 306
Warning[Pe223]: function "sys_arch_mbox_fetch" declared implicitly \src\api\api_lib.c 339
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 375
Warning[Pe223]: function "sys_arch_mbox_fetch" declared implicitly \src\api\api_lib.c 384
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 438
Warning[Pe223]: function "TCPIP_APIMSG" declared implicitly \src\api\api_lib.c 469
Warning[Pe223]: function "tcpip_apimsg" declared implicitly \src\api\api_lib.c 488

Например Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_lib.c 86
касается этого
Код
LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL);

Warning[Pe223]: function "tcpip_apimsg" declared implicitly \src\api\api_lib.c 118
касается этого
Код
tcpip_apimsg(&msg);


Для api_msg.c еще больше непоняток.
CODE
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 93
Error[Pe029]: expected an expression \src\api\api_msg.c 116
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 159
Error[Pe029]: expected an expression \src\api\api_msg.c 185
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 215
Error[Pe029]: expected an expression \src\api\api_msg.c 227
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 314
Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_msg.c 319
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 323
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 376
Error[Pe029]: expected an expression \src\api\api_msg.c 388
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 482
Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_msg.c 536
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 540
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 546
Warning[Pe550]: variable "size" was set but never used \src\api\api_msg.c 499
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 581
Error[Pe029]: expected an expression \src\api\api_msg.c 582
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 596
Error[Pe029]: expected an expression \src\api\api_msg.c 597
Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_msg.c 605
Error[Pe020]: identifier "SYS_SEM_NULL" is undefined \src\api\api_msg.c 709
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 750
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 843
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 869
Error[Pe020]: identifier "SYS_MBOX_NULL" is undefined \src\api\api_msg.c 874
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 893
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 931
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 959
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 1097
Warning[Pe223]: function "TCPIP_APIMSG_ACK" declared implicitly \src\api\api_msg.c 1145


Пытался найти решение проблем в настройках lwipopts.h - не получилось.
В стеке еще имеется файл opt.h но как с ним работать непонятно. Файл вообще с атрибутами только для чтения.
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 14 2012, 17:05
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



opt.h - это настройки по умолчанию, их не стоит трогать, потому он read only
lwipopt.h - это файл для настройки пользователем, они имеют приоритет над настройками по умолчанию, его и крутите

Как я понимаю все эти ошибки из за того, что стек не видит FreeRTOS.
И еще, файлы sys_arch являются связкой между FreeRTOS и lwIP и тоже должны иметься в проекте.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 14 2012, 18:17
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Понял. Спасибо. Файл нашел.
Можно ли подружить этот файл ( sys_arch.h) со стеком без FreeRTOS?
Вроде в нем есть то чего не хватает для нормальной компиляции api_lib.c, api_msg.c
Наверняка должен же как то стек (имеется ввиду netbuf API и netconn ) работать в stm32 и без какой-либо операционной системы (уровень pcb работает без ОС).
Очевидно для работы стека в режиме netbuf API и netconn без ОС нужны другие файлы api_lib.c, api_msg.c и может еще некоторые другие h файлы.

Сообщение отредактировал Acvarif - Jan 14 2012, 18:46
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 14 2012, 19:04
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Должен работать конечно, но нюансов не скажу, так как я так же как и вы взял пример от ST и кручу его под свою задачу.
И вы берите пример с ОС, как я и посоветовал в первом своем посте, грех на таком чипе без нее что либо вообще делать. Самому FreeRTOS можно конечно приладить, но без опыта можно долго биться, да и зачем когда есть пример.
Немного лирики. Отличие с ОС и без ОС в том, что без ОС надо по таймерам вызывать определенные процедуры из стека, ловить пакеты через callback-и и прочие неудобства, а когда ОС - просто крутится поток, а взаимодействие стека с вашим приложением идет через через API, которые используют сервисы ОС и в итоге интерфейс с lwIP становится совершенно элементарным.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 14 2012, 19:35
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Понял. Спасибо. С ОС стек компилится без проблем. Попробую уровень netbuf API и netconn.
Go to the top of the page
 
+Quote Post
MK2
сообщение Jan 15 2012, 18:20
Сообщение #15


Местный
***

Группа: Свой
Сообщений: 202
Регистрация: 30-10-10
Пользователь №: 60 535



А чем вы с компьютера посылали пакеты?
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 16 2012, 06:36
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(MK2 @ Jan 15 2012, 22:20) *
А чем вы с компьютера посылали пакеты?


Да вот этой штукой http://www.hw-group.com/products/hercules/index_en.html Хотя в демке есть программки (вроде под DOS), но они лишены визуальности - работать неудобно.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 16 2012, 13:23
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



В общем вроде все получилось. Использовал имеющийся в демке проект под FreeRTOS udptcp_echo_server_netconn
и функцию мигания светодиодом void ToggleLed4(void * pvParameters).
Немного ее модифицировал:
CODE
void ToggleLed4(void * pvParameters)
{
struct netconn *connn;
struct netbuf *buf1;
struct netbuf *buf2;
struct ip_addr addr;
char *data1;
char *data2;
char text1[] = "Hello,my name is SK-STM32F217\n\r";
char text2[] = "I am transmit UDP package\n\r";
int i,n = 0;

/* create a new connection */
connn = netconn_new(NETCONN_UDP);
/* set up the IP address of the remote host */
addr.addr = htonl(0xC0A802A8);
/* connect the connection to the remote host */
netconn_connect(connn, &addr, 7);
/* create a new netbuf */
buf1 = netbuf_new();
buf2 = netbuf_new();

while(1)
{
test = xnetif.ip_addr.addr;
/*check if IP address assigned*/
if (test !=0)
{
for( ;; )
{
/* toggle LED1 each 250ms */
STM_EVAL_LEDToggle(LED1);
vTaskDelay(1000);

data1 = netbuf_alloc(buf1, strlen(text1));
/* create some arbitrary data */
for(i = 0; i < sizeof(text1); i++)
data1[i] = text1[i];

data2 = netbuf_alloc(buf2, strlen(text2));
/* create some arbitrary data */
for(i = 0; i < sizeof(text2); i++)
data2[i] = text2[i];
if(n == 0)
{
n = 1;
netbuf_ref(buf1, text1, strlen(text1));
netconn_send(connn, buf1);
netbuf_delete(buf1);
}
else
{
n = 0;
netbuf_ref(buf2, text2, strlen(text2));
netconn_send(connn, buf2);
netbuf_delete(buf2);
}
}
}
}
}


Все вроде работает. Теперь стала задача подсчитать скорость передачи, а заодно и проверить надежность передающей системы.
Как можно это сделать на базе этой функции.
Ну допустим запустить цикл передачи в 1000 пакетов по 256 байт и осциллоскопом как-то (пока не представляю как) померять период передачи 1000 пакетов.
Может можно както без осциллоскопа?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 13:36
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Acvarif @ Jan 16 2012, 17:23) *
Все вроде работает. Теперь стала задача подсчитать скорость передачи, а заодно и проверить надежность передающей системы.
Как можно это сделать на базе этой функции.
Ну допустим запустить цикл передачи в 1000 пакетов по 256 байт и осциллоскопом как-то (пока не представляю как) померять период передачи 1000 пакетов.

В MAC есть счётчики для различной статистики (например, число отправленных и принятых пакетов). Просто смотрите их содержимое до и после "передачи в 1000 пакетов по 256 байт". То же самое полезно проделать со стороны ПК.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 16 2012, 14:52
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(scifi @ Jan 16 2012, 17:36) *
В MAC есть счётчики для различной статистики (например, число отправленных и принятых пакетов). Просто смотрите их содержимое до и после "передачи в 1000 пакетов по 256 байт". То же самое полезно проделать со стороны ПК.


Спасибо за информацию. Посмотрю.
Попытался сделать влоб, поставив светодиод (вроде должен индицировать время передачи 1000 пакетов) типа так:
CODE

...
STM_EVAL_LEDOn(LED2);
for(j = 0; j < 1000; j++)
{
data1 = netbuf_alloc(buf1, strlen(text1));
/* create some arbitrary data */
for(i = 0; i < sizeof(text1); i++)
data1[i] = text1[i];

data2 = netbuf_alloc(buf2, strlen(text2));
/* create some arbitrary data */
for(i = 0; i < sizeof(text2); i++)
data2[i] = text2[i];

if(n == 0)
{
n = 1;
netbuf_ref(buf1, text1, strlen(text1));
netconn_send(connn, buf1);
netbuf_delete(buf1);
}
else
{
n = 0;
netbuf_ref(buf2, text2, strlen(text2));
netconn_send(connn, buf2);
netbuf_delete(buf2);
}
}
STM_EVAL_LEDOff(LED2);
}

Но очевидно так будет не корректно. Не знаю почему но пакет из ~10 000 байт светодиод отсчитывает за 160 мс, что очень много для скорости в TBase100
Хотя я не уверен, что скорость Mac выставлена 100. Покак не допру где это утанавливается. Да даже если скорость 10 всеравно 160мс это многовато будет.

Сообщение отредактировал Acvarif - Jan 16 2012, 14:54
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 19:43
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Acvarif @ Jan 16 2012, 18:52) *
Но очевидно так будет не корректно. Не знаю почему но пакет из ~10 000 байт светодиод отсчитывает за 160 мс, что очень много для скорости в TBase100
Хотя я не уверен, что скорость Mac выставлена 100. Покак не допру где это утанавливается. Да даже если скорость 10 всеравно 160мс это многовато будет.

Пакет 10000 байт? Вы в курсе, что макс. размер кадра Ethernet - это 1500 байт или около того? Это если не учитывать экзотику типа Jumbo Frame. Значит, пакет фрагментируется на уровне IP. Я думаю, скорость физического уровня здесь ни при чём. В lwip есть огромное множество настроек, которые могут влиять на самые разные вещи, включая задержки при пересылке. Но это только предположение.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 16 2012, 20:16
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(scifi @ Jan 16 2012, 22:43) *
Пакет 10000 байт? Вы в курсе, что макс. размер кадра Ethernet - это 1500 байт или около того? Это если не учитывать экзотику типа Jumbo Frame. Значит, пакет фрагментируется на уровне IP. Я думаю, скорость физического уровня здесь ни при чём. В lwip есть огромное множество настроек, которые могут влиять на самые разные вещи, включая задержки при пересылке. Но это только предположение.

Да, я в курсе. Просто я передаю 1000 кадров по 100 байт в каждом. Опять же, наверняка так не корректно. Очевидно нужно передавать просто один кадр, например 500 байт, и как то определять его период. Хотя и в этом не уверен.
Буду признателен, за подсказку - технологию определения скорости.
И вообще интересует вопрос реально ли на LwIP + FreeRtos + UDP + stm32f217 получить сорость ~90..100?
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jan 17 2012, 08:45
Сообщение #22


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата(Acvarif @ Jan 16 2012, 22:16) *
Да, я в курсе. Просто я передаю 1000 кадров по 100 байт в каждом. Опять же, наверняка так не корректно. Очевидно нужно передавать просто один кадр, например 500 байт, и как то определять его период. Хотя и в этом не уверен.
Буду признателен, за подсказку - технологию определения скорости.
И вообще интересует вопрос реально ли на LwIP + FreeRtos + UDP + stm32f217 получить сорость ~90..100?


90 реально, но не по 100 байт, как минимум 512, а то и 1024
Go to the top of the page
 
+Quote Post
sparcmaster
сообщение Jan 17 2012, 08:51
Сообщение #23


Частый гость
**

Группа: Свой
Сообщений: 93
Регистрация: 13-01-12
Из: Гатчина
Пользователь №: 69 333



Цитата(Acvarif @ Jan 17 2012, 00:16) *
Буду признателен, за подсказку - технологию определения скорости.

Я в свое время для оценки скорости замерял за сколько девайс отдаст файл размером в 100 мбайт.
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 17 2012, 09:11
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Цитата(Acvarif @ Jan 16 2012, 17:52) *
Но очевидно так будет не корректно. Не знаю почему но пакет из ~10 000 байт светодиод отсчитывает за 160 мс, что очень много для скорости в TBase100
Хотя я не уверен, что скорость Mac выставлена 100. Покак не допру где это утанавливается. Да даже если скорость 10 всеравно 160мс это многовато будет.


Параметр TCP_WND сильно на скорость передачи влияет. Увеличить его попробуйте.
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jan 17 2012, 09:44
Сообщение #25


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Буду признателен, за подсказку - технологию определения скорости.


Я пользуюсь этой
iperf
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 17 2012, 11:10
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(=F8= @ Jan 17 2012, 13:11) *
Параметр TCP_WND сильно на скорость передачи влияет. Увеличить его попробуйте.

Это из рубрики "Вредные советы"? :-)
Каким образом TCP_WND может повлиять на UDP?
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 17 2012, 12:37
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Цитата(scifi @ Jan 17 2012, 14:10) *
Это из рубрики "Вредные советы"? :-)
Каким образом TCP_WND может повлиять на UDP?

Сорри, недосмотрел. На UDP никак.
Go to the top of the page
 
+Quote Post
Twen
сообщение Jan 17 2012, 12:38
Сообщение #28


Частый гость
**

Группа: Участник
Сообщений: 163
Регистрация: 7-02-09
Пользователь №: 44 543



Аналогично использую МК stm32 + LwIp на FreeRTOS, при ключении прибора не всегда начинает пинговаться, после нескольких сбросов отвечает, хотя эзернет модуль принимает данные(проверено)...У кого нибудь возник еще такая проблема?
Хотя, когда прошил пример без ОС udp_echo_server, пингуется ставильно после вкл./выкл. питания.

Сообщение отредактировал Twen - Jan 17 2012, 13:04
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 17 2012, 13:25
Сообщение #29


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(MALLOY2 @ Jan 17 2012, 12:44) *
Я пользуюсь этой
iperf


Спасибо. Уже ближе. Попробую с этим разобраться применительно к stm32.
В окончательном варианте для тестирования сделал так.
CODE
void ToggleLed4(void * pvParameters)
{
const int Size = 255;
const int Count = 100;
struct netconn *connn;
struct netbuf *buf1;
struct ip_addr addr;
char *data1;
char text1[Size];
int i,j,n = 0;

for(n = 0; n < Size; n++)
text1[n] = 0x55;
/* create a new connection */
connn = netconn_new(NETCONN_UDP);
/* set up the IP address of the remote host */
addr.addr = htonl(0xC0A802A8);
/* connect the connection to the remote host */
netconn_connect(connn, &addr, 7);
/* create a new netbuf */
buf1 = netbuf_new();

while(1)
{
test = xnetif.ip_addr.addr;
/*check if IP address assigned*/
if (test !=0)
{
for( ;; )
{
/* toggle LED1 each 250ms */
STM_EVAL_LEDToggle(LED1);
vTaskDelay(1000);

STM_EVAL_LEDOn(LED2);
for(j = 0; j < Count; j++)
{
data1 = netbuf_alloc(buf1, strlen(text1));
/* create some arbitrary data */
for(i = 0; i < sizeof(text1); i++)
data1[i] = text1[i];


netbuf_ref(buf1, text1, strlen(text1));
netconn_send(connn, buf1);
netbuf_delete(buf1);
}
STM_EVAL_LEDOff(LED2);
}
}
}
}

Отправка из потока ToggleLed4 на комп 100 пакетов по 255 байт. Количеством пакетов и их размером можно управлять. Передается без проблем (со скоростью буду разбираться).
Да, по ходу возникла небольшая проблема. Пакеты немногим более 300 байт не хотят отправляться.
Вообще все виснет. Хотя в UDP должны нормально отправляться (без фрагментации) не менее 512. Очевидно что то в настройках LwIP...

Почитал про iperf - получается, что в моем случае придется воспользоваться UDP эхо сервером, который работает в другом потоке ОС

Сообщение отредактировал Acvarif - Jan 17 2012, 13:37
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 17 2012, 13:48
Сообщение #30


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Если кто не знает. В LwIP системма выдачи отладочной информации.
1. Чтоб ее задействовать нужно определить макрос LWIP_PLATFORM_DIAG в файле debug.h Если говорить про iar то все просто:
#define LWIP_PLATFORM_DIAG printf
и устанавливаете в опциях пректа флажек "include semihosting interfice", если поддерживает контороллер и отладчик включаете режим "Semihosted, stdout/stderr via SWO"(в режиме "Semihosted, stdout/stderr via semihosting" лучше даже не пытаться - уж больно тормозяво, если не получается через SWO лучше уж через UART предварительно написав драйвер с приличным буфером), в общем включаете выдачу отладочных сообщений на консоль.
2 в файле opt.h
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL/LWIP_DBG_LEVEL_WARNING/LWIP_DBG_LEVEL_SERIOUS в зависимости от того какие сообщения хотите получать.
там-же #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
там-же настраиваете от каких модулей хотите получать сообщения.
90% вопросов "почему не работает" отпадет при просмотре логов.
Ваш К.О.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 17 2012, 14:12
Сообщение #31


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Спасибо за полезную информацию.
Что имеется ввиду под консолью?

Протестировал выдачу по UDP - 1 пакет 255 байт с помощью iperf -u -s -i1 -p 7
Вот результат

Неужели скорость всего 2кб/сек?
Если так, то в чем загвоздка?
А вот 500 пакетов

Не пойму, как это правильно разшифровать. Что такое 0.2 мс?
Почему же такая маленькая скорость 1Mbits/sec ?


Сообщение отредактировал Acvarif - Jan 17 2012, 14:59
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 17 2012, 15:59
Сообщение #32


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Цитата(Acvarif @ Jan 17 2012, 18:12) *
Спасибо за полезную информацию.
Что имеется ввиду под консолью?

Если непосредственно в IARе то в режиме отладки View->Terminal IO. Если используете как оболочку Eclipse то Window->Show View->Console, в окне консоли нажимаете кнопку с монитором и выбираете C-SPY Terminal I/O.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 18 2012, 07:40
Сообщение #33


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 17 2012, 16:48) *
Если кто не знает. В LwIP системма выдачи отладочной информации.
1. Чтоб ее задействовать нужно определить макрос LWIP_PLATFORM_DIAG в файле debug.h Если говорить про iar то все просто:
#define LWIP_PLATFORM_DIAG printf
и устанавливаете в опциях пректа флажек "include semihosting interfice", если поддерживает контороллер и отладчик включаете режим "Semihosted, stdout/stderr via SWO"(в режиме "Semihosted, stdout/stderr via semihosting" лучше даже не пытаться - уж больно тормозяво, если не получается через SWO лучше уж через UART предварительно написав драйвер с приличным буфером), в общем включаете выдачу отладочных сообщений на консоль.
2 в файле opt.h
#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL/LWIP_DBG_LEVEL_WARNING/LWIP_DBG_LEVEL_SERIOUS в зависимости от того какие сообщения хотите получать.
там-же #define LWIP_DBG_TYPES_ON LWIP_DBG_ON
там-же настраиваете от каких модулей хотите получать сообщения.
90% вопросов "почему не работает" отпадет при просмотре логов.
Ваш К.О.


Пытаюсь повторить в IAR.
#define LWIP_PLATFORM_DIAG printf в файле debug.h установлено по умолчанию
в файле opt.h по умолчанию
Код
#ifndef LWIP_DBG_MIN_LEVEL
#define LWIP_DBG_MIN_LEVEL              LWIP_DBG_LEVEL_ALL
#endif#ifndef LWIP_DBG_TYPES_ON
#define LWIP_DBG_TYPES_ON               LWIP_DBG_ON
#endif

А это
Цитата
и устанавливаете в опциях пректа флажек "include semihosting interfice",
не нашел.
Пользуюсь J-Link 8
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 18 2012, 08:11
Сообщение #34


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Я бы не парился с этим режимом.
лучше напишите свой putchar и гоните в свободный UART, их у вас все таки 5
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 18 2012, 08:45
Сообщение #35


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(kan35 @ Jan 18 2012, 11:11) *
Я бы не парился с этим режимом.
лучше напишите свой putchar и гоните в свободный UART, их у вас все таки 5

Да я бы рад. LwIP определяет это так
CODE
#ifdef LWIP_DEBUG
/** print debug message only if debug message type is enabled...
* AND is of correct type AND is at least LWIP_DBG_LEVEL
*/
#define LWIP_PLATFORM_DIAG printf
#define LWIP_DEBUGF(debug, message) do { \
if ( \
((debug) & LWIP_DBG_ON) && \
((debug) & LWIP_DBG_TYPES_ON) && \
((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
LWIP_PLATFORM_DIAG message; \
if ((debug) & LWIP_DBG_HALT) { \
while(1); \
} \
} \
} while(0)

#else /* LWIP_DEBUG */
#define LWIP_DEBUGF(debug, message)
#endif /* LWIP_DEBUG */

Получается определяет функцию для выдачи сообщений
Как к ней приладить свой putchar?
Go to the top of the page
 
+Quote Post
kan35
сообщение Jan 18 2012, 10:16
Сообщение #36


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Все верно у тебя сделано.

Чтобы printf куда-то выводил строки, надо ему дать через что, вот putchar и есть это "что", пиши свою ф-ю по типу:
int putchar (int);
В ней просто вываливай байт в последовательный порт
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jan 18 2012, 10:44
Сообщение #37


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Получается определяет функцию для выдачи сообщений
Как к ней приладить свой putchar?


Все это делается в файле "сс.h"

Вот мой

CODE
#ifndef __CCT_H__
#define __CCT_H__

#include <stdint.h>
#include <intrinsics.h>
#include "mk_heap.h"

#ifdef __cplusplus
extern "C"
{
#endif

extern void dev_debugf(const char *args, ...);
#define LWIP_PLATFORM_ASSERT(x) do \
{dev_debugf("Assertion \"%s\" failed at line %d in %s\r", x, __LINE__, __FILE__);} \
while(0)
#define LWIP_PLATFORM_DIAG(x) {dev_debugf x;}

#define LWIP_NOASSERT
#define LWIP_DEBUG
#define ETHERNET_CHECKSUM_BY_HARDWARE
#define PACK_STRUCT_USE_INCLUDES

#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_END
#define PACK_STRUCT_FIELD(x) x

#define BYTE_ORDER LITTLE_ENDIAN
#define LWIP_PLATFORM_BYTESWAP 1

#if LWIP_PLATFORM_BYTESWAP
#define LWIP_PLATFORM_HTONS(x) __REV16(x)
#define LWIP_PLATFORM_NTONS(x) __REV16(x)
#define LWIP_PLATFORM_HTONL(x) __REV(x)
#define LWIP_PLATFORM_NTONL(x) __REV(x)
#endif

#define mem_free mk_free

#define mem_malloc mk_malloc

#define mem_calloc mk_calloc

#define LWIP_ERR_T int32_t

#define U16_F "u"
#define S16_F "d"
#define X16_F "x"
#define U32_F "lu"
#define S32_F "ld"
#define X32_F "lx"

typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef uint32_t u32_t;
typedef int32_t s32_t;
typedef uint64_t u64_t;
typedef int64_t s64_t;
typedef u32_t mem_ptr_t;

typedef uint32_t sys_prot_t;

#ifdef __cplusplus
}
#endif

#endif


Сдесь функция dev_debugf это моя функция вывода в уарт.

Сообщение отредактировал IgorKossak - Jan 18 2012, 20:57
Причина редактирования: [codebox]!!!
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 18 2012, 11:25
Сообщение #38


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Цитата(Acvarif @ Jan 18 2012, 10:40) *
А это не нашел.
Пользуюсь J-Link 8

Извиняюсь, дал названия из eclipse. Непосредственно в IARе: Project->Option->General Option->Library Configuration->Library Low-level interface impletation ->Переключаете в в режим Semihosted и stdout/stderr в режим Via SWO. Если отлаживаете через JTAG, а не через SWD то режим Via SWO естественно недоступен. IAR 6.21.
Цитата
Я бы не парился с этим режимом. лучше напишите свой putchar и гоните в свободный UART, их у вас все таки 5

При наличии J-Linkа поддерживающего SWD и контроллера с SWD такой возможностью грех не воспользоватся. Уже давно на кортексах все отладочные сообщения вывожу именно через отладчик.
А с UARTом не так все просто. Если в putchar тупо кидать данные в UART то, например при выводе более-менее приличного обема данных в прерывании есть шанс пропустить другое прерывание, это в худшем случае, но даже без этого вывод через UART без буфферизации занимает слишком много времени.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 18 2012, 13:27
Сообщение #39


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 18 2012, 14:25) *
Извиняюсь, дал названия из eclipse. Непосредственно в IARе: Project->Option->General Option->Library Configuration->Library Low-level interface impletation ->Переключаете в в режим Semihosted и stdout/stderr в режим Via SWO. Если отлаживаете через JTAG, а не через SWD то режим Via SWO естественно недоступен. IAR 6.21.

Все сделал. Тоже в IAR 6.21
oph.h
Код
/**
* API_LIB_DEBUG: Enable debugging in api_lib.c.
*/
#ifndef API_LIB_DEBUG
#define API_LIB_DEBUG                   LWIP_DBG_OFF
#endif

Хотя файл защищен от записи. Пришлось изменить ему атрибуты и вместо LWIP_DBG_OFF написать LWIP_DBG_ON
Отладчик запустился с появлением зеленой кнопки SWO, но сообщений пока на терминале нет. Хотя в api_lib.c есть что выводить на терминал
Может еще что нужно сделать ON для того, чтобы увидеть работу терминала при работе стека?

Сообщение отредактировал Acvarif - Jan 18 2012, 13:33
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 18 2012, 13:57
Сообщение #40


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Прежде всего нужно переопределить макрос LWIP_DBG_TYPES_ON с LWIP_DBG_OFF на LWIP_DBG_ON - это глобальное разрешение выдачи отладочных сообщение. Затем макросом LWIP_DBG_MIN_LEVEL регулируем что именно мы хотим получать - все(LWIP_DBG_LEVEL_ALL), предупреждения(LWIP_DBG_LEVEL_WARNING) или ошибки (LWIP_DBG_LEVEL_SERIOUS).
После с помощью макросов ETHARP_DEBUG, NETIF_DEBUG, PBUF_DEBUG...... в том числе API_LIB_DEBUG указывеме из каких модулей вы хотите получать сообщения( например API_LIB_DEBUG управляет отладочными сообщенияим из модуля api_lib.c).
PS Для проверки добавте в main что-небудь вроде printf("test\r\n"); если с настройками собственно отладочных сообщений все в норме то при запуске увидите в терминале "test".

Сообщение отредактировал IgorKossak - Jan 18 2012, 20:56
Причина редактирования: Бездумное цитирование
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 18 2012, 14:29
Сообщение #41


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Сделано так
LWIP_DBG_ON
LWIP_DBG_LEVEL_ALL
CODE
/**
* UDP_DEBUG: Enable debugging in UDP.
*/
#ifndef UDP_DEBUG
#define UDP_DEBUG LWIP_DBG_ON
#endif
.....
/**
* UDP_DEBUG: Enable debugging in UDP.
*/
#ifndef UDP_DEBUG
#define UDP_DEBUG LWIP_DBG_ON
#endif


В функцию мигания светодиодом и посылки UDP пакетов добавлено printf("test\r\n");
Код
        ........
        /* toggle LED1 each 250ms */
        STM_EVAL_LEDToggle(LED1);
        vTaskDelay(1000);
        printf("test\r\n");
        ..............

Не получается застревает на
Код
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

Восстанавливается если убрать printf("test\r\n");

Сообщение отредактировал IgorKossak - Jan 18 2012, 20:58
Причина редактирования: Бездумное цитирование
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 18 2012, 15:56
Сообщение #42


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Глубина стека в задаче какая? printf довольно стекожрущая процедура. Отлаживаете точно через SWD?
PS если нет ничего военного выложите куда-небуть весь проект.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 18 2012, 18:46
Сообщение #43


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 18 2012, 18:56) *
Глубина стека в задаче какая? printf довольно стекожрущая процедура. Отлаживаете точно через SWD?
PS если нет ничего военного выложите куда-небуть весь проект.

Вроде через SWD (J-link v8 от starterkit) + платка от того же starterkit SK-STM32F217
Проект (Iar Arm 6.21) не военный, пока только тест на базе демки от st, для оценки возможностей FreeRTOS + LwIP + UDP. Находится тут http://depositfiles.com/files/aulnju494
В проекте закомментил все потоки кроме одного, в котором выдается 100 UDP пакетов по 255 байт в каждом один раз в секунду и при этом мигают 2 светодиода. Для консоли все настройки выставил.
1. Не пойму почему не позволяется создавать пакет больше 300 (с хвостиком) байт (поток виснет).
2. Никак не получается померять скорость Судя по времени за которое прокручивается выдача 25 000 байт (10 мс) получается 20 Mbits/s Маловато будет. Но очевидно так мерять не орректно. А iperf вооще показывает 0.2 Mbits/s Не пойму где тут собака порылась.

Сообщение отредактировал Acvarif - Jan 18 2012, 18:51
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 19 2012, 10:14
Сообщение #44


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Чтоб появились сообшения в настройках проекта укажите правильно частоту на которой работает контроллер Project->Option->J-Link/j-trace->Clock Setup->CPU Clock установить 120 MHz, SWO clock или оставить как есть или переключить в "Auto".
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 19 2012, 12:26
Сообщение #45


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 19 2012, 13:14) *
Чтоб появились сообшения в настройках проекта укажите правильно частоту на которой работает контроллер Project->Option->J-Link/j-trace->Clock Setup->CPU Clock установить 120 MHz, SWO clock или оставить как есть или переключить в "Auto".

Большое спасибо. Работает.
Посоветуйте пожалуйста, что в opt.h нужно сделать ON для контроля работы netconn.
Может сталкивались - не получается посылать UDP пакеты размером > 300 байт (#define SIZE 355)
Поток застревает на
Код
/* create a new connection */
connn = netconn_new(NETCONN_UDP);

После команды Break поток оказывается на
Код
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}


Сообщение отредактировал Acvarif - Jan 19 2012, 12:29
Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 19 2012, 13:04
Сообщение #46


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



Посмотрел код.....
1 Вы обявляете локальную переменную char text1[SIZE]; размером в 255 байт, при этом размер стека у потока configMINIMAL_STACK_SIZE 128 * 4 = 512 байт. т.е. одна локальная переменная съедает мол стека. Оставшихся 64 слов хватает едава едава. Отсюда и зависания при вызове printf и невозможность увеличить SIZE.
2 разберитесь с назначением функций netbuf_alloc и netbuf_ref. А то у вас пулучается что сначала вы с помощью data1 = netbuf_alloc(buf1, sizeof(text1)); создаете новый буфер в buf1, затем с помощью netbuf_ref(buf1, text1, sizeof(text1)); прикрепляете к buf1 буффер text1. Что при этом происходит с предварительно выделеным буфером - х.з.
ниже привел исправленный код, у меня с ним, правда с MII интерфейсом(RTL8201) получается скорость около 90-95Mbit
CODE
#define SIZE 1000
void ToggleLed4(void * pvParameters)
{
struct netconn *connn;
struct netbuf *buf1;
struct ip_addr addr;
static char text1[SIZE];//!!!! Буфер объявлен как static

memset(text1, 0x55, SIZE);
// create a new connection
connn = netconn_new(NETCONN_UDP);
// set up the IP address of the remote host
IP4_ADDR(&addr, 192, 168, 0, 18);//Не забудте исправить IP
// connect the connection to the remote host
netconn_connect(connn, &addr, 7);
// create a new netbuf
buf1 = netbuf_new();

while(1)
{
vTaskDelay(1000);

test = xnetif.ip_addr.addr;
//check if IP address assigned
if (test !=0)
{
for(;; )
{
// toggle LED1 each 1000ms
STM_EVAL_LEDToggle(LED1);
//vTaskDelay(1000);
//printf("test\r\n");

STM_EVAL_LEDOn(LED2);
for(int j = 0; j < 10000; j++)
{
netbuf_ref(buf1, text1, sizeof(text1));
netconn_send(connn, buf1);
}
STM_EVAL_LEDOff(LED2);
}
}
}
}


Сообщение отредактировал IgorKossak - Jan 20 2012, 16:37
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 19 2012, 14:31
Сообщение #47


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 19 2012, 16:04) *
Посмотрел код.....
1 Вы обявляете локальную переменную char text1[SIZE]; размером в 255 байт, при этом размер стека у потока configMINIMAL_STACK_SIZE 128 * 4 = 512 байт. т.е. одна локальная переменная съедает мол стека. Оставшихся 64 слов хватает едава едава. Отсюда и зависания при вызове printf и невозможность увеличить SIZE.
2 разберитесь с назначением функций netbuf_alloc и netbuf_ref. А то у вас пулучается что сначала вы с помощью data1 = netbuf_alloc(buf1, sizeof(text1)); создаете новый буфер в buf1, затем с помощью netbuf_ref(buf1, text1, sizeof(text1)); прикрепляете к buf1 буффер text1. Что при этом происходит с предварительно выделеным буфером - х.з.


Большое спасибо.
Все заработало.
Виноват. Совсем вылетело, что у ОС свой стек у каждого потока. А локалка заседает в стеке. Надо будет с FreeRTOS поразбираться. До сего времени использовал только scmRTOS
Про функции буду читать мануал.
Со скоростью пока не понятно. Perf показывает ~13 Mbits/s

Или я не врубился как мерять или что то не так с инициализацией MAC+RMII на нужной скорости или со скоростью камня что то не так

Go to the top of the page
 
+Quote Post
=F8=
сообщение Jan 19 2012, 14:50
Сообщение #48


Знающий
****

Группа: Свой
Сообщений: 567
Регистрация: 7-07-07
Из: Донецк
Пользователь №: 28 954



А размер пакета(SIZE) увеличить не забыли? От этого скорость очень сильно зависит.
SIZE = 250
Прикрепленное изображение

SIZE = 1400
Прикрепленное изображение
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 19 2012, 15:10
Сообщение #49


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(=F8= @ Jan 19 2012, 17:50) *
А размер пакета(SIZE) увеличить не забыли? От этого скорость очень сильно зависит.

Да, все сделал. Спасибо.
Сначала не врубился. Теперь все прояснилось. Режим отладки нужно выключить (LWIP_DBG_OFF). Тормозит однако.
Получилось так
Прикрепленное изображение


Сообщение отредактировал Acvarif - Jan 19 2012, 15:26
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 20 2012, 15:52
Сообщение #50


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Касательно этой темы:

1. Удержит ли LwIP+FreeRtos скорость ~90 если FreeRtos будет иметь еще 2...3 потока. Например работа с ADC, DAC, цифровая обработка сигналов с ADC?
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jan 20 2012, 16:05
Сообщение #51


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
Например работа с ADC, DAC, цифровая обработка сигналов с ADC?


Странный вопрос, цифровая обработка сигналов может быть такая что он и сам не потянет не то что еще и стек sm.gif, на этот вопрос вам никто и никогда не даст ответа.
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Jan 20 2012, 17:58
Сообщение #52


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(MALLOY2 @ Jan 20 2012, 20:05) *
Странный вопрос, цифровая обработка сигналов может быть такая что он и сам не потянет не то что еще и стек sm.gif, на этот вопрос вам никто и никогда не даст ответа.

Не совсем верно поставил вопрос.
Допустим
1 поток - 16 каналов ADC КИХ фильтры (предполагается, что stm32f217 справится)
2 поток - выдача обработанных результатов (все 16 каналов) на комп через LwIP (между выборками)
3 поток - выдача результатов прокрутки каждой выборки через КИХ на DAC
Go to the top of the page
 
+Quote Post
Twen
сообщение Jan 28 2012, 08:46
Сообщение #53


Частый гость
**

Группа: Участник
Сообщений: 163
Регистрация: 7-02-09
Пользователь №: 44 543



Добрый день. Я разбираюсь с реализацией веб0сервера на LwIp стеке. Сейчас меня интересует верхний уровень, сам HTTP. У примере под stm32F207 реализован HTTP с поддержкой POST и GET запросов.
Но с POST запросами есть один нюанс, после объявления константы, как:
#define LWIP_HTTPD_SUPPORT_POST 1
компилятор показывает, что в проекте не определены 3 функции:

err_t httpd_post_receive_data(void *connection, struct pbuf *p);


void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);


err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
u16_t http_request_len, int content_len, char *response_uri,
u16_t response_uri_len, u8_t *post_auto_wnd);

Для начала я их определил , как пустыми, возвращающими return ERR_OK(все норм.)...я так понимаю их нужно самому дописывать, может кто-нибудь посоветовать что-то по поводу их правильного описания.


За раннее, спасибо!

Сообщение отредактировал Twen - Jan 28 2012, 15:31
Go to the top of the page
 
+Quote Post
Алллексей
сообщение Aug 20 2013, 12:32
Сообщение #54





Группа: Новичок
Сообщений: 1
Регистрация: 20-08-13
Пользователь №: 77 997



Цитата(Twen @ Jan 28 2012, 12:46) *
Добрый день. Я разбираюсь с реализацией веб0сервера на LwIp стеке. ...


Добрый вечер! Вам удалось разобраться с этим вопросом?

Сообщение отредактировал IgorKossak - Aug 26 2013, 19:30
Причина редактирования: избыточное цитирование
Go to the top of the page
 
+Quote Post
Log_in
сообщение Dec 20 2013, 11:44
Сообщение #55


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 9-06-12
Пользователь №: 72 244



Доброго времени суток. Пытаюсь разобраться с работой стека, следуя по стопам Acvarif, но застрял почти на начале.) Используя пример указанный в самом начале, UDP сообщение так и посылается.
CODE
struct udp_pcb *upcb;
struct pbuf *p;
struct ip_addr DestIPaddr;
char tdata[] = {"Test"};
char *data = tdata;

/* Create a new UDP control block */
upcb = udp_new();
/*assign destination IP address */
IP4_ADDR( &DestIPaddr, DEST_IP_ADDR0, DEST_IP_ADDR1, DEST_IP_ADDR2, DEST_IP_ADDR3 );
/* configure destination IP address and port */
udp_connect(upcb, &DestIPaddr, UDP_SERVER_PORT);
/* allocate pbuf from pool*/
p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)data), PBUF_POOL);
/* copy data to pbuf */
pbuf_take(p, (char*)data, strlen((char*)data));
/* send udp data */
udp_send(upcb, p);

По IP адресу отправляется ARP запрос, ПК шлет ответ (смотрю Wireshark), но присланный МАС адрес ПК не добавляется в таблицу. Я так понимаю, что нужно включить обработчик приема сообщений, но не знаю как. Кто знает, подскажите как это сделать, либо укажите где не прав.)
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 20 2013, 12:37
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(Log_in @ Dec 20 2013, 15:44) *
Доброго времени суток. Пытаюсь разобраться с работой стека, следуя по стопам Acvarif, но застрял почти на начале.) Используя пример указанный в самом начале, UDP сообщение так и посылается.

По IP адресу отправляется ARP запрос, ПК шлет ответ (смотрю Wireshark), но присланный МАС адрес ПК не добавляется в таблицу. Я так понимаю, что нужно включить обработчик приема сообщений, но не знаю как. Кто знает, подскажите как это сделать, либо укажите где не прав.)


чтобы стэк работал, надо постоянно вызывать функцию
TCP_IP_Process(),
несмотря на название для UDP тожеsm.gif

а также
timer_tick () с заданным интервалом
Go to the top of the page
 
+Quote Post
Log_in
сообщение Dec 20 2013, 12:50
Сообщение #57


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 9-06-12
Пользователь №: 72 244



Дело в том, что у меня F107, и в связи с этим в библиотеке этих функций нет. Может Вы можете назвать аналоги для этого контроллера? Или следует рассмотреть работу этих функций в для f2xx и самому потом сориентироваться?
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Dec 20 2013, 13:01
Сообщение #58


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ОЙ блин!
не,... надо ваще забыть про мое сообщение - это я от другого стэка вам функции сказал%(...

в LwIP тоже есть функции, которые надо постоянно дергать что все крутилось и пакеты обрабатывались.
это
tcp_fasttmr()
tcp_slowtmr()

одну часто, она стэк крутит
а другую пореже, она таймауты считает и убивает закрытые сокеты
Go to the top of the page
 
+Quote Post
Log_in
сообщение Dec 23 2013, 11:40
Сообщение #59


Участник
*

Группа: Участник
Сообщений: 21
Регистрация: 9-06-12
Пользователь №: 72 244



Использовал функцию LwIP_Periodic_Handle, вызывающую tcp_tmr, которая в свою очередь tcp_fasttmr и tcp_slowtmr с заданной периодичностью. Но ситуация не особо изменилась. В ходе просмотра выполнения функций было обнаружено, что переменная tcp_active_pcbs, используемая в tcp_fasttmr, всегда принимает значение равное нулю. В связи с этим функция сразу вываливается из цикла без каких либо действий. Вроде эта структура означает все доступные соединения. Есть какие-нибудь соображения? Неужели соединение некорректно установлено? Интересно, что не мне удалось бы найти функции, где бы происходило присвоение каких либо значений. И не могли бы Вы также пояснить, где в конкретно происходила бы обработка ARP ответов при штатной работе стека?

Использовал функцию LwIP_Pkt_Handle(), вызывающую ethernetif_input, сразу после udp_send(upcb, p) и стек смог принять и корректно обработать ARP ответ, добавив МАС адрес в таблицу, после чего UDP дошла до ПК, но хотелось бы более элегантное и разумное решение для приема. Да и с tcp_active_pcbs неясность осталась.
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.02198 секунд с 7
ELECTRONIX ©2004-2016