реклама на сайте
подробности

 
 
> C++, мучения в освоении и JTAG отладке
Aprox
сообщение Mar 14 2011, 18:42
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 374
Регистрация: 7-11-07
Из: Moscow
Пользователь №: 32 131



Расскажу один назидательный случай, который случился со мной в освоении и отладке программ на С++. После того, как разобрался с помощью гуру, как разместить константы во Flash, а нев SRAM, со мной случилась другая проблема, связанная с загрузкой и JTAJ отладкой. Когда программа на С++ блистала своей красотой и лаконичностью, когда все прекрасно показывал симулятор IAR, настала пора грузить ее в кристалл. И вот тут-то началось! Отладчик JTAG упорно не хотел добегать до метки main, программа ускакивала в ловушку на векторе UndefinedHandler. Опускаю процесс поисков, сразу к сути. Оказывается, нельзя ни в коем случае в глобальных объектах заниматься инициализацией периферии кристалла. Вообще касаться периферии нельзя! Резонов два: -1. порядок вызовов конструкторов не определен, и -2 при JTAG отладке ARM после загрузки FLASH успевает промолотить еще достаточное количество инструкций прежде, чем сработает break по RESET и сдернет программу обратно в address_reset. Последнее меня и погубило. Дело в том, что я записал в конструктор куски инициализации Flash, а отладчик сдергивал кристалл как раз в момент этой инициализации. Возвращался по Reset он уже в испорченное содержимое сегмента-векторов. Победить удалось следующим приемом- из конструкторов глобальных объектов убрал любое обращение к периферии кристалла. Вместо этого, ввел в классы с периферией методы инициализации периферии типа obj.Start() с вызовом этих методов после входа в main(). Мне кажется, пережитые мучения пойдут на пользу всем, кто хочет переползти с С на С++.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
sergeeff
сообщение Mar 14 2011, 19:11
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(Aprox @ Mar 14 2011, 22:42) *
Расскажу один назидательный случай


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

Вам два совета:
- хороший тон - инициализация железа до входа в main();
- если уж хочется железо инициализировать в классах, никто не мешает объявить глобальные указатели на объекты, а в какой-либо low_level_init написать, что-нибудь типа:

Usart const *pUsart1;
....

void low_level_init(void)
{
pUsart1 = new Usart(1, 19200, 8, 1, 0); // пример чисто условный.
...
}

Есть еще варианты с singleton'ами, гарантирующими однократный вызов конструктора объекта.
Go to the top of the page
 
+Quote Post
Aprox
сообщение Mar 15 2011, 08:26
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 374
Регистрация: 7-11-07
Из: Moscow
Пользователь №: 32 131



Цитата(sergeeff @ Mar 14 2011, 22:11) *
Вам два совета:
- хороший тон - инициализация железа до входа в main();
Почему? Я вспоминаю примеры профессиональных устройств c UCOS и С++, где задачи и железо при них создаются уже после входа в main(). Например, Ethernet модули фирмы NetBurner.
Цитата
- если уж хочется железо инициализировать в классах, никто не мешает объявить глобальные указатели на объекты, а в какой-либо low_level_init написать, что-нибудь типа:

Usart const *pUsart1;
....

void low_level_init(void)
{
pUsart1 = new Usart(1, 19200, 8, 1, 0); // пример чисто условный.
...
}

Есть еще варианты с singleton'ами, гарантирующими однократный вызов конструктора объекта.
Я пробовал с low_level_init. Для JTAG отладки программ ARM-ов - не годится. Проблема в том, что для JTAG отладки периферии требуется создать глобальные переменные-указатели на SFR-регистры. Иначе отладчик просто не видит периферию. По крайней мере, у меня с отладкой на кристаллах STR91xx именно так. И если в low_level_init произвести инициализацию этих указателей, то следующая за этим инициализация сегментов просто их стирает. В результате, отладчик улетает неизвестно куда.

Я по-прежнему считаю, что самый простой и надежный прием написания программ на C++ для ARMов- это вообще не касаться периферии до входа в main().


Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Mar 15 2011, 10:10
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(Aprox @ Mar 15 2011, 11:26) *
Я пробовал с low_level_init. Для JTAG отладки программ ARM-ов - не годится. Проблема в том, что для JTAG отладки периферии требуется создать глобальные переменные-указатели на SFR-регистры.

