Например TDA7294

Форум РадиоКот • Просмотр темы - Удобный массив заголовков для HTTP-сервера
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Чт фев 12, 2026 21:47:00

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Пт фев 08, 2019 19:17:47 
Родился

Зарегистрирован: Пт май 20, 2016 02:44:46
Сообщений: 12
Рейтинг сообщения: 0
Здраствуйте! Пишу маленький HTTP-сервер. Столкнулся с примитивной, но нерешимой для себя задачей. Прошу помощи у знающих людей.
Спойлер
Код:
//file   "HeadersOfHttpResponse.h"
typedef uint16_t   HttpStatusCode;//0, 100, 200, 404, 500, ect.

struct HeadersOfHttpResponse {
   HttpStatusCode         statusCode;
   uint8_t            amountItemOfHeaders;   //количество элементов в массиве
   const char * const*      headersOfHttpResponse;
};


extern HeadersOfHttpResponse      availableHeadersOfHttpResponse[];

Спойлер
Код:
/file   "HeadersOfHttpResponse.cpp"
const char HTTP_1_1_200_OK_rn_pstr[] PROGMEM = "HTTP/1.1 200 OK\r\n";
const char HTTP_1_1_500_Internal_Server_Error_rn_pstr[] PROGMEM = "HTTP/1.1 500 Internal Server Error\r\n";
const char ContentType_text_html_rn_pstr[] PROGMEM = "Content-Type: text/html\r\n";



static const char * const headersOfHttpResponse_200_ok[] PROGMEM = {//массив указателей на строки, расположенные в памяти программ
   HTTP_1_1_200_OK_rn_pstr,
   ContentType_text_html_rn_pstr,
   CRLFCRLF_pstr
};

//Массив структур инициализируем сразу!
HeadersOfHttpResponse      availableHeadersOfHttpResponse[] = {//доступные HTTP-ответы
   //индекс массива 0 (приведён для примера)
   {//HTTP-код 200
      200,   //HTTP-код (StatusCode)
      3,       //количество строк в массиве
      headersOfHttpResponse_200_ok //именованный массив указателей на строки, расположенные в памяти программ
   },
   //индекс массива 1. Ничем не отличается от нулевого, кроме способа инициализации указателя на массив указателей
   {//HTTP-код 200
      200,   //HTTP-код (StatusCode)
      3,       //количество строк в массиве
      (const char * const[]) {//анонимный массив указателей на строки, расположенные в памяти программ
         HTTP_1_1_200_OK_rn_pstr,
         ContentType_text_html_rn_pstr,
         CRLFCRLF_pstr
      }
   },
   //индекс массива 2
   {//HTTP-код 500
      500,      //HTTP-код (StatusCode)
      3,        //количество строк в массиве
      (const char * const[]){//анонимный массив указателей на строки, расположенные в памяти программ
         HTTP_1_1_500_Internal_Server_Error_rn_pstr,
         ContentType_text_html_rn_pstr,
         CRLFCRLF_pstr
      }
   },
};


Кратко опишу весь этот "зоопарк".
"availableHeadersOfHttpResponse[]" — глобальный массив доступных в программе HTTP-ответов. Когда сервер решает ответить на запрос, например,
кодом "200", то он ищет соответствие среди элементов данного массива. И отправляет соответствующие строки заголовков, а потом уже запрошенный файл. Строки распологаются в памяти программ.

Собственно, код компилируется без варнингов. Компилятор (AVR Studio v4.19) молчит как партизан.
Чтение строк массива "availableHeadersOfHttpResponse[0].headersOfHttpResponse" происходит корректно.
А вот чтение строк из массивов "availableHeadersOfHttpResponse[1].headersOfHttpResponse" и "availableHeadersOfHttpResponse[2].headersOfHttpResponse" выдаёт
всё что угодно, но только не то что надо! Я так понимаю указатель ".headersOfHttpResponse" указывает куда-то не туда. :)))
Так вот вопрос.
Как обойтись только анонимными массивами, без массивов типа "static const char * const headersOfHttpResponse_200_ok[] PROGMEM"?
Методом научного тыка, перепробовал массу разных комбинаций.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 09:39:45 
Мудрый кот
Аватар пользователя

Карма: 24
Рейтинг сообщений: 286
Зарегистрирован: Чт июн 10, 2010 08:55:35
Сообщений: 1810
Откуда: Сибирские Афины
Рейтинг сообщения: 0
Хм... Ну, очень вероятно, вы неправильно "достаёте" строки.
Банально дам ссылку, проверьте всё ещё раз. И проверьте как вы достаёте строки из флэша.
https://www.microchip.com/webdoc/AVRLib ... rings.html

_________________
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 09:46:15 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2121
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18460
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
пора отказываться от геморроя с pgm_read_xxx, применяйте модификатор __flash и работайте полноценно с "переменными" во flash и указателями на данные там же.
модификатор __flash__memx, кстати - тоже неплохая фишка) доступен с версии avr-gcc 5.x.x (по-моему, сам я на 6-й сижу, но есть уже и 8).

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 10:39:18 
Мудрый кот
Аватар пользователя

Карма: 24
Рейтинг сообщений: 286
Зарегистрирован: Чт июн 10, 2010 08:55:35
Сообщений: 1810
Откуда: Сибирские Афины
Рейтинг сообщения: 0
Ну, да и это тоже в тему.
https://gcc.gnu.org/onlinedocs/gcc/Name ... ess-Spaces

_________________
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 11:08:00 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 66
Рейтинг сообщений: 536
Зарегистрирован: Чт июл 28, 2016 07:58:37
Сообщений: 1925
Откуда: Kyiv, UA
Рейтинг сообщения: 0
ARV писал(а):
применяйте модификатор __flash

Походу это те же яйца, только в профиль.
Обертка того же pgm_read'а. В обоих случаях компилятор сотворит закидывание адреса чтения в ZL,ZH и выполнит LPM Rxx, Z[+]
Причем меня сильно гложет сомнение, что если читать циклом массив данных, то gcc поймет это и будет использовать директиву с автоинкрементом Z.
С __flash не пробовал, но вот такую конструкцию
Код:
   while(counter) {
      *(ram++) = pgm_read_byte(pgm++);
      counter--;
   }


компилятор разворачивает в отдельный LPM Rxx,Z и отдельный инкремент Z-пары
Код:
   while(counter) {
00002189  MOVW R30,R22      Copy register pair
0000218A  TST R20      Test for Zero or Minus
0000218B  BREQ PC+0x08      Branch if equal
      *(ram++) = pgm_read_byte(pgm++);
0000218C  LPM R18,Z      Load program memory
0000218D  MOVW R26,R24      Copy register pair
0000218E  ST X+,R18      Store indirect and postincrement
0000218F  MOVW R24,R26      Copy register pair
      counter--;
00002190  SUBI R20,0x01      Subtract immediate
00002191  ADIW R30,0x01      Add immediate to word
00002192  RJMP PC-0x0008      Relative jump
}


И я не уверен, что __flash скомпилируется по другому. Но pgm_read дает более полное понимание того, что делается.

_________________
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 11:09:58 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 482
Зарегистрирован: Сб сен 10, 2011 17:46:25
Сообщений: 3832
Рейтинг сообщения: 0
Цитата:
Компилятор (AVR Studio v4.19)

наверное старенький или WinAVR или старый тулчейн от А
делал когда-то по
http://www.tuxgraphics.org/electronics/ ... 6111.shtml
Спойлер
Код:
// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf,uint8_t on_off)
{
        uint16_t plen;
        plen=fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
        plen=fill_tcp_data_p(buf,plen,PSTR("<center><p>Output is: "));
        if (on_off){
                plen=fill_tcp_data_p(buf,plen,PSTR("<font color=\"#00FF00\"> ON</font>"));
        }else{
                plen=fill_tcp_data_p(buf,plen,PSTR("OFF"));
        }
        plen=fill_tcp_data_p(buf,plen,PSTR(" <small><a href=\".\">[refresh status]</a></small></p>\n<p><a href=\"."));
        if (on_off){
                plen=fill_tcp_data_p(buf,plen,PSTR("/0\">Switch off</a><p>"));
        }else{
                plen=fill_tcp_data_p(buf,plen,PSTR("/1\">Switch on</a><p>"));
        }
        plen=fill_tcp_data_p(buf,plen,PSTR("</center><hr><br>version 2.17, tuxgraphics.org\n"));
        return(plen);
}

Код:
// fill in tcp data at position pos. pos=0 means start of
// tcp data. Returns the position at which the string after
// this string could be filled.
uint16_t fill_tcp_data_p(uint8_t *buf,uint16_t pos, const prog_char *progmem_s)
{
        char c;
        // fill in tcp data at position pos
        //
        // with no options the data starts after the checksum + 2 more bytes (urgent ptr)
        while ((c = pgm_read_byte(progmem_s++))) {
                buf[TCP_CHECKSUM_L_P+3+pos]=c;
                pos++;
        }
        return(pos);
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 12:24:27 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2121
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18460
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
goldenandy писал(а):
И я не уверен, что __flash скомпилируется по другому. Но pgm_read дает более полное понимание того, что делается.
я вас уверяю, что не смотря на то, что компилятор делает то же самое, для вас более полное понимание того, что делается, будет именно в случае __flash.

простой пример: вы храните в FLASH массив, состоящий из указателей на массивы структур (тоже во FLASH), внутри которых тоже указатели на другие данные во FLASH (такое запросто бывает в случае организации меню многоуровневого, например). просто напишите что-то аналогичное этому:
Код:
const __flash my_struct *ptr = &my_array_from_flash;

if(ptr[1]->my_field->name != NULL) pfintf_P(PSTR("Name = %S"), ptr[1]->my_field->name);
c использованием pgm_read_xxxx... думаю, у вас будет такой огород преобразования типов, и все равно разыменование указателей из FLASH так просто не получится сделать без промежуточных pgm_read_xxxx...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Удобный массив заголовков для HTTP-сервера
СообщениеДобавлено: Вс фев 10, 2019 15:39:17 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 66
Рейтинг сообщений: 536
Зарегистрирован: Чт июл 28, 2016 07:58:37
Сообщений: 1925
Откуда: Kyiv, UA
Рейтинг сообщения: 0
ARV писал(а):
более полное понимание того, что делается, будет именно в случае __flash


Может быть, тут уж кто как привык.

Я железнозависимые вещи вообще стараюсь выносить в HAL либо в другую библиотеку.
Там один раз чтение обернуть в макрос или функцию - и забыть.

для основной программы это вообще должно быть некоей функцией getHttpResponseStr(unsigned char responseIndex, char* responseBuf);

А хранить массив строк во флеше AVR'ок можно либо объявив каждую строку как свой массив и потом сложить массив указателей на строки, либо пожертвовать неким объемом флеша и объявить двумерный массив с явным указанием максимальной длины строк...
Код:
const __flash my_stringArr[][160] = {"String one", "Strung two", Superstring"};

_________________
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 33


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y