Jump to content

    

Компиляция и трассировка

При трассировки необходимо передавать информацию о функции в котором произошло событие/ошибка.  

Есть предустановленный макрос  __FUNCTION__ который возвращает указатель на имя функции в которой используется.

Но пересылать строкой (например через UART) все имя слишком накладно(слишком много букв :) ). Рациональнее было бы пересылать ID этой функции в несколько байт.

Но вот как автоматически сформировать эти идентификаторы? И самое главное как потом расшифровать их обратно в читабельный вид на принимающей стороне (сервисное ПО принимающее данные по UART).

Первое, что приходит на ум: формировать файл конфигурации (вопрос только как?) содержащий массив строк/указателей на строки, соответственно слать в терминал индекс функции из этого массива, а на обратной стороне в соответствии с этим же файлом расшифровывать посылку и выводить уже строку с именем.

Собственно вопрос в том как формировать этот файл (автоматически при компиляции) и как при выполнении функций трассировки получить соответствующий индекс?

 

Share this post


Link to post
Share on other sites
8 minutes ago, InxSergey said:

все имя слишком накладно(слишком много букв :) )

А в цифрах? Запустите UART на скорости 1 Мбит ~ 125 кБайт/сек. Допустим у вас среднее имя функции 16 символов. Это уже почти 8 тысяч имён в секунду. Конечно, я полагаю, у вас там не только имена передаются/, но и другая служебная информация. Но всё же следует всё посчитать. Может и заморачиваться с идентификаторами не потребуется.

Share this post


Link to post
Share on other sites

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

Edited by InxSergey

Share this post


Link to post
Share on other sites
6 minutes ago, InxSergey said:

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

Используйте RS-232, 485 или 422.

7 minutes ago, InxSergey said:

на значительном

Сколько?

Share this post


Link to post
Share on other sites

передавайте адрес, а на приемной стороне, по map файлу, узнаете имя

Share this post


Link to post
Share on other sites
27 minutes ago, InxSergey said:

Но вот как автоматически сформировать эти идентификаторы? И самое главное как потом расшифровать их обратно в читабельный вид на принимающей стороне (сервисное ПО принимающее данные по UART).

Они уже сформированы - это адреса функций. Но лучше такие вещи оставлять в читаемом виде.

Share this post


Link to post
Share on other sites
6 минут назад, x893 сказал:

передавайте адрес, а на приемной стороне, по map файлу, узнаете имя

... а можно написать такое "сервисное ПО", которое само поищет в .map-файле по заданному адресу. :wink:

Share this post


Link to post
Share on other sites
19 minutes ago, jcxz said:

... а можно написать такое "сервисное ПО", которое само поищет в .map-файле по заданному адресу. :wink:

Конечно. Берёте на работу

https://www.intel.ai/intel-movidius-neural-compute-stick-one-year-on/

и не только имя найдёт, но ещё и спляшет, и споёт.

Share this post


Link to post
Share on other sites

Есть вот такое, для ARM, но сам не пробовал. Трассировка посредством встроенных в ядро модулей ITM/ETM, вывод данных по SWO. Отображение с помощью плагина в Sigrok, туда же подгружается .elf файл, из которого берутся имена функций. 

А вообще, можно просто по UART текстом передавать, а чтобы не тормозило использовать FIFO+прерывания UARTa.

Share this post


Link to post
Share on other sites
22 минуты назад, x893 сказал:

Конечно. Берёте на работу

https://www.intel.ai/intel-movidius-neural-compute-stick-one-year-on/

и не только имя найдёт, но ещё и спляшет, и споёт.

 

Не выдумывайте - это работа максимум на один день для программиста средней квалификации.

Например для IAR:

1) oткрыть текстовый файл *.map

2) найти в нем блок "ENTRY LIST"

3) распарсить в массив "файл-функция-адрес-длина-тип"

4) найти свой адрес в этом массиве

5) вывести "файл-имя"

Все. Строчек 100 кода на C#. Даже пример кода бросать не буду, чтоб интерес не убивать на корню. 

Share this post


Link to post
Share on other sites
1 час назад, arhiv6 сказал:

