Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LWIP Как послать данные (tcp_write) по событию?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
js_slider
Здравствуйте.
Сделал на STM32F4 TCP/IP сервер c использованием lwip стека без OS.
Все работает замечательно по типу запрос-ответ. Ответ процедурой tcp_write реализован как и требуется из callback.
Но вот возникла необходимость посылать данные не по запросу, а по событию - по приходу строба на ножку.
Делал ссылку на pcb во время коннекта клиента, и отправлял данные вне callback...

Код
struct tcp_pcb *Globalpcb;
....
Globalpcb=pcb;
....

if(Globalpcb != NULL)
{
COUNT_TX=tcp_sndbuf(Globalpcb);
if(COUNT_TX > Len)
{
err = tcp_write(Globalpcb, Data, Len, 1);
tcp_output(Globalpcb);
}
}

все работает..., но не долго - периодически стек падает.

Вопрос как гармотно использовать tcp_write в данном случае чтобы не порушить стек? Кто сталкивался?
scifi
Цитата(js_slider @ Apr 29 2014, 13:49) *
Но вот возникла необходимость посылать данные не по запросу, а по событию - по приходу строба на ножку.
Делал ссылку на pcb во время коннекта клиента, и отправлял данные вне callback...

Надеюсь, не из обработчика прерывания вызываете функции lwip. Потому что это отличный способ завалить программу.
js_slider
Цитата(scifi @ Apr 29 2014, 13:44) *
Надеюсь, не из обработчика прерывания вызываете функции lwip. Потому что это отличный способ завалить программу.


Из него родимого... из прерывания... а можете пояснить почему это отличный способ завалить программу??? какая разница из обработчика прерывания вызывать или еще откуда в программе... если так и так не callback?
scifi
Цитата(js_slider @ Apr 29 2014, 15:53) *
Из него родимого... из прерывания... а можете пояснить почему это отличный способ завалить программу??? какая разница из обработчика прерывания вызывать или еще откуда в программе... если так и так не callback?

Элементарно. Предположим, программа зашла в tcp_write() из callback, меняет переменные, выделяет и освобождает память, пишет в буферы. И тут - БАЦ! - прерывание, и обработчик прерывания тоже заходит в tcp_write(), лезет в те же переменные и т.д. Так нельзя, всё сразу упадёт. Надо посылать в главный цикл сигнал из прерывания (через переменную volatile), и уже в главном цикле слать данные через TCP.
kolobok0
Цитата(js_slider @ Apr 29 2014, 15:53) *
Из него ...какая разница из обработчика прерывания вызывать или еще откуда в программе....


выше уже мысль прозвучала конечно-же...
почаще ставте себя на место микроконтроллера или процессора. многое станет понятным...
KnightIgor
Цитата(kolobok0 @ Apr 29 2014, 20:46) *
почаще ставте себя на место микроконтроллера или процессора. многое станет понятным...

Типа "Criminal Minds", а точнее "Silicon Minds"? wink.gif

SCNR.
js_slider
Благодарю всех откликнувшихся. Проблема решена. Действительно стек падал из-за вызовов tcp_write из прерывания.
TriAlexAnt
Если можно, хочу задать вопрос в развитие данной темы.

Я тоже планирую использовать TCP/IP сервер c использованием lwip стека без OS.

Хочу на нем организовать рассылку данных в формате JSON по нескольким IP адресам (без запроса со стороны клиента).

Хотя бы в общих чертах, как это можно сделать? Во всех примерах, что я смотрел, всегда присутствует запрос от клиента. А мне нужно стартануть передачу самому.
scifi
Цитата(TriAlexAnt @ May 7 2014, 16:26) *
Хотя бы в общих чертах, как это можно сделать? Во всех примерах, что я смотрел, всегда присутствует запрос от клиента. А мне нужно стартануть передачу самому.