Создать именно в программе? Зачем там лишние сущности? Подключаете ddf файл для вашего контроллера, и смотрите всю периферию.
Цитата
Иначе отладчик просто не видит периферию. По крайней мере, у меня с отладкой на кристаллах STR91xx именно так.

По моему вы придумали для себя проблему, а потом ее решили, причем далеко не лучшим способом.
Во всяком случае сейчас посмотрел установленный у себя IAR и тут:
C:\Program Files\IAR Systems\Embedded Workbench 6.0\arm\config\debugger\ST\
находятся ddf файлы в том числе для STR91xx
Причем это все автоматически подключается, если вы в качестве целевого контроллера выберите именно ваш тип контроллера, а не generiс типа ARM7 или ARM9

Цитата
И если в low_level_init произвести инициализацию этих указателей, то следующая за этим инициализация сегментов просто их стирает. В результате, отладчик улетает неизвестно куда.

При желании и эту проблему можно обойти, но в вашем случае она надумана.

Цитата
Я по-прежнему считаю, что самый простой и надежный прием написания программ на C++ для ARMов- это вообще не касаться периферии до входа в main().

Это только один из способов, причем не факт, что самый надежный. Вы лишаете себя возможности создавать глобальные объекты классов с использованием периферии, при этом вручную вынуждены в определенной последовательности вызывать функции дополнительной инициализации объектов из main или откуда то еще, то есть совершаете дополнительное действие, которое можно забыть сделать.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Aprox   C++   Mar 14 2011, 18:42
|- - Сергей Борщ   Вставьте в low_level_init задержку чтобы отладчик ...   Mar 15 2011, 10:04
||- - Aprox   Цитата(Сергей Борщ @ Mar 15 2011, 13:04) ...   Mar 15 2011, 11:20
||- - Andy Mozzhevilov   Цитата(Aprox @ Mar 15 2011, 14:20) Я рабо...   Mar 15 2011, 12:19
|||- - Aprox   Цитата(Andy Mozzhevilov @ Mar 15 2011, 15...   Mar 15 2011, 14:49
|||- - Andy Mozzhevilov   Цитата(Aprox @ Mar 15 2011, 17:49) Да, я ...   Mar 15 2011, 16:08
|||- - sergeeff   Цитата(Andy Mozzhevilov @ Mar 15 2011, 20...   Mar 15 2011, 22:01
|||- - Aprox   Цитата(Andy Mozzhevilov @ Mar 15 2011, 19...   Mar 16 2011, 07:23
||- - Сергей Борщ   QUOTE (Aprox @ Mar 15 2011, 13:20) А в бо...   Mar 15 2011, 14:01
- - Andy Mozzhevilov   Обращайтесь, если что. Можно в аську.   Mar 16 2011, 08:36
|- - Aprox   Цитата(Andy Mozzhevilov @ Mar 16 2011, 11...   Mar 17 2011, 17:28
|- - Andy Mozzhevilov   Цитата(Aprox @ Mar 17 2011, 20:28) Вы гов...   Mar 18 2011, 04:37
|- - Aprox   Цитата(Andy Mozzhevilov @ Mar 18 2011, 07...   Mar 18 2011, 08:16
|- - Andy Mozzhevilov   Цитата(Aprox @ Mar 18 2011, 11:16) Вспоми...   Mar 18 2011, 08:24
|- - Aprox   Цитата(Andy Mozzhevilov @ Mar 18 2011, 11...   Mar 18 2011, 11:10
|- - sergeeff   Цитата(Aprox @ Mar 18 2011, 15:10) Не сов...   Mar 18 2011, 18:28
|- - Aprox   Цитата(sergeeff @ Mar 18 2011, 21:28) А к...   Mar 19 2011, 09:30
|- - sergeeff   Цитата(Aprox @ Mar 19 2011, 13:30) Наверн...   Mar 19 2011, 09:38
- - MALLOY2   Цитата2. Вызвать из нее функцию статической инициа...   Mar 23 2011, 13:18
- - Andy Mozzhevilov   Цитата(MALLOY2 @ Mar 23 2011, 16:18) Можн...   Mar 23 2011, 17:30
- - Andy Mozzhevilov   Код// __iar_data_init - функция из библиотеки, вы...   Mar 24 2011, 08:12


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th July 2025 - 14:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01427 секунд с 7
ELECTRONIX ©2004-2016