Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
271 / 130 / 44
Регистрация: 05.02.2015
Сообщений: 827
1

Искажение массивов

04.06.2020, 21:56. Просмотров 522. Ответов 30
Метки нет (Все метки)

Здравствуйте. Раньше писал под пк, теперь есть проект, который нужно сопровождать на c под микроконтроллер, и в общих чертах столкнулся с проблемой искажением данных:
C
1
2
const char value_1[]={4,4,7,4,7,4,6,1,1,8}; 
const char value_2[]={0,0,2,1,0,0,2,0,0,6};
Как видите объявлены константами, нигде в коде их значение не меняю, да и не могу собственно: константы в C не меняются.
Когда я вывожу на экран первый массив, выводится все корректно.
Второй массив почему-то искажается: в первой половине массива появляется какое-то значение 32, которое я не указывал. Вообще, массив портится именно значением 32. Что это за магическое число?
Пробовал переставлять массивы местами, ситуация меняется: тот, который объявлен первым выводится без проблем, тот который вторым - искажается. Почему это может быть. Есть у кого идеи?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.06.2020, 21:56
Ответы с готовыми решениями:

Искажение формы сигнала
Есть схема. В ней используется полудуплексная передача с помощью программного UART (9600 б/с). За...

Искажение дискретных сигналов
Как влияет скорость передачи информации на степень искажений дискретных сигналов при наличии...

Искажение данных из-за пульсо мера
Всем доброго времени суток! Я использую датчик пульса и GSM модуль SIM808. два этих модуля Пульс...

Искажение аудиосигнала при ресемплинге Ланцоша
Есть представление дискретного аудио-сигнала в виде амплитудных отсчетов с частотой дискретизации...

30
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
05.06.2020, 06:03 2
Цитата Сообщение от minore Посмотреть сообщение
Почему это может быть. Есть у кого идеи?
памяти не хватает
посему главный вопрос что за камень?
Цитата Сообщение от minore Посмотреть сообщение
в общих чертах столкнулся с проблемой
здесь нет "общих черт" слишком много задействовано нюансов
второй вопрос: Что за компилятор?
ибо
Цитата Сообщение от minore Посмотреть сообщение
const char
это неизменные величина, а куда его разместить в ОЗУ или в ПЗУ решает компилятор, точнее линкер
1
271 / 130 / 44
Регистрация: 05.02.2015
Сообщений: 827
05.06.2020, 09:41  [ТС] 3
За ответ спасибо. Хорошо, что есть хоть объяснение. А то бред такой пишешь одно значение - он тебе другое подставляет.
Среда разработки Atmel Studio 7.0.
0
2573 / 1165 / 152
Регистрация: 28.10.2011
Сообщений: 4,135
Записей в блоге: 6
05.06.2020, 11:40 4
Цитата Сообщение от ValeryS Посмотреть сообщение
куда его разместить в ОЗУ или в ПЗУ решает компилятор, точнее линкер
Все же компилятор. Он раскидывает код по секциям и в зависимости от того в какую попадут данные, они будут в флеше или ОЗУ. Линкер в принципе эти вопросы решать не может, т. к. во многих МК для доступа к флешу и озу требуются разные асм инструкции.
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
05.06.2020, 12:12 5
Цитата Сообщение от minore Посмотреть сообщение
Среда разработки Atmel Studio 7.0.
а камень?
за атмел студио ничего не могу сказать, давно не работаю
но по моему раньше для размешения во флеше(тоже ПЗУ) нужно было писать ключевое слово PROGMEM
0
1779 / 1109 / 109
Регистрация: 04.01.2010
Сообщений: 3,888
05.06.2020, 17:59 6
Цитата Сообщение от minore Посмотреть сообщение
А то бред такой пишешь одно значение - он тебе другое подставляет.
покажите, как вы выводите значения?
Цитата Сообщение от ValeryS Посмотреть сообщение
за атмел студио ничего не могу сказать, давно не работаю

Не по теме:

(gcc может скопировать значения массива сама из FLASH в RAM, но учитывать что это константа).


Цитата Сообщение от ValeryS Посмотреть сообщение
вопрос что за камень?
актуальный вопрос, как и наложение участков RAM. Возможно, вы портите значения в другом коде.
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
05.06.2020, 18:28 7
Цитата Сообщение от Voland_ Посмотреть сообщение
gcc может скопировать значения массива сама из FLASH в RAM, но учитывать что это константа
в том то и дело
массив лежит в флеш но при старте переносит это в RAM
нужно чтобы всегда лежало во флешь и по коду обращалось к нему
ключевое слово PROGMEM так и позволяет сделать но я не помню к какому компилятору это относится
0
1779 / 1109 / 109
Регистрация: 04.01.2010
Сообщений: 3,888
05.06.2020, 20:33 8
Цитата Сообщение от ValeryS Посмотреть сообщение
к какому компилятору это относится
к avr gcc и относится... Все верно говоришь. И гарантировать, что данные не поменяются таким образом, тоже можно
1
271 / 130 / 44
Регистрация: 05.02.2015
Сообщений: 827
06.06.2020, 12:20  [ТС] 9
ValeryS, мне больше всего понравилась версия про нехватку памяти. Хотелось бы как-то убедится или опровергнуть эту версию, так как если памяти действительно не хватает или она в притык, то в принципе код нужно будет переписывать, чтобы не было сюрпризов в других местах. По сему вопрос: Как можно ррасчитать , сколько памяти задействовано при работе моей программы? Можно ли как то вручную это сделать, даже если это муторно?
Всего доступно 4 кб оперативной памяти.
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
06.06.2020, 12:58 10
minore, при компиляции программы пишется все ресурсы flech eeprom ram
но у каждого компилятора это по своему
еще раз повторю: Atmel Studio я не знаю
1
1779 / 1109 / 109
Регистрация: 04.01.2010
Сообщений: 3,888
07.06.2020, 19:44 11
Цитата Сообщение от minore Посмотреть сообщение
Как можно ррасчитать , сколько памяти задействовано при работе моей программы?
в gcc есть тула, которая выводит количество откушенных ресурсов. Называется gcc-size... Но насколько я знаю, она не считает количество занятых данных на стеке, и вложенность функций. Соответственно, для этой задачи чаще всего используют т.н. "stack analizer". именно эта тула помогает оценить, теоретическую "вершину стека". На практике же иногда полезно просто сделать дамп памяти и посмотреть сколько памяти использовалось. Обычно, если она использовалась - ее контент не нулевой, и таким образом, можно понять что было использовано, а что нет.
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
07.06.2020, 19:49 12
minore, хочешь покажу как можно испортить второй массив
C
1
2
for(int i=0;i<sizeof(value_1)+20;i++)
  value_1[i]=i;
и все, 20 элементов 2 массива испорчены
0
1779 / 1109 / 109
Регистрация: 04.01.2010
Сообщений: 3,888
09.06.2020, 09:29 13
Цитата Сообщение от ValeryS Посмотреть сообщение
и все, 20 элементов 2 массива испорчены
(в этом случае - очень вероятно, но не всегда так. потому что во-первых, gcc может взять стратегию размещения переменных в памяти "задом наперед", во-вторых, он их перемешивает, достигая наибольшей оптимальности как в размере так и скорости доступа).
Это я к тому, что результат может быть не таким как ожидается ). Для этого есть более надежные способы...
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
09.06.2020, 09:52 14
Цитата Сообщение от Voland_ Посмотреть сообщение
Для этого есть более надежные способы...
для UB!?
ну ты, барин, и даешь
0
1779 / 1109 / 109
Регистрация: 04.01.2010
Сообщений: 3,888
09.06.2020, 13:13 15
Цитата Сообщение от ValeryS Посмотреть сообщение
для UB!?
what's that?
0
Модератор
8199 / 6070 / 810
Регистрация: 14.02.2011
Сообщений: 21,057
09.06.2020, 14:02 16
UB - undefined behavior (Неопределенное поведение)
выход за пределы массива чистое UB
https://habr.com/ru/post/216189/
и тут такое заявление
Цитата Сообщение от Voland_ Посмотреть сообщение
Для этого есть более надежные способы...
надежные для UB
1
2573 / 1165 / 152
Регистрация: 28.10.2011
Сообщений: 4,135
Записей в блоге: 6
09.06.2020, 20:05 17
Цитата Сообщение от ValeryS Посмотреть сообщение
выход за пределы массива чистое UB
Я думаю что дело в другом. ТС дал подсказку.
Цитата Сообщение от minore Посмотреть сообщение
Вообще, массив портится именно значением 32. Что это за магическое число?
Он похоже использует sprintf или что-то подобное и записывая больше чем размер массива, пробелами затирает данные в другом массиве.
0
271 / 130 / 44
Регистрация: 05.02.2015
Сообщений: 827
09.06.2020, 20:14  [ТС] 18
Контроллер: риалабовский MC12D8O .
Проверил занятую память: память программ 28% память данных 67%.
Отказался от массивов, переписал логику без них. Стала затираться переменная, которая была выше массивов. И тоже либо значением 0 либо 32.
Ушел от проблемы следующим образом: из Main все объявления переменных перенес в глобальную область. Все заработало, ничего не затирается.
Объясните, почему в локальной и глобальной области работает по-разному. Человек, который до меня вел проект ппредложил смотреть Map проекта, сопоставлять адреса переменных, потому что одна может затирать другую. Почему это может быть? Как одна переменная может затереть другую?
Простите за нубские вопросы, но очень хочу разобраться, если есть , что почитать на эту тему - буду благодарен. Но то, что если я из локальной области перенес в глобальную и все заработало говорит о том, что ошибка точно не в алгоритме/ коде.

Добавлено через 6 минут
"""Он похоже использует sprintf """ в точку. Но только для отладки, когда уже все сломалось. А 32 - это код пробела?
0
Эксперт .NET
6860 / 4464 / 1072
Регистрация: 25.05.2015
Сообщений: 13,644
Записей в блоге: 13
09.06.2020, 20:20 19
Цитата Сообщение от minore Посмотреть сообщение
ValeryS, мне больше всего понравилась версия про нехватку памяти. Хотелось бы как-то убедится или опровергнуть эту версию, так как если памяти действительно не хватает или она в притык, то в принципе код нужно будет переписывать, чтобы не было сюрпризов в других местах. По сему вопрос: Как можно ррасчитать , сколько памяти задействовано при работе моей программы? Можно ли как то вручную это сделать, даже если это муторно?
Всего доступно 4 кб оперативной памяти.
Это не рассчитывают.
Заполняют всю ОЗУ паттерном, через линкер скрипт или программно.
Запускают программу.
Смотрят, какие области озу были перезаписаны в ходе её работы.
Обычная проблема - стек задачи слишком мал и при помещении в него данных они вылезли за пределы выделенной стеку области, да затёрли то, что лежало ниже (глобальные переменные).

Добавлено через 2 минуты
Чуть более продвинуто - прямо в ходе работы программы она проверяет, что нижняя граница стека имеет заданный паттерн и не была затёрта. Если таки была - падаем и вопим о вопиющей ошибке дизайна.
0
271 / 130 / 44
Регистрация: 05.02.2015
Сообщений: 827
09.06.2020, 20:24  [ТС] 20
Rius , Ровно наоборот. Когда я описание переменных из main убрал в глобальную область - все заработало. Затиралось то, что в main. загадка, но факт.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.06.2020, 20:24

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Что вызывает искажение нижних и верхних пиков сигнала?
Что вызывает искажение нижних и верхних пиков сигнала?

Искажение изображения
Всем привет! Как сделать искажение изображения, подобное тому, как на приложенной картинке?

Искажение изображения
Имеется изображение белого светлых оттенков которое добавлено на задний план формы....

Искажение цветов
В чем причина такого искажения? +Еще на голубом появляются искажения розового оттенка Как можно...

Искажение экрана
Всем привет. Только что возникла проблема на экране. Идет какое-то искожение букв, картинок(Всего)...

Искажение картинки
Всем привет, я оттуда https://www.cyberforum.ru/win-api/thread1225579.html начинаю работать с...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.