HTTP не предусматривает возможности установления соединения по инициативе сервера. Это чаще всего и невозможно из-за всяких NAT, firewall и проч.
Если соединение уже установлено, то есть всякие извращенные способы посылать по нему асинхронные посылки от сервера к клиенту: тут.
TriAlexAnt
Цитата(scifi @ May 7 2014, 16:50) *
HTTP не предусматривает возможности установления соединения по инициативе сервера. Это чаще всего и невозможно из-за всяких NAT, firewall и проч.
Если соединение уже установлено, то есть всякие извращенные способы посылать по нему асинхронные посылки от сервера к клиенту: тут.


А если на другой стороне висит тоже WEB-сервер? То есть каким-то образом нужно имитировать работу браузера?
scifi
Цитата(TriAlexAnt @ May 7 2014, 18:04) *
А если на другой стороне висит тоже WEB-сервер? То есть каким-то образом нужно имитировать работу браузера?

Вы лучше обрисуйте задачу поподробнее. Потому что "рассылать JSON по нескольким адресам" - само по себе довольно сомнительное занятие, поэтому и посоветовать особо нечего.
jcxz
Цитата(scifi @ May 7 2014, 19:50) *
HTTP не предусматривает возможности установления соединения по инициативе сервера. Это чаще всего и невозможно из-за всяких NAT, firewall и проч.

Возможно автору нужно не http, а простой tcp/ip-коннект (сокет).
Если на той стороне есть tcp-порт открытый в listen-режиме, то конечно на него можно установить активное соединение.
Автору нужно почитать про TCP/IP-стек и как он работает чтобы понять, что ему нужно.
doom13
Хочу к своему проекту прикрутить либу LWIP, пока читаю доку и нахожу:
Цитата
It can send, receive and forward packets, but can not send or receive fragmented IP packets.

Данная либа не позволяет послать фрагментированный UDP длинной 32 kB?!!
scifi
Цитата(doom13 @ May 19 2014, 16:19) *
Данная либа не позволяет послать фрагментированный UDP длинной 32 kB?!!

Это сильно устаревшая информация. Там давно уже добавлено "IP layer fragmentation and reassembly".
doom13
Цитата(scifi @ May 19 2014, 15:50) *
Это сильно устаревшая информация. Там давно уже добавлено "IP layer fragmentation and reassembly".

Читаю доку "Design and Implementation of the lwIP TCP/IP Stack" за 20.02.2001, и использовать хотел lwip v1.3.2 (она в техасовских примерах есть).
Посоветуйте, что нового почитать, что-то в google ток эту нашёл.
Будет ли поддержка фрагментации в v1.3.2 (12.2009) или брать новую версию?
scifi
Цитата(doom13 @ May 19 2014, 16:57) *
Посоветуйте, что нового почитать, что-то в google ток эту нашёл.
Будет ли поддержка фрагментации в v1.3.2 (12.2009) или брать новую версию?

Можно попробовать почитать полуофициальный вики проекта. А поддерживается или нет - легко увидеть в исходниках: ищите макросы IP_FRAG и IP_REASSEMBLY.
doom13
Цитата(scifi @ May 19 2014, 16:04) *
Можно попробовать почитать полуофициальный вики проекта. А поддерживается или нет - легко увидеть в исходниках: ищите макросы IP_FRAG и IP_REASSEMBLY.

Спасибо, глянем.
andrewlekar
Цитата
Данная либа не позволяет послать фрагментированный UDP длинной 32 kB?!!

У вас UDP пакеты длиной 32КБ? Фрагментация касается разбиения отдельных пакетов, когда они не влезают в MTU. Если у вас пакеты небольшие, то без фрагментации всё будет прекрасно работать на любых потоках.
Golikov A.
проблема в том что макс пакет около 1500 байт, 1432 на данные. Даже если жумбо фрейм использовать и тогда 12 КБ край. Так что 32 КБайтные данные лучше самому порезать на порции и слать их. А учитывая что UDP не дает гарантии доставки, надо сверху еще протокольчик накинуть.
doom13
Цитата(andrewlekar @ May 20 2014, 07:49) *
У вас UDP пакеты длиной 32КБ? Фрагментация касается разбиения отдельных пакетов, когда они не влезают в MTU. Если у вас пакеты небольшие, то без фрагментации всё будет прекрасно работать на любых потоках.


32 kB это для примера, но точно больше 1500, одним ethernet-пакетом не пошлёшь.
Golikov A.
А! ну у вас ошибка терминологии)

