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

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

24.10.2017, 05:35. Показов 1609. Ответов 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ом там где в исходном коде страницы не отображаются...

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

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

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

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

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

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

Если же происходит сдвиг всех идентификаторов в зависимости от размера информации, то придется вылавливать по всей строке эти идентификаторы и то что следует за ними.
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
26.10.2017, 11:29 4
А, кстати да... Разбор пакета гораздо проще автомата состояний... Если пакет полностью принять.
0
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
26.10.2017, 20:30  [ТС] 5
ну в зависимости от команды строка приходить мне будет постоянно разная
0
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
27.10.2017, 04:20 6
Цитата Сообщение от 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
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
27.10.2017, 16:09  [ТС] 7
длина строки да статичная, максимальная ну чтобы все вошло....
это да длина данных, значение которой мы видим в 0e
0
Эксперт С++
8483 / 6150 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
27.10.2017, 16:23 8
Цитата Сообщение от SadiQ228 Посмотреть сообщение
где можно почитать о создании парсера именно для мк ардуино?
Взять книги по С или С++ ?

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

Добавлено через 2 минуты
Цитата Сообщение от SadiQ228 Посмотреть сообщение
парсить буду ответ смарт карты в формате TLV
Для начала стоит найти точное описание формата и по нему делать.
0
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
27.10.2017, 16:35  [ТС] 9
спасибо Кэп
0
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
27.10.2017, 19:28 10
Цитата Сообщение от 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
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
01.11.2017, 20:26 11
По хорошему - надо сделать 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
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
03.11.2017, 00:04  [ТС] 12
друг подскажи у меня Тэгов около ста штук.... плюс еще и их имена.... типо вот такие ....как в примере:
'6F' File Control Information (FCI) Template
'84' Dedicated File (DF) Name
'A5' File Control Information (FCI) Proprietary Template
где мне их хранить и в каком формате? в структуре в прошивке или в eeprom таблицей? или как это похитрее то сделать? ну чтобы и память не засирать лишний раз и быстро их прочитать
0
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
03.11.2017, 00:54 13
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
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
04.11.2017, 18:01  [ТС] 14
а вот еще такой вопросик как лучше организовать приставку следующего бита?
объясняю:
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
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
04.11.2017, 20:37 15
Поправлю код:
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
Модератор
Эксперт по электронике
8951 / 6717 / 921
Регистрация: 14.02.2011
Сообщений: 23,714
04.11.2017, 21:13 16
Цитата Сообщение от Fox_exe Посмотреть сообщение
sizeof(array / sizeof(int) == 3, поскольку:
лучше писать
CВыделить код
1
sizeof (array)/sizeof(array[0]);
размер массива делим на размер первого элемента
и тогда если возникнет нужда поменять тип массива с int на char или float
не надо будет по всему листингу править
1
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
05.11.2017, 04:02  [ТС] 17
а по другому кроме как заводить еще один массив никак?
0
8 / 8 / 2
Регистрация: 01.10.2017
Сообщений: 49
05.11.2017, 09:43 18
Цитата Сообщение от SadiQ228 Посмотреть сообщение
а по другому кроме как заводить еще один массив никак?
Неа. После компиляции enum перестаёт существовать: Все перечисленыне в нем переменные заменяются по всему коду на их значения - тоесть везде, где вы писали "TMP_FCI" будет подставлено "0x00".
Соответственно, если гдето используется switch-case со значениями из enum - то все эти значения будут в оперативной памяти, а не на флеше (Памяти программы / eeprom).
По этому и приходится всячески извращаться...
1
-4 / 24 / 7
Регистрация: 16.12.2016
Сообщений: 716
12.11.2017, 03:45  [ТС] 19
дабы не плодить новых тем хочу спросить следующее: а как засечь в ms время выполнения функции на ардуино? вот я получил строку, у меня есть рабочая ( таки да) функция которая раскладывает строку... и как засечь сколько времени нужно моей функции от получения строки до полного разбора ее по пакетам?
0
techpriest
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
12.11.2017, 08:06 20
Перед вызовом функции с помощью функции micros() снимаете время в микросекундах. По выходу их функции снимаете отметку второй раз. Разница между отметками и есть интервал времени (с точностью до затрат на снятие меток)

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

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

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

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

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

Как писать приложения под андроид?
Здравствуйте, недавно я решил заняться разработкой приложений и игр под андроид. Есть у меня Rad...

С чего начать писать парсер на С++
Дали текстовый документ, раскодировал его, теперь нужно вывести информацию текстового документа в...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Как объединить два словаря одним выражением в Python
InfoMaster 19.01.2025
В мире программирования на Python работа со словарями является неотъемлемой частью разработки. Словари представляют собой мощный инструмент для хранения и обработки данных в формате "ключ-значение". . . .
Как без исключения проверить существование файла в Python
InfoMaster 19.01.2025
При разработке программного обеспечения на Python часто возникает необходимость проверить существование файла перед выполнением операций с ним. Это критически важная задача, которая помогает избежать. . .
Как определить, содержит ли строка подстроку в JavaScript
InfoMaster 19.01.2025
При разработке веб-приложений часто возникает необходимость выполнять различные операции со строками, среди которых особое место занимает поиск подстрок. JavaScript предоставляет несколько встроенных. . .
Что такое метаклассы в Python
InfoMaster 19.01.2025
Метаклассы в Python представляют собой один из самых мощных и одновременно сложных механизмов языка, позволяющий программистам контролировать процесс создания классов. По своей сути, метакласс. . .
Как удалить свойство из объекта JavaScript
InfoMaster 19.01.2025
В современной веб-разработке объекты JavaScript играют фундаментальную роль в организации и структурировании данных. Они представляют собой контейнеры, которые хранят связанные данные и. . .
Какая разница между String и string в C#
InfoMaster 19.01.2025
В языке программирования C# существует интересная особенность: для работы со строками можно использовать как String, так и string. Эта двойственность часто вызывает вопросы у разработчиков, особенно. . .
Как в Git откатить репозиторий к предыдущему коммиту
InfoMaster 19.01.2025
В современной разработке программного обеспечения система контроля версий Git стала неотъемлемой частью рабочего процесса, предоставляя разработчикам мощные инструменты для управления изменениями в. . .
Как работают замыкания (closure) в JavaScript
InfoMaster 19.01.2025
В мире современной веб-разработки замыкания (closures) представляют собой один из фундаментальных концептов языка JavaScript, который часто вызывает затруднения у начинающих разработчиков, но при. . .
Как в Linux найти все файлы, содержащие указанную строку
InfoMaster 19.01.2025
Операционная система Linux предоставляет мощный набор инструментов для поиска текста в файлах, каждый из которых имеет свои уникальные возможности и особенности применения. Центральное место среди. . .
Как поменять сообщение коммита в Git
InfoMaster 19.01.2025
Правильно оформленные сообщения коммитов существенно упрощают процесс разработки, особенно при работе в команде или при необходимости вернуться к более ранним версиям проекта. Каждое сообщение. . .
Как лучше объявлять функции в JavaScript: var functionName = function() {} или function functionName() {}
InfoMaster 19.01.2025
В мире современной веб-разработки JavaScript играет ключевую роль, предоставляя разработчикам мощные инструменты для создания динамических и интерактивных веб-приложений. Одним из фундаментальных. . .
Как сделать редирект на другую веб-страницу
InfoMaster 19.01.2025
В современной веб-разработке редирект является неотъемлемым инструментом для управления навигацией пользователей между страницами сайта. Перенаправление представляет собой автоматическое перемещение. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru