Форум программистов, компьютерный форум, киберфорум
Arduino
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/8: Рейтинг темы: голосов - 8, средняя оценка - 5.00
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716

Как писать парсер строки под дуино?

24.10.2017, 05:35. Показов 1651. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
где можно почитать о создании парсера именно для мк ардуино? ну там же память надо экономить туда сюда... не хочу чтобы он занимал более 20%
парсить буду ответ смарт карты в формате TLV
тоесть из вот такого
C Скопировано
1
6f 2c 84 0e 32 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 1a bf 0c 17 61 15 4f 07 a0 00 00 00 04 30 60 87 01 01 50 07 4d 41 45 53 54 52 4f 90 00
хотелось бы получить вот такое
C Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
6F File Control Information (FCI) Template (44 Byte)
 84 Dedicated file (DF) Name (14 Byte)
    32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
 A5 File Control Information (FCI) Proprietary Template (26 Byte)
  BF0C File Control Information (FCI) Issuer Discretionary Data (23 Byte)
   61 Application Template (21 Byte)
    4F Application Identifier (AID) - card (7 Byte)
       A0 00 00 00 04 30 60
    87 Application Priority Indicator (1 Byte)
       01
    50 Application Label (7 Byte)
       4D 41 45 53 54 52 4F
90 Issuer Public Key Certificate
это мой первый не тривиальный код под ардуину поэтому прошу советов у опытных коллег, как лучше и хитрее организовать данное дело?
на что в первую очередь обратить внимание? посоветуйте статьи и публикации на тему парсеров под ардуино.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.10.2017, 05:35
Ответы с готовыми решениями:

Как писать сложный парсер?
как писать сложный парсер сайтов с javasriptом там где в исходном коде страницы не отображаются тексты например ответы mail.ru или...

Как писать под RockBox?
Всем здравствуйте! :) У меня возникла такая проблема: нужно написать какую-нибудь игру ил программу для плеера, работающего на...

Как писать под windows?
Как писать на java под windows - какую лучше использовать среду разработки Eclipse или какую нибудь другую?? И как будет выглядеть...

19
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
24.10.2017, 11:14
Как правило такая задача решается построением автомата состояний. То есть вы в зависимости от предшествующего ввода меняете состояние своего автомата и соответствующим образом интерпретируете следующий байт. В базовом виде, без украшательств, получается длинный switch-case-if-else-goto... Есть более академические подходы к построению парсеров, но тут они избыточны.

Добавлено через 26 минут
Собственно, такой автомат побайтно получает данные и в зависимости от них изменяет своё состояние.
1
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
26.10.2017, 08:03
SadiQ228, вообще есть куча решений, начиная от регулярок и заканчивая собственными велосипедами.
Начинать надо с того, что у вас все таки строка имеет статичный размер или нет?
Грубо говоря первый и 3й байт всегда останутся на своем месте и например 15й или все таки после 3го байта может быть менее 14 байт?

Если все статично, то в чем вообще проблема выделить свои буфера статичные под эту строку и дергать уже в каждый буфер инфу по своим индексам?

Если же происходит сдвиг всех идентификаторов в зависимости от размера информации, то придется вылавливать по всей строке эти идентификаторы и то что следует за ними.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.10.2017, 11:29
А, кстати да... Разбор пакета гораздо проще автомата состояний... Если пакет полностью принять.
0
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
26.10.2017, 20:30  [ТС]
ну в зависимости от команды строка приходить мне будет постоянно разная
0
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
27.10.2017, 04:20
Цитата Сообщение от SadiQ228 Посмотреть сообщение
ну в зависимости от команды строка приходить мне будет постоянно разная
строка то понятно что разная - я спрашивал про длину строки???

Цитата Сообщение от SadiQ228 Посмотреть сообщение
84 Dedicated file (DF) Name (14 Byte)
* * 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
*A5 File Control Information (FCI) Proprietary Template (26 Byte)
между байтом со значением 84 и байтом A5 статичная длина этого массива данных?

Цитата Сообщение от SadiQ228 Посмотреть сообщение
32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
0
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
27.10.2017, 16:09  [ТС]
длина строки да статичная, максимальная ну чтобы все вошло....
это да длина данных, значение которой мы видим в 0e
0
Эксперт С++
 Аватар для Avazart
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
27.10.2017, 16:23
Цитата Сообщение от SadiQ228 Посмотреть сообщение
где можно почитать о создании парсера именно для мк ардуино?
Взять книги по С или С++ ?