Если у вас есть большие данные и вы их разбиваете на пакеты UDP - это не входит в ТСР/IP уровень. Это вы делаете сами, как умеете, сами обеспечиваете контроль целостности и так далее...

Если у вас большие данные и вы их пихаете в сокет TCP, то это входит в TCP/IP уровень, стэк сам берет на себя задачу проверки того что данные дошли, что они пришли в нужном порядке, что они не повторились и так далее...

При этом UDP пакет может придти только весь разом, и он не может быть больше 1500 байт (поправьте если я ошибаюсь). ТСР может идти порциями в зависимости от размера окна и прочего. При этом есть такая неприятность как внутрипакетная фрагментация - фрагментация одного пакета, обычно всякие WiFi этим грешат. Когда ваш один большой пакет UDP (но не больше 1500 байт) режут на порции и шлют кусками, такую фрагментацию также отрабатывает стэк (начиная с какой то версии), и собирает ваш единый пакет отдает вам целиком. Но это не значит что вы ему суните 32 КБайт данных, а стэк все сделает сам. Это верно только в случае ТСP, в случае UDP это придется сделать самому руками, да еще следить чтобы пакеты пришли в правильном порядке и без повторений. Причем когда вы это сделает, вы получите ТСРsm.gif


doom13
Цитата(Golikov A. @ May 20 2014, 07:56) *
проблема в том что макс пакет около 1500 байт, 1432 на данные. Даже если жумбо фрейм использовать и тогда 12 КБ край. Так что 32 КБайтные данные лучше самому порезать на порции и слать их.

Как бы IP поддерживает фрагментацию, а максимальная длинна UDP примерно 2^16 = 65kB.

Цитата(Golikov A. @ May 20 2014, 07:56) *
А учитывая что UDP не дает гарантии доставки, надо сверху еще протокольчик накинуть.

Если протяжённость сети измеряется не километрами и пакет не проходит через тучу маршрутизаторов, то, не смотря на отсутствие гарантий доставки, всё нормально работает без потерь данных при длинне UDP-пакета 32 kB и скорости передачи 655 Mbit/s (поднимал тему, Вы участвовали в обсуждении).

Цитата(Golikov A. @ May 20 2014, 10:14) *
А! ну у вас ошибка терминологии)

Позвольте не согласиться, с терминологией всё в порядке.

Цитата(Golikov A. @ May 20 2014, 10:14) *
Если у вас есть большие данные и вы их разбиваете на пакеты UDP - это не входит в ТСР/IP уровень. Это вы делаете сами, как умеете, сами обеспечиваете контроль целостности и так далее...

Данные большие 32 kB, но я их не разбиваю на пакеты UDP, а посылаю одним UDP-пакетом. В шапке IP используются флаги для фрагментирования данного пакета. Это не TCP, а UDP, который является одним из поддерживаемых TCP/IP-стеком (lwIP) протоколов. Вопрос был в том, что UDP поддерживается стеком, но без поддержки фрагментации (It can send, receive and forward packets, but can not send or receive fragmented IP packets).

Цитата(Golikov A. @ May 20 2014, 10:14) *
Если у вас большие данные и вы их пихаете в сокет TCP, то это входит в TCP/IP уровень, стэк сам берет на себя задачу проверки того что данные дошли, что они пришли в нужном порядке, что они не повторились и так далее...

Для передачи данных, как написал, хочу использовать UDP, не TCP.

Цитата(Golikov A. @ May 20 2014, 10:14) *
При этом UDP пакет может придти только весь разом, и он не может быть больше 1500 байт (поправьте если я ошибаюсь). ТСР может идти порциями в зависимости от размера окна и прочего. При этом есть такая неприятность как внутрипакетная фрагментация - фрагментация одного пакета, обычно всякие WiFi этим грешат. Когда ваш один большой пакет UDP (но не больше 1500 байт) режут на порции и шлют кусками, такую фрагментацию также отрабатывает стэк (начиная с какой то версии), и собирает ваш единый пакет отдает вам целиком. Но это не значит что вы ему суните 32 КБайт данных, а стэк все сделает сам. Это верно только в случае ТСP, в случае UDP это придется сделать самому руками, да еще следить чтобы пакеты пришли в правильном порядке и без повторений. Причем когда вы это сделает, вы получите ТСР

