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

 
 
 
Reply to this topicStart new topic
> hard fault stm32
dimanisu
сообщение Oct 24 2011, 20:48
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



Здравствуйте!

Столкнулся со следующей проблемой.
Разрабатываю в keil под stm32. Раньше все проекты писал на си. Сейчас решил опробовать с++.
В проекте много сишных файлов. Включил в проект один .cpp файл. Все работало. Решил немного усложнить используемый класс. Ввел наследование. И программа посыпалась – вылетает в hard_fault прерывание. Причем не там, где вызываются мои объекты с их методами, а гораздо раньше и в совершенно другом месте.
Объекты создаются как обычно, а не через new:
TItem item((const u8*)”текст”);
Причем обнаружил следующую закономерность:
Если уменьшить количество создаваемых объектов, то программа вроде как работает. Но вот если добавить несколько строчек кода в любое другое место, программа опять вылетает в hard_fault.
Пробовал увеличивать размер стека и кучи. Это не помогло.
Раньше с таким не сталкивался
Подскажите пожалуйста, в чем может быть загвоздка?

Вылетает при обращении к жки. Он висит на fsmc шине. Раньше все работало нормально.
CODE
Код
typedef struct
{
volatile u16 reg;
volatile u16 ram;
} Tlcd;


// Note: LCD /CS is CE4 - Bank 4 of NOR/SRAM Bank 1~4
#define LCD_BASE ((u32)(0x60000000 | 0x0C000000))
#define LCD ((Tlcd *) LCD_BASE)


#define WRITE_CMD(value) LCD->reg=value
#define WRITE_DATA8(value) LCD->ram=value

*************************************************

void init_lcd (void)
{

//разный код

WRITE_CMD(LCD_SOFT_RESET);
WRITE_CMD(LCD_SOFT_RESET); // вылетает здесь
WRITE_CMD(LCD_SOFT_RESET);

}

// вот что творит keil
Код
199: WRITE_CMD(SSD1963_SOFT_RESET);
0x08003E88 2001 MOVS r0,#0x01
0x08003E8A F04F41D8 MOV r1,#0x6C000000
0x08003E8E 8008 STRH r0,[r1,#0x00]
200: WRITE_CMD(SSD1963_SOFT_RESET);
0x08003E90 8008 STRH r0,[r1,#0x00]
201: WRITE_CMD(SSD1963_SOFT_RESET);
202:
0x08003E92 8008 STRH r0,[r1,#0x00]


Сообщение отредактировал IgorKossak - Oct 25 2011, 07:21
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 26 2011, 09:01
Сообщение #2


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



объекты создаются глобально или на стеке?
Go to the top of the page
 
+Quote Post
dimanisu
сообщение Oct 26 2011, 10:34
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



Объекты создаются глобально.
Go to the top of the page
 
+Quote Post
dimanisu
сообщение Oct 26 2011, 13:17
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



У меня такое ощущение, что затык как раз в том, что объекты глобальные. Насколько я понял они создаются до вызова main и тем самым как то поганят программу.
Нужно еще выполнять какие либо танцы с бубном, чтобы использовать с++ файлы совместно с сишними (ну там выставлять опции компилятора, править стартапы и т.д. и т.п)?

Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 27 2011, 03:46
Сообщение #5


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

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(dimanisu @ Oct 26 2011, 17:17) *
У меня такое ощущение, что затык как раз в том, что объекты глобальные.

Посмотрите тут мою реализацию. Может поможет.
До того, как я стал делать так, как описал, то сталкивался с проблемой, очень похожей на вашу: при статическом создании экэмпляров классов их порядок имел значение.
А вообще, код перед кодированием приходится всегда вначеле проектировать, иначе получится каша, которую по-просту уже невозможно отлаживать.
А у вас есть структура (дерево) классов проекта или что-то подобное?


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
dimanisu
сообщение Oct 27 2011, 06:11
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



Цитата
А у вас есть структура (дерево) классов проекта или что-то подобное?

Есть, структуру я уже продумал. Я сейчас создаю простой gui. И решил испробовать c++ реализацию. Пока создал два класса. TItem и наследника TMenu. Если без наследования(т.е. все в одном классе) то все работает, но вот с наследованием и случается эта беда.

Классы немного упрощены и все поля объявлены как public (потом раскидаю по секциям как надо)
CODE
class TItem;

class TItem
{
public:
u16 id;
const u8* text;
TItem* parent;
TItem* prev; // предыдущий сосед
TItem* next; // следующий сосед
TItem* child;
TItem* selected; //выбранный пункт меню
u16 count; // счетчик узлов

static TItem* active;

TItem (const u8* text);
void activate(TItem* item); // установка активным друго пункта меню

virtual void add(TItem* item);
virtual void draw();
virtual void event(u32 event, u32 param1=0, u32 param2=0){}
};


class TMenu : public TItem
{
public:
TItem* visible_first_child; //первый отображаемый пункт
TItem* visible_last_child; //последний отображаемый пункт

TMenu (const u8* text, u16 num_visible_items=1);
virtual void add(TItem* item);
virtual void draw();
virtual void event(u32 event, u32 param1=0, u32 param2=0);
};


Сообщение отредактировал IgorKossak - Oct 27 2011, 07:59
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 27 2011, 07:14
Сообщение #7


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

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(dimanisu @ Oct 27 2011, 10:11) *
Классы немного упрощены и все поля объявлены как public (потом раскидаю по секциям как надо)

Пара дельных советов из моего печального опыта:
поля класса (это объекты-данные класса) НИКОГДА не ставьте в секцию public, даже для целей отладки
Для полей допустимо только private, в особых случаях protected.
Это - пагубная привычка, потому что потом так и останется :-))
Через методы можно ограничить доступ к полям, там же защитить их мьютексами/критическими секциями...
Т.е. доступ к полям должен прозводится ТОЛЬКО через методы класса.
А если все же требуется прямое обращение к полям, то это уже не класс, а обычная структура (разумеется без методов).

Где возможно расставлять const - это защищает от лени программиста искать правильные пути.

Вообще мне не понятно, зачем вы пишите свой GUI, для изучения С++?
Есть же ведь готовые реализации GUI в исходниках и на C++. Берите их и изучайте.
Благо щас готового и даже полностью бесплатного софта море, вот лет 5..10 назад такого увы не было...



--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
dimanisu
сообщение Oct 27 2011, 08:01
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



Цитата
Т.е. доступ к полям должен прозводится ТОЛЬКО через методы класса.

Так и делал изначально. Но потом, когда вылез этот косяк, стал все упрощать, чтобы понять в чем дело

Цитата
Вообще мне не понятно, зачем вы пишите свой GUI, для изучения С++?


С++ мне не нужно изучать. Мне не нужны навороченные gui библиотеки. GUI будет простой. Я начал его писать на си, но потом решил попробовать c++. Под arm ранее писал только на си. Использование С++ для контроллеров для меня в диковинку, вот и решил попробовать.
И Сразу грабли biggrin.gif.

Под дебагером смотрел - сначала вызываются конструкторы, потом только main.

Цитата
Есть же ведь готовые реализации GUI в исходниках и на C++.

Если не не сложно киньте ссылочкой на с++ реализацию под arm.


Go to the top of the page
 
+Quote Post
Forger
сообщение Oct 27 2011, 08:21
Сообщение #9


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

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(dimanisu @ Oct 27 2011, 12:01) *
Под дебагером смотрел - сначала вызываются конструкторы, потом только main.


Все верно, так и должно быть, однако порядок вызова конструкторов определяет линковщик.
Ясное дело объекты в пределах одного cpp файла создаются в порядке их объявления (хотя я в этом не особо уверен).
А вот в каком порядке линковщих собирает откомпилированные срр файлы - неизвестно,
а это создает немалые сложности, которые зависят от компилятора.
А в классе объекты-поля ВСЕГДА создаются в порядке их перечисления - это стандарт С++.
Все это важно, когда все объекты создаются статически, т.е. до вызова main.
Но если использовать кучу - эта проблема отпадает, но возникает другая - сама куча.
Например, я стараюсь избегать использования кучи везде, где это возможно, а взамен нее использовать пулы (fixed size memory pool) или стек.
Разумеется, тут я имею ввиду embedded приложения - под виндой все это намного прозаичнее, хотя тоже требует осмысленных действий.

Я еще частенько использую другой способ - отложенная инициализация,
это когда взамен конструктора (или только часть его реализации) заменяется спец. методом, у меня он называется initialize(),
который вызывает уже в коде, это дает возможность в нужном порядке инициализировать объейты классов.

Цитата
Если не не сложно киньте ссылочкой на с++ реализацию под arm.

Для примера вот конкретно под Win X.
Есть весьма популярная Qt, но она мне кажется монстроподобной для небольших embedded.
Ну и стандартно: google :-))
Переписать драйвер под свой проц и железо - проблем нет.
Потом есть масса С реализаций GUI платформонезависимые, а не тока "под ARM" или что-то еще.
C++ "обертку" под C реализацию тоже можно создать. Не так сложно, как кажется - главное, сначала спроектировать все.
Например, я так сделал обертку под RTOS, теперь в ЛЮБОМ проекте мне по-барабану, какая ось стоит,
Это оказалось весьма удобной штукой как при сопровождении так и создании новых проектов на базе других.
Я бы попробовал именно такой путь (возможно, скоро этим и сам займусь )))).


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 28 2011, 07:51
Сообщение #10


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



раз объекты создаются глобально, то надо удостоверится что crt код вызывает их конструкторы, иначе естественно ничего работать не будет.
Go to the top of the page
 
+Quote Post
dimanisu
сообщение Oct 28 2011, 09:56
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-10-07
Пользователь №: 31 055



Цитата
раз объекты создаются глобально, то надо удостоверится что crt код вызывает их конструкторы, иначе естественно ничего работать не будет.


Я в дебаге ставил точки останова в конструкторе - они вызываются. Прошу прощения, что за crt код? И если удостоверюсь, то как исправить?
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:56
Рейтинг@Mail.ru


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