Цитата Сообщение от SadiQ228 Посмотреть сообщение
ну там же память надо экономить туда сюда... не хочу чтобы он занимал более 20%
парсить буду ответ смарт карты в формате TLV
тоесть из вот такого
Зачем экономить ? Экономить надо когда ее начинает хватать.

Добавлено через 2 минуты
Цитата Сообщение от SadiQ228 Посмотреть сообщение
парсить буду ответ смарт карты в формате TLV
Для начала стоит найти точное описание формата и по нему делать.
0
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
27.10.2017, 16:35  [ТС]
спасибо Кэп
0
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
27.10.2017, 19:28
Цитата Сообщение от SadiQ228 Посмотреть сообщение
длина строки да статичная, максимальная ну чтобы все вошло....
это да длина данных, значение которой мы видим в 0e
значит нечего изобретать велосипед - в твоем случае ты знаешь индексы нужных тебе байтов и данных следующих за ними..
У тебя в любом случае

Цитата Сообщение от SadiQ228 Посмотреть сообщение
84 Dedicated file (DF) Name (14 Byte)
* * 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
84 определен индексом 3, а 4й индекс у тебя содержит размер твоей всей строки, хотя это по сути и не надо вот и делай что то наподобии такого
Я парсил PDUS формат GSM модема, получается что то типа такого - создал структуру и в нее пихаешь данные, а индексы твои это разделители.

C++ Скопировано
1
2
3
4
5
  //с 12 по 17 байт - номер входящий, 19й - кодировка, 27й - размер текста в байтах, с 28го и до конца - текст сообщения
  //  1й   2й              9й  10й  11й 12й       17й  18й  19й                   27й   28й
  //  07   91 9732520180F1 24  0B   91  9731128885F3   00   00   61303281232242   04    D4F29C0E
  
  inputSms.incomingNumberPdu = lineFullStr.substring(22 + shiftInd, 34 + shiftInd); //Выдернули номер в режиме PDU - его надо еще перевести в нормальный формат
соответственно пиши в структуру или просто отдельные массивы с того индека с которого требуется инфу и все, ничего придумывать не надо
1
 Аватар для Fox_exe
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
01.11.2017, 20:26
По хорошему - надо сделать struct и заполнять уже его. Но в силу ограниченности ресурсов - проще в цикле читать данные из консоли и обрабатывать их по мере поступления.

Скажем, формат такой:
C++ Скопировано
1
2
3
4
5
6
7
8
9
struct TLVHEADER
{
    uint8_t dataType;
    uint8_t dataSize;
    char *data;
};
 
// setup() { ...
TLVHEADER tlvHeader = { 1, 14, F("Hello, world!") };    // 14й символ в строке = NULL (Невидим в коде)
В консоль они идут форматом: "01 0E 01 02 03 04 05 06 07 08 09 10 11 12 13 00"

Тоесть читаем через Serial.read() по 3 символа, первые два конвертиуем в число через atoi(), получаем тип данных (Строка), читаем снова 3 символа, первые 2 конвертим в число, получаем длинну (14).
Создаем char *string и считываем 14 раз по 3 байта, ковертируя первые 2 в сивол (*string = convertedChar; *string++). Последним будет NULL (0x00) - тоесть конец строки. (Тут оговорка - можно было бы читать до NULL, тогда и байт длины строки не нужен. Но это уже другая история).

Кажысь все верно расписал. Хотя и без кода.
1
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
03.11.2017, 00:04  [ТС]
друг подскажи у меня Тэгов около ста штук.... плюс еще и их имена.... типо вот такие ....как в примере:
'6F' File Control Information (FCI) Template
'84' Dedicated File (DF) Name
'A5' File Control Information (FCI) Proprietary Template
где мне их хранить и в каком формате? в структуре в прошивке или в eeprom таблицей? или как это похитрее то сделать? ну чтобы и память не засирать лишний раз и быстро их прочитать
0
 Аватар для Fox_exe
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
03.11.2017, 00:54
C++ Скопировано
1
2
3
#define DATA_FCITMP 0x6f
#define DATA_DFNAME 0x84
#define DATA_FCIPTMP    0xa5
или так (Правильнее)
C++ Скопировано
1
2
3
4
5
6
7
8
enum DATA_VALUES {
    TMP_FCI = 0x00,
    TMP_FCIP    = 0x01,
    DF_NAME = 0x02,
    FIRST   = 0xAA,
    SECOND  = 0xBB,
    THIRD   = 0xCC,
};
* Значения можно не указывать - по умолчанию присваиваются числа от 0 и по нарастающей.