UDP-пакет может быть длинной больше 1500 байт (длинна UDP ограничена размером поля "UDP length" в шапке UDP), это ethernet-пакет ограничен длинной порядка 1500 байт. TCP использовать пока не приходилось, вот думаю опробовать при использовании lwIP.
Golikov A.
странно это все для меня, ну если вы говорите.... Надо будет перечитать стандарт на досуге
doom13
В либе LwIP часто встречается термин PCB, если можно, поясните, что он означает?
scifi
Цитата(doom13 @ Jun 3 2014, 17:28) *
В либе LwIP часто встречается термин PCB, если можно, поясните, что он означает?

Protocol Control Block. Структура, содержащая всю информацию о состоянии данного соединения.
doom13
Цитата(scifi @ Jun 3 2014, 16:46) *
Protocol Control Block. Структура, содержащая всю информацию о состоянии данного соединения.

Спасибо, а то что-то никак не мог подобрать соответствующую расшифровку
doom13
Нужна помощь, не могу понять, чего не хватает, чтобы udp пакет ушёл в сеть.

CODE
int main(void)
{
unsigned long ulUser0, ulUser1;
unsigned char pucMACArray[8];

ulUser0 = 0x00F263A8;
ulUser1 = 0x00800000;

pucMACArray[0] = ((ulUser0 >> 0) & 0xff);
pucMACArray[1] = ((ulUser0 >> 8) & 0xff);
pucMACArray[2] = ((ulUser0 >> 16) & 0xff);
pucMACArray[3] = ((ulUser1 >> 0) & 0xff);
pucMACArray[4] = ((ulUser1 >> 8) & 0xff);
pucMACArray[5] = ((ulUser1 >> 16) & 0xff);

unsigned long board_ip = 0xC0A80110;
unsigned long net_mask = 0xFFFFFF00;

lwIPInit(pucMACArray, board_ip, net_mask, 0, IPADDR_USE_STATIC);

struct udp_pcb *pcb;
pcb = udp_new();

struct ip_addr ip_rmt;

//udp_bind(pcb, (struct ip_addr *)&board_ip, 11000);
udp_bind(pcb, IP_ADDR_ANY, 11000);
udp_connect(pcb, &ip_rmt, 12000);


unsigned char buffer[128];
int i;
for(i = 0; i < 128; i++)
{
buffer[i] = i;
}

struct pbuf * pb;
pb = pbuf_alloc(PBUF_TRANSPORT, 128, PBUF_RAM);
memcpy(pb->payload, buffer, sizeof(buffer));

//udp_send(pcb, pb);
//udp_sendto(pcb, pb, &ip_rmt, 12000);
//pbuf_free(pb);

int tx_en = 0;

while(1)
{
if(tx_en)
{
udp_send(pcb, pb);
//udp_sendto(pcb, pb, &ip_rmt, 12000);
pbuf_free(pb);
tx_en = 0;
}
}
}
Golikov A.
как минимум надо дергать еще функции LwIP которые обрабатывают стэк. Вы пока создали сообщение и добавили его в очередь, а сам стэк не работает...

tcp_fasttmr();

и еще для прочей работы

tcp_slowtmr();
doom13
Цитата(Golikov A. @ Jun 4 2014, 12:51) *
как минимум надо дергать еще функции LwIP которые обрабатывают стэк. Вы пока создали сообщение и добавили его в очередь, а сам стэк не работает...

Почему не работает? Если пингануть плату - она ответит.

Цитата(Golikov A. @ Jun 4 2014, 12:51) *
tcp_fasttmr();
tcp_slowtmr();

Но это функции для работы по TCP протоколу, каким боком они к UDP?
scifi
Цитата(doom13 @ Jun 4 2014, 14:02) *
Почему не работает? Если пингануть плату - она ответит.

