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

 
 
> Пересечение адресов переменных
Wano
сообщение Jan 3 2009, 20:12
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Обнаружил странную проблемку. В прожке есть глобальный массив char[2000]. При вызове функций записи в файл командами FatFS, все переменные в функциях своими адресами влазать в массив. Менял размер массива - никакого толку не даёт. Все локальные переменные в функциях именно FatFS своими адресами пересакают конец массива, отсюда значения в массиве заолняются мусором. Прога в uVision, проц LPC2478. Может кто такое наблюдал? Как вариант думал всё стереть и начать заново, но если есть проблема,как бы не вылезла в другом месте. Число портящихся байт ~300.
Спасибо.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 14)
sergeeff
сообщение Jan 3 2009, 21:01
Сообщение #2


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

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



Недостаточно выделено места под стек. Попробуй выделить под стек еще 512 байт и посмотреть.
Go to the top of the page
 
+Quote Post
rimpocha
сообщение Jan 3 2009, 21:56
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 6-03-07
Из: Новосибирск, Seattle
Пользователь №: 25 935



Это точно стек переполняется.

Попробуйте оптимизировать использование стека с помощью динамического выделения памяти под локальные переменные из кучи (malloc) или уменьшив глубину вложенности функций. Ну или увеличте стек smile.gif
Обращайте внимание сколько отжирают от стека библиотечные функции.


--------------------
НГТУ, Физико-технический факультет, кафедра Лазерных систем
Go to the top of the page
 
+Quote Post
Wano
сообщение Jan 5 2009, 14:46
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Кароче проблема решается объявлением переменной файла как глобальной. Подобно FatFS либа EFSL также не пашет с локальными файловыми переменными.
Может что-то делаю не так, но если создавать в своей функции записи локальную переменную типа FIL, то при вызове любых функций FatFS происходит пересечение адресов. Странно но факт.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 5 2009, 15:37
Сообщение #5


Гуру
******

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



Цитата(Wano @ Jan 5 2009, 16:46) *
Подобно FatFS либа EFSL также не пашет с локальными файловыми переменными.
Вот так всегда: в первую очередь "либа кривая". Почему-то у остальных "пашет", у вас нет, и виновата, конечно же, либа.
Цитата(Wano @ Jan 5 2009, 16:46) *
Может что-то делаю не так
100%. Если вы объявляете переменную глобально, память под нее выделяется на этапе линковки. Если локально - она размещается на стеке. Если стека не хватает - естественно, будут затираться какие-то другие данные, на которые наползет стек. Переменная типа FIL кроме 40 байтов данных содержит еще и буфер на 512 байт. Итого 542 байта. А сколько стека у вас выделено всего?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
rimpocha
сообщение Jan 5 2009, 15:41
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 6-03-07
Из: Новосибирск, Seattle
Пользователь №: 25 935



Цитата(Wano @ Jan 5 2009, 20:46) *
Кароче проблема решается объявлением переменной файла как глобальной. Подобно FatFS либа EFSL также не пашет с локальными файловыми переменными.
Может что-то делаю не так, но если создавать в своей функции записи локальную переменную типа FIL, то при вызове любых функций FatFS происходит пересечение адресов. Странно но факт.


Ничего странного! Говорят же вам, все локальные переменные помещаются в стек, а он не резиновый.
Изучите подробно, как устроены функции в Си, как осуществляется вызов функции, где выделяется память под переменные, что такое стек и куча. Иначе в будущем будет еще больше проблем возникать.


--------------------
НГТУ, Физико-технический факультет, кафедра Лазерных систем
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jan 5 2009, 16:07
Сообщение #7


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

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



Ну еще не ясно, товарищ откравает файл - пишет/читает - закрывает в одной своей функции или в разных?
Go to the top of the page
 
+Quote Post
Wano
сообщение Jan 6 2009, 13:13
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Цитата(sergeeff @ Jan 5 2009, 18:07) *
Ну еще не ясно, товарищ откравает файл - пишет/читает - закрывает в одной своей функции или в разных?

Да всё в одной функции. Открыл, сотню байт кинул и закрыл.

Хороший вопрос по поводу стэка и его размера, особенно где его глянуть в данном случае. Что мешает использовать под него всё ОЗУ? Ясно ,конечно, если вы динамически выделяете место под свои переменные,имея заранее какой-то массив. А если такого нет?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 6 2009, 14:22
Сообщение #9


Гуру
******

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



Цитата(Wano @ Jan 6 2009, 15:13) *
Хороший вопрос по поводу стэка и его размера, особенно где его глянуть в данном случае.
Для Кейла не знаю, но искать надо где-то в районе опций линкера и/или его скрипта.
Цитата(Wano @ Jan 6 2009, 15:13) *
Что мешает использовать под него всё ОЗУ?
Тот факт, что у ARM 6 стеков, по одному для каждого из режимов: FIQ, IRQ, Supervisor, User/System, Abort, Undefined


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Wano
сообщение Jan 6 2009, 15:09
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



Цитата(Сергей Борщ @ Jan 6 2009, 16:22) *
Тот факт, что у ARM 6 стеков, по одному для каждого из режимов: FIQ, IRQ, Supervisor, User/System, Abort, Undefined


А где можно глянуть такие сведения?
Фишка заключается в том, что вызов функций именно с большим объёмом(>500Б) локальных переменных вызывает проблемы. Ладно бы ОЗУ не хватало для всех, так места 98кБ хватит и на прогу и на её переменные два раза.
Настройки все смотрел, очевидного окошка в кейле не наблюдаю для ввода размера стэка.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 6 2009, 15:38
Сообщение #11


Гуру
******

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



Цитата(Wano @ Jan 6 2009, 17:09) *
А где можно глянуть такие сведения?
О чем? О количестве стеков и режимах работы? В User manual на LPC кратенько, если недостаточно - Google-> "ARM7TDMI manual". О настройке стеков в кейле? В документации на кейл. Или медитируя над параметрами, с которыми запускается линкер и его скриптом (кажется, у кейла он называется scratch-файл).


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Jan 6 2009, 16:55
Сообщение #12


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

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



А разве не в startup'e задается размер стеков?
Go to the top of the page
 
+Quote Post
Wano
сообщение Jan 6 2009, 18:00
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 272
Регистрация: 3-06-06
Пользователь №: 17 737



beer.gif smile.gif))) ннда приплыл. Больше глупых постов делать не буду. Всем спасибо.
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Jan 6 2009, 20:24
Сообщение #14


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(sergeeff @ Jan 6 2009, 18:55) *
А разве не в startup'e задается размер стеков?
Нет. В параметрах, передаваемых линкеру.
В startup'e инициализация стеков и режимов.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 6 2009, 21:19
Сообщение #15


кекс
******

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



Цитата(HARMHARM @ Jan 6 2009, 22:24) *
Нет. В параметрах, передаваемых линкеру.
В startup'e инициализация стеков и режимов.

линкер вообще-то здесь не при делах.
Размеры стеков в Keil "по-умолчанию" задаются в стартапе.
Никто также не мешает определить массивы стеков в .c файле.

Цитата
кажется, у кейла он называется scratch-файл

scatter файл, в нем задаются секции памяти.
тем не менее никто не мешает разместить стек просто как массив в ROOT-RW, всмысле не создавать отдельных секций под стек линкером (что в Keil и делается).
Go to the top of the page
 
+Quote Post

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

 


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


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