Есть вот такое, для ARM, но сам не пробовал. Трассировка посредством встроенных в ядро модулей ITM/ETM, вывод данных по SWO. Отображение с помощью плагина в Sigrok, туда же подгружается .elf файл, из которого берутся имена функций. 

А вообще, можно просто по UART текстом передавать, а чтобы не тормозило использовать FIFO+прерывания UARTa.

SWO можно растянуть хотя бы на несколько десятков метров?

1 час назад, x893 сказал:

передавайте адрес, а на приемной стороне, по map файлу, узнаете имя

Есть ли способ автоматической подстановки адреса функции, по аналогии с именем -  __FUNCTION__

1 час назад, haker_fox сказал:

Используйте RS-232, 485 или 422.

Сколько?

RS-232 на мегабите? А вот по поводу RS485/422 дельный совет.

 

Edited by InxSergey

Share this post


Link to post
Share on other sites

А не проще передавать всего лишь 2 числа: номер .c-файла и номер строки в коде, где вылетела ошибка? У себя иногда так и делаю, когда ошибки в журнал пишу.

Share this post


Link to post
Share on other sites

Проще, думал об этом, но не пробовал, есть сомнения: как будет считать строки при наличии вложенных файлов (#include), закомментированных строк?

Номер строки __LINE__, а что такое номер файла? Стандартными методами можно автоматически получить только имя файла

 

и если есть номер файла (но что это и как получить) и номер строки, то в сервисном ПО из исходников можно вытащить и имя функции.

 

Еще одна проблема возникает если после прошивки прибора исходники изменились, и соответственно все номера съехали. Сохранять вместе с каждой серийной прошивкой к примеру map файл проще чем весь проект, состоящий часто из исходников разбросанных по разным репозиториям.

Получается напрямую строки наиболее надежный и понятный способ.

Edited by InxSergey

Share this post


Link to post
Share on other sites
2 часа назад, InxSergey сказал:

Проще, думал об этом, но не пробовал, есть сомнения: как будет считать строки при наличии вложенных файлов (#include), закомментированных строк?

Не скажу насчет всех IDE, но, например, в Keil комментирование строк и вложение файлов не ломают логику нумерации.

 

2 часа назад, InxSergey сказал:

Номер строки __LINE__, а что такое номер файла? Стандартными методами можно автоматически получить только имя файла...

В начале любого исходного .c-файла есть некий

#define SRC_FILE_ID FILE_ID_FLASH_C

а выше подключается глобальный файл настроек - вот в нем и перечислены все ID всех файлов.

Потом этот самый SRC_FILE_ID можно использовать в макросе вызова соответствующей функции-ловушки.

 

2 часа назад, InxSergey сказал:

Еще одна проблема возникает если после прошивки прибора исходники изменились, и соответственно все номера съехали...

А не надо заливать в девайс левый релиз.

У меня, например, каждая прошивка имеет уникальные параметры, такие, как контрольная сумма образа, дата и время сборки, версия самого ПО.

Ну а trunk-версия проекта хранится на рабочем сервере с системой контроля версий.

 

2 часа назад, InxSergey сказал:

Получается напрямую строки наиболее надежный и понятный способ...

Визуально человеку - да. Сервисному ПО - до лампочки.

При сборке DEBUG у меня большинство ловушек превращаются в банальный print() в консоль. В релизе - по-разному.

 

P.S. Опять же, это не панацея. Делайте, как удобно. Я и сам по-разному делаю и единообразия, как такового, нет.

Share this post


Link to post
Share on other sites
3 часа назад, InxSergey сказал:

RS-232 на мегабите? А вот по поводу RS485/422 дельный совет.

А что не так? Вот у меня сейчас девайс шлёпает лог в RS-232 на 921600 бод. Мож он чего не знает что так нельзя?  :biggrin:

Могу ему и больше вдуть - тоже будет работать.

2 часа назад, InxSergey сказал:

Еще одна проблема возникает если после прошивки прибора исходники изменились, и соответственно все номера съехали. Сохранять вместе с каждой серийной прошивкой к примеру map файл проще чем весь проект, состоящий часто из исходников разбросанных по разным репозиториям.

По одному только .map номер строки внутри функции не определите. Надо ещё и .lst сохранять.  :unknw:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now