Что-то не видно, как кадры из Ethernet принимаются и обрабатываются. В обработчике прерывания что ли?
Кстати, есть ещё ARP. Он тоже может задерживать отправку пакетов, и там есть таймеры.
doom13
Цитата(scifi @ Jun 4 2014, 13:21) *
Что-то не видно, как кадры из Ethernet принимаются и обрабатываются. В обработчике прерывания что ли?
Кстати, есть ещё ARP. Он тоже может задерживать отправку пакетов, и там есть таймеры.

Я пока отправку пытаюсь сделать, или Вы хотите сказать, что посылать данные без настройки приёма оно не будет?
ARP и ICMP начинают работать уже после
Код
lwIPInit(pucMACArray, board_ip, net_mask, 0, IPADDR_USE_STATIC);

и ничего более не требуют.
scifi
Цитата(doom13 @ Jun 4 2014, 14:26) *
Я пока отправку пытаюсь сделать, или Вы хотите сказать, что посылать данные без настройки приёма оно не будет?

Отправка без приёма работать не должна. Если только не сделаете заранее статическую таблицу ARP.
doom13
Цитата(scifi @ Jun 4 2014, 13:57) *
Отправка без приёма работать не должна. Если только не сделаете заранее статическую таблицу ARP.

По идее должна работать, скоро проверим, похоже, нашёл проблему, udp_send ошибку выдаёт ERR_VAL.
scifi
Цитата(doom13 @ Jun 4 2014, 15:06) *
По идее должна работать

Интересно, как?
SEND: ARP REQUEST
RECEIVE: ARP RESPONSE
SEND: UDP
Если уберёте вторую строчку, то всё заглохнет.
doom13
Цитата(scifi @ Jun 4 2014, 14:12) *

Мы наверное с Вами про разные отправку/приём говорим. Я про то, что UDP должен работать на передачу, вне зависимости от приёма (настроен обработчик принимаемых сообщений или нет). Вы про ARP, где должны быть реализованы и приём и передача, но арп начинает работать уже после инициализации LwIP, там да, должен работать и приём и передача, для UDP мне пока приёмник не нужен, только начинаю разбираться с либой, хочу передачу затестить.
scifi
Цитата(doom13 @ Jun 4 2014, 15:24) *
Вы про ARP, где должны быть реализованы и приём и передача, но арп начинает работать уже после инициализации LwIP, там да, должен работать и приём и передача, для UDP мне пока приёмник не нужен, только начинаю разбираться с либой, хочу передачу затестить.

То есть приём кадров Ethernet уже есть? Вот я и поинтересовался, где он. Потому что если он в обработчике прерывания, то это - бяка, так нельзя.
doom13
Короче передача заработала, проблема была в том, что дефайн IP4_ADDR задаёт IP в обратном порядке следования байт, что и необходимо функциям LwIP, я задавал в прямом. Как итог библиотечная функция udp_sendto_if() при проверке IP выкидывала ошибку и ничего не отправляла.

CODE
....
.... // Инициализация LwIP
....

// UDP
struct udp_pcb *pcb;
pcb = udp_new();

unsigned short port_rmt, port_local;
struct ip_addr ip_rmt, ip_local;

IP4_ADDR(&ip_rmt, 192, 168, 1, 66);
IP4_ADDR(&ip_local, 192, 168, 1, 16);
port_rmt = 12000;
port_local = 11000;

udp_bind(pcb, &ip_local, port_local);
udp_connect(pcb, &ip_rmt, port_rmt);

unsigned char buffer[128];
int i;
for(i = 0; i < 128; i++)
{
buffer[i] = i;
}

struct pbuf * pb;
pb = pbuf_alloc(PBUF_TRANSPORT, 128, PBUF_RAM);
memcpy(pb->payload, buffer, sizeof(buffer));

int tx_en = 0;
err_t error = 55;

while(1)
{
if(tx_en)
{
error = udp_send(pcb, pb);
pbuf_free(pb);
tx_en = 0;
}
}


Цитата(scifi @ Jun 4 2014, 14:31) *
То есть приём кадров Ethernet уже есть? Вот я и поинтересовался, где он. Потому что если он в обработчике прерывания, то это - бяка, так нельзя.