Далее делаем массив, сохраненный в флеш-памяти (eeprom):
C++ Скопировано
1
2
3
4
5
6
uint8_t PROGMEM valuesArray[sizeof(DATA_VALUES )];
 
for (uint8_t i = 0; i < sizeof(DATA_VALUES ); i++)
{
    valuesArray[i] = static_cast<DATA_VALUES >(i);
}

... Пишу по памяти, может немного ошибся...
1
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
04.11.2017, 18:01  [ТС]
а вот еще такой вопросик как лучше организовать приставку следующего бита?
объясняю:
C Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
 
#define ARR_SIZE 4
 
int main( void )
{
    enum DATA
    {
        FIRST  = 0xAA,
        SECOND = 0xBB,
        THIRD  = 0xCC
    };
    
    int array[ ARR_SIZE ] = { 0x6F, 0xBB, 0x84, 0x0E };
    
    
    for ( unsigned i = 0; i < ARR_SIZE; ++i )
        switch( array[ i ] )
        {
        case FIRST:  puts( "0xAA First"  ); break;
        case SECOND: puts( "0xBB Second" ); break;
        case THIRD:  puts( "0xCC Third"  ); break;
        }
        
}
в таком коде все четко, но если элемент массива, при разборе битов, имеет с 1 бита по 5 единички, то значние arr[i] у меня должно быть как бы arr[i i+1]
привожу пример:
C Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
 
#define ARR_SIZE 4
 
int main( void )
{
    enum DATA
    {
        FIRST  = 0x6F,
        SECOND = 0xBFCD,
        THIRD  = 0x0E
    };
    
    int array[ ARR_SIZE ] = { 0x6F, 0xBF, 0xCD, 0x0E };
    
    
    for ( unsigned i = 0; i < ARR_SIZE; ++i )
        switch( array[ i ] )
        {
        case FIRST:  puts( "0xAA First"  ); break;
        case SECOND: puts( "0xBFCD Second" ); break;
        case THIRD:  puts( "0xCC Third"  ); break;
        }
        
}
я знаю как маской проверять биты, тоесть условие задам для проверки, а дальше то что?
как бы решить такое объединение байтов? сижу вот думаю чет на ум не приходит ничего
0
 Аватар для Fox_exe
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
04.11.2017, 20:37
Поправлю код:
C++ Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main(void)
{
    enum DATA
    {
        FIRST =     0x6F,   // == 0x006F
        SECOND =    0xBFCD,
        THIRD =     0xE     // == 0x000E
    };
 
    // Размер массива писать не нужно, если переменные в нем задаются явно
    int array[] = { FIRST, SECOND, THIRD }; // Имена заменятся на значения компилятором.
 
    // sizeof(array / sizeof(int) == 3, поскольку:
    // sizeof(array) = 6 (3 значения по 2 байта)
    // sizeof(int) = 2 (байта). Это если Ардуина. Редко, но бывает и 4 (32 бит). Зависит от компилятора.
    // т.к. считаем от нуля - то [i < array_size] правильно. при array_size = 3
    // А вот если от 1 считать, то надо заменить на [i <= array_size]
 
    for (uint8_t i = 0; i < sizeof(array) / sizeof(int); i++)
    {
        switch (array[i])
        {
            case FIRST:  puts("0xAA First"); break;
            case SECOND: puts("0xBFCD Second"); break;
            case THIRD:  puts("0xCC Third"); break;
        }
    }
}
1
Модератор
Эксперт по электронике
8962 / 6728 / 921
Регистрация: 14.02.2011
Сообщений: 23,752
04.11.2017, 21:13
Цитата Сообщение от Fox_exe Посмотреть сообщение
sizeof(array / sizeof(int) == 3, поскольку:
лучше писать
C Скопировано
1
sizeof (array)/sizeof(array[0]);
размер массива делим на размер первого элемента
и тогда если возникнет нужда поменять тип массива с int на char или float
не надо будет по всему листингу править
1
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
05.11.2017, 04:02  [ТС]
а по другому кроме как заводить еще один массив никак?
0
 Аватар для Fox_exe
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
05.11.2017, 09:43
Цитата Сообщение от SadiQ228 Посмотреть сообщение
а по другому кроме как заводить еще один массив никак?
Неа. После компиляции enum перестаёт существовать: Все перечисленыне в нем переменные заменяются по всему коду на их значения - тоесть везде, где вы писали "TMP_FCI" будет подставлено "0x00".
Соответственно, если гдето используется switch-case со значениями из enum - то все эти значения будут в оперативной памяти, а не на флеше (Памяти программы / eeprom).
По этому и приходится всячески извращаться...
1
 Аватар для SadiQ228
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
12.11.2017, 03:45  [ТС]
дабы не плодить новых тем хочу спросить следующее: а как засечь в ms время выполнения функции на ардуино? вот я получил строку, у меня есть рабочая ( таки да) функция которая раскладывает строку... и как засечь сколько времени нужно моей функции от получения строки до полного разбора ее по пакетам?
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
12.11.2017, 08:06
Перед вызовом функции с помощью функции micros() снимаете время в микросекундах. По выходу их функции снимаете отметку второй раз. Разница между отметками и есть интервал времени (с точностью до затрат на снятие меток)

Если функция выполняется слишком быстро, то единичный прогон может быть малоинформативен.
Тогда делаем снимаем интервал над выполнением цикла из 100-1000 выполнений функции.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.11.2017, 08:06
Помогаю со студенческими работами здесь

Как писать плугины на С++ под RRose?
Народ! Как писать плугины на С++ под RRose? Кто может объяснить что такое вообще плугины и структуру их написания. lama@mail.ru

Как начать писать под iOS?
Дабы &quot;въехать&quot; в Си почитал Сишную часть книги Аарона Хиллегаса. Для понятия синтакса почитал некие темы Кочана которые, как по мне, мне...

Как писать в python 3 под java?
Есть у кого сведения какие? Добавлено через 11 минут Jython 3 выйдет или нет?

Как писать под Android в Eclipse?
Здравствуйте. Раньше писал только под ПК, а тут решил попробовать написать под андроид. Установил SDK, установил ADT Plugin, создаю...

Как писать резиденты под винду
&quot;Машущая ладошка)&quot; В общем темой я давно интересуюсь и нигде не нахожу дельного ответа.. Насколько я понимаю, виндовс какими-то магическими...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Параллельное программирование с OpenMP в C++
NullReferenced 24.04.2025
Параллельное программирование — подход к созданию программ, когда одна задача разбивается на несколько подзадач, которые могут выполняться одновременно. Оно стало необходимым навыком для. . .
Цепочки методов в C# с Fluent API
UnmanagedCoder 24.04.2025
Современное программирование — это не только решение функциональных задач, но и создание кода, который удобно поддерживать, расширять и читать. Цепочки методов и Fluent-синтаксис в C# стали мощным. . .
Мульти-тенантные БД с PostgreSQL Row Security
Codd 23.04.2025
Современные облачные сервисы и бизнес-приложения всё чаще обслуживают множество клиентов в рамках единой программной инфраструктуры. Эта архитектурная модель, известная как мульти-тенантность, стала. . .
Реализация конвейеров машинного обучения с Python и Scikit-learn
AI_Generated 23.04.2025
Мир данных вокруг нас растёт с каждым днём, и умение эффективно обрабатывать информацию стало необходимым навыком. Специалисты по машинному обучению ежедневно сталкиваются с задачами предобработки. . .
Контроллеры Kubernetes Ingress: Сравнительный анализ
Mr. Docker 23.04.2025
В Kubernetes управление входящим трафиком представляет собой одну из ключевых задач при построении масштабируемых и отказоустойчивых приложений. Ingress — это API-объект, который служит вратами. . .
Оптимизация кода Python с Cython и Numba
py-thonny 23.04.2025
Python прочно обосновался в топе языков программирования благодаря своей простоте и гибкости. Разработчики любят его за читабельность кода и богатую экосистему библиотек. Но у этой медали есть и. . .
Микросервис на Python с FastAPI и Docker
ArchitectMsa 23.04.2025
В эпоху облачных вычислений и растущей сложности программных продуктов классическая монолитная архитектура всё чаще уступает место новым подходам. Микросервисная архитектура становится фаворитом. . .
Создаем веб-приложение на Vue.js и Laravel
Reangularity 23.04.2025
Выбор правильного технологического стека определяет успех веб-проекта. Laravel и Vue. js формируют отличную комбинацию для создания современных приложений. Laravel — это PHP-фреймворк с элегантным. . .
Максимальная производительность C#: Span<T> и Memory<T>
stackOverflow 22.04.2025
Мир высоконагруженных приложений безжалостен к неэффективному коду. Каждая миллисекунда на счету, каждый выделенный байт памяти может стать причиной падения производительности. Разработчики на C#. . .
JWT аутентификация в Java
Javaican 21.04.2025
JWT (JSON Web Token) представляет собой открытый стандарт (RFC 7519), который определяет компактный и самодостаточный способ передачи информации между сторонами в виде JSON-объекта. Эта информация. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер