|
Странная проблема с переменными, или как пользоваться volatile |
|
|
|
Aug 6 2008, 13:46
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Чудесным образом портится память. Стал выяснять что же не так и не пойму. Возник вопрос каксающийся volatile. Есть ли разница в следующем и какая? Код typedef struct TSTRUCT { volatile u8 *DATABuff; volatile u8 *CMDBuff; } T_STRUCT;
volatile T_STRUCT STRUCT; и вариант Код typedef struct TSTRUCT { u8 *DATABuff; u8 *CMDBuff; } T_STRUCT;
volatile T_STRUCT STRUCT; Какова будет разница? есть ли тут смысл?
|
|
|
|
|
Aug 6 2008, 14:17
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Сергей Борщ @ Aug 6 2008, 16:58)  P.S. Вообще интересная постановка вопроса: "А что же я понаписал?" Может стоить формулировать его несколько иначе: "Мне надо чтобы было так-то. Как это сделать?" При memory corruption bug'ах не до постановки "Мне надо чтобы...", потому что неизвестно что надо на самом деле.. Автор может сказать лишь - "Мне надо чтобы не глючило". Цитата есть ли тут смысл? Смысла в volatile'ях тут нет, как перед полями структуры так и перед объявлением самой структуры. Расскажите больше о характере повреждений. Чем перетирается, размер перетираемого блока, в каком участке памяти (всегда в одном участке или в разных). Попробуйте локализовать модуль ответсвенный за повреждения (отлючайте функционал вашей программы постепенно, до тех пор пока не перенестанет портиться память) Чем больше статистических данных получите, тем проще будет локализовать блок вызывающий повреждения.
|
|
|
|
|
Aug 6 2008, 14:31
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Alexey Belyaev @ Aug 6 2008, 17:25)  Почему? Точнее почему нет смыла перед объявлением самой структуры? Потому что компилятор обычно не опускает обращения к полям структур и так. Да и не видя кода где такая структура используется volatile - теряют весь смысл. У вас указатели в ней могут произвольно меняться скажем "железом" или еще каким-то странным образом? Цитата данные могут портиться при нарушении выравнивания слов. Не могут - ШД 8-ми битная. Это не ARM.
|
|
|
|
|
Aug 7 2008, 02:06
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(defunct @ Aug 6 2008, 21:31)  Потому что компилятор обычно не опускает обращения к полям структур и так. Да и не видя кода где такая структура используется volatile - теряют весь смысл. В основном структура передаётся в функции как указатель на неё. Код foo(T_STRUCT *S); И ещё делаю memcpy(). Цитата(defunct @ Aug 6 2008, 21:31)  У вас указатели в ней могут произвольно меняться скажем "железом" или еще каким-то странным образом? :\ А как "железо" может сменить указатель?  Нет.
|
|
|
|
|
Aug 7 2008, 04:21
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(SysRq @ Aug 7 2008, 09:33)  Цитата(defunct @ Aug 6 2008, 18:17)  Расскажите больше о характере повреждений
+1 А sizeof() используете? Внимательно проверьте где и как. К примеру есть переменная uint8_t *InitString; В практически самом начале программы, на неё аллочится память примерно так: Код uint8_t *InitString; .... len=strlen(TempBuffer+Offset); InitString=(uint8_t *)malloc(len); strcpy(InitString,TempBuffer+Offset); ... И всё ровно, пока не произойдёт нечто. К примеру содержимое строки было "AT+IFC=2,2\r\n" и первое и второе и даже третее обращение к ней именно это и получало, но после чего-то содержимое строки может стать "подбитым" к примеру таким "AT+I@C*2,2\r\n". И это только частный пример. Бывает что просто переменная uint8_t внутри структуры сменила своё значение. Я сейчас занимаюсь выводом в дебаг инфы при обращении к указателям, дабы исключить обращения "не туда". Но на глаз по коду тут всё ровно.
|
|
|
|
|
Aug 7 2008, 06:03
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(Непомнящий Евгений @ Aug 7 2008, 12:32)  размер кучи достаточен? Куча часом не до стека идет? Может стек переполняется? Только не кидайте гнилыми помидорами, а где это глянуть? Использую WinAVR.
|
|
|
|
|
Aug 7 2008, 06:29
|

В поисках истины
  
Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923

|
Цитата(sigmaN @ Aug 7 2008, 13:20)  Я не пользовался WinAVR, но называется это обычно heap size для кучи и stack size для стека ))
volatile действительно не имеет смысла. Просмотрите внимательно ещё раз весь код. Может быть как-то прогнать пошагово и попытаться определить где именно косяк? для инициализации внешней памяти использую рекомендацию из WinAVR: -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x807FFF т.е. 32к во внешней. Всё остальное не изменно.
|
|
|
|
|
Aug 7 2008, 07:46
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Alexey Belyaev @ Aug 7 2008, 09:29)  т.е. 32к во внешней. Всё остальное не изменно. А не может сбоить сама внешняя память? Попробуйте какой-нибудь тест написать (записать псевдослучайную последовательность и считывать ее в цикле, считая сбои), может программа и не виновата. Цитата(Alexey Belyaev @ Aug 7 2008, 05:06)  :\ А как "железо" может сменить указатель?  Может. Самый простой пример - указатель стека. Более сложный - регистры адреса источника и приемника при ПДП (DMA). Софтовые варианты - указатель изменяется в прерывании. Или еще один случай - многопоточное приложение, доступ к указателю в разных потоках. volatile перед стуктурой распространяет volatile на все члены структуры. Если ни один из этих вариантов не подходит под ваш случай, то вам не нужно делать указатели volatile - этим вы дадите больше свободы оптимизатору, код станет короче и/или быстрее.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|