Ну я так глубоко пока не копал, взял пример http сервера для моей платы, и пытаюсь передрать его под UDP, что потом и буду использовать, правда, уже на другой борде. Поэтому связку LwIP->драйвер PHY оставил на потом. Следующий шаг - это отправить UDP-пакет за несколько фрагментов.

Очередной вопрос, как отправить фрагментированный UDP пакет?
scifi
Цитата(doom13 @ Jun 4 2014, 16:23) *
Очередной вопрос, как отправить фрагментированный UDP пакет?

Что значит "фрагментированный"? Фрагментация на уровне IP должна работать автомагически.
doom13
Цитата(scifi @ Jun 4 2014, 17:54) *
Что значит "фрагментированный"? Фрагментация на уровне IP должна работать автомагически.

Как бы да, это и имел ввиду. Когда флаги выставляются More Fragments, Last Fragment и поле Fragment offset.
Попробовал сделать так:
Код
    ..........
    ..........
    unsigned char buffer[4096];
    int i;
    for(i = 0; i < 4096; i++)
    {
        buffer[i] = i;
    }

    struct pbuf * pb;
    pb = pbuf_alloc(PBUF_TRANSPORT, 4096, PBUF_RAM);
    memcpy(pb->payload, buffer, sizeof(buffer));

    int tx_en = 0;

    while(1)
    {
        if(tx_en)
        {
            udp_send(pcb, pb);
            pbuf_free(pb);
            tx_en = 0;
        }
    }


т.е. передать данные длинной 4096 байт, в итоге отправилось три пакета, в сумме то, что надо - 4096 байт. Стек сам поделил на фрагменты, вроде как круто, но потом стал разбираться, оказалось в третьем фрагменте данные повторяют данные второго фрагмента, а флаги выставились неправильно, во втором фрагменте уже стоит Last Fragment, что не верно. Может либа старая или ещё что, примеры от Техаса используется LwIP v1.3.2?

Да, и поле Fragment Offset у второго и третьего фрагментов одинаковое.
doom13
WireShark для некоторых пакетов, отправляемых LwIP, выдаёт ETHERNET FRAME CHECK SEQUENCE INCORRECT, например, для ответа на ARP запрос выдаёт эту месагу.
Кто такой этот ETHERNET FRAME CHECK SEQUENCE, который получился как 5A D2 36 08, а должен был быть 4F 8F 14 D1? Ведь ethernet CRC формируется MAC-контроллером и WireShark-ом я его, по идее, не вижу.
doom13
Смотрю, что в ARP протоколе этих четырёх последних байт нету, зачем LwIP их добавляет?
jcxz
ARP-кадр у вас вроде верный.
Не забыли, что пре передаче по Ethernet, кадр дополняется до некоей величины (не помню точно, 50 с чем-то байт, вроде 54 или 56) паддингом.
Вы его имеете в виду?

PS: пользуемся своим TCP/IP-стеком, ругани от WireShark на его кадры не замечал.
Хотя у нас только ARP, IP, ICMP, TCP. UDP - не используется.
doom13
Цитата(jcxz @ Jun 5 2014, 14:15) *
ARP-кадр у вас вроде верный.
Не забыли, что пре передаче по Ethernet, кадр дополняется до некоей величины (не помню точно, 50 с чем-то байт, вроде 54 или 56) паддингом.
Вы его имеете в виду?

Да. Так вот, на втором скриншоте ARP RESPONSE от нашего сервака (в конце данные ARP добиты нулями, как и должно быть), на первом - ответ от платы с LwIP (посылка больше на 4 байта и они какой-то ерундой забиты). Если кто может проверить, посмотрите плиз, как у Вас отвечает на ARP запросы. Просто интересно, это баг LwIP v1.3.2 или техасовцы cо своими примерами где-то прокололись. Пока поставил заглушку, для ответа на ARP, уменьшаю длину пакета на 4 байта.
doom13
Приветствую.
Разбирался с работой LwIP на плате с Cortex-M3, всё было good. Счас пробую переделать проект для ARM9 (TI - AM1808) и компилятор не хочет кушать __attribute__ ((__packed__)), который используется для всех структур в LwIP. Без него всё компилится и даже работает (на плате с M3).
Можно ли использовать LwIP с #define PACK_STRUCT_STRUCT вместо #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)), во что это может вылится?
scifi
Цитата(doom13 @ Jun 10 2014, 12:57) *
Можно ли использовать LwIP с #define PACK_STRUCT_STRUCT вместо #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)), во что это может вылится?

Надо наладить упаковку структур, иначе работать не будет.
У меня, к примеру, сделано так:
в файле cc.h:
Код
...
/* Compiler hints for packing structures */
#define PACK_STRUCT_USE_INCLUDES
#define PACK_STRUCT_FIELD(x) x
#define PACK_STRUCT_STRUCT
#define PACK_STRUCT_BEGIN
#define PACK_STRUCT_END
...

в файле bpstruct.h:
Код
#pragma pack(push,1)

в файле epstruct.h:
Код
#pragma pack(pop)
doom13
Цитата(scifi @ Jun 10 2014, 12:04) *

Спасибо, то что надо.
Странно только, что техасовское условие выполняется:
Код
#if (__TI_COMPILER_VERSION__ >= 5000000)
    #define PACK_STRUCT_BEGIN
    #define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
    #define PACK_STRUCT_END
    #define PACK_STRUCT_FIELD(x) x
#endif

__TI_COMPILER_VERSION__ = 5001001, а компилер выдаёт ошибку.
doom13
Возник вопрос, получится ли использовать LwIP и AM1808 (ARM926EJ-S) у которого 128 кБ On-Chip RAM? Сколько должна весить сама либа? Пока линкер выдаёт ошибки - program will not fit into available memory. В техасовских примерах для этого процессора используется внешняя DDR2-память, может ли это означать, что без неё не обойтись и 128 кБ памяти мало для использования LwIP?
Golikov A.
LwIP можно утоптать в работу на аж на 2 КБайтах РАМ, Она для того и сделана чтобы работать на супер маленьких AVR. Другое дело что она сможет на такой памяти потянуть... Больше вопрос в том сколько flash она сожрет
scifi
Цитата(doom13 @ Jun 11 2014, 11:21) *
Возник вопрос, получится ли использовать LwIP и AM1808 (ARM926EJ-S) у которого 128 кБ On-Chip RAM? Сколько должна весить сама либа?

У мну lwip занимает 21К байт памяти программ (Cortex-M3). Это Raw API, no OS. Полное приложение занимает 85К байт памяти программ. Это не считая константы, а их много: все веб-страницы там же. Приложение содержит много функционала. По моему опыту, 32К байт оперативной памяти для буферов lwip - это оч. комфортный объём, с которым веб интерфейс летатает. Наверняка и с 16К тоже будет летать.
doom13
Цитата(Golikov A. @ Jun 11 2014, 12:03) *
LwIP можно утоптать в работу на аж на 2 КБайтах РАМ, Она для того и сделана чтобы работать на супер маленьких AVR. Другое дело что она сможет на такой памяти потянуть... Больше вопрос в том сколько flash она сожрет

Flash-а на этом проце нету, т.е. надо всё в RAM утоптать, вот и вопрос, сколько же код всех функций и прочего LwIP скушает?


Цитата(scifi @ Jun 11 2014, 12:42) *
У мну lwip занимает 21К байт памяти программ (Cortex-M3). Это Raw API, no OS. Полное приложение занимает 85К байт памяти программ. Это не считая константы, а их много: все веб-страницы там же. Приложение содержит много функционала. По моему опыту, 32К байт оперативной памяти для буферов lwip - это оч. комфортный объём, с которым веб интерфейс летатает. Наверняка и с 16К тоже будет летать.

Вот и у меня на плате с Cortex-M3 вместе с проектом переработанным из примера Техаса под Cortex-M3 весь код прошивки уместился в 38 кБ. Попытка прикрутить LwIP к ARM9 (так же на основе примера Техаса, но для ARM9) не проходит, после комента кучи функций код занимает порядка 90 кБ, а если оставить как есть, то и в 128 кБ не помещается. Что-то, наверное, для либы можно оптимизировать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.