|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
28.08.2021, 18:27 | #1 |
Участник клуба
Регистрация: 30.04.2007
Сообщений: 1,307
|
Если буфер = 0, то почему работает? (Си, AVR)
Доброго времени суток.
Собственно, не знаю есть ли разница обычной программы на Си и прошивки для микроконтроллера, сути ведь не меняет, что читает программу. Случайно допустил ошибку, но почему всё работает не пойму. У кого какие мысли, вот код: (Среда AtmelStudio 6) // Заголовки, подключение библиотек и всё такое .... Код:
В теле этой процедуры, запись в буфер происходит в основном так: Код:
И так, если мы хотим прочитать 128 байт с чипа, то в переменную countByte заносим число 128. Вызываем процедуру чтения и она спокойно нам возвращает в массив 128 байт информации. Это нормально. Процесс записи в чип особо не изменяется. Код:
Код:
Приняли байты, записали. Отправили команду контроллеру, считали байты, отправили дальше. И это нормально. А вот что не нормально! Мне нужно было проверить объём ОЗУ занимаемый не буфером, а всякими переменными, по этому я константу SIZE сделал равной нулю. Код:
Однако, вернуть на родину константу я забыл и залил прошивку в микроконтроллер. И к моему удивлению, никаких багов не было! Читал блоки по 4096 байт (кусками по 256 в потоке). Вопрос к тем, кто знает или сталкивался с подобным, почему????? Почему программа работала?
Всё гениальное - просто!
|
28.08.2021, 19:03 | #2 |
МегаМодератор
СуперМодератор
Регистрация: 09.11.2010
Сообщений: 7,289
|
Потому что проверок выхода за границы массива нет. Повезло, что при переполнении не затирали какие-то важные данные, вот программа и работала.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
|
28.08.2021, 20:53 | #3 | |
Участник клуба
Регистрация: 21.11.2007
Сообщений: 1,063
|
По чему бы и не работать?
Не верно. При объявлении: Код:
Если объявить: Код:
И то что чтение данных выполняется, это нормально. Просто чем меньше буфер тем чаще он будет обновляться. P. S. #define SIZE 256 — не константа, макроопределение. Цитата:
I am not a wizard, I am just learning.
Последний раз редактировалось Desc; 28.08.2021 в 21:49. Причина: Добавил P. S. |
|
28.08.2021, 22:41 | #4 | ||||
Участник клуба
Регистрация: 30.04.2007
Сообщений: 1,307
|
С этим да, могу согласиться, просто досконально в терминологии Си ещё не силён.
А вот с этим чёт ни чего не пойму))) Цитата:
uint8_t это и есть 8 бит, т.е. 1 байт. Если написать Код:
Если написать Код:
Если написать Код:
Но уже на 256 больше. Согласно арифметике 8 бит * 256 = 2048 бит, это те же самые 256 байт. Т.е. откуда взялись 2056 не пойму. Если написать размер ноль... он и в африке будет ноль. Потому что это размер, а не адрес в памяти. Согласно отчёту компилятора (смотрим скрин) при SIZE = 0 занятая память 584 байта. при SIZE = 1 занятая память 585 байт. при SIZE = 256 занятая память 840 байт. Теперь снова арифметика. 840 - 256 = 584 Это вполне очевидно доказывает, что Цитата:
Цитата:
Если бы получилось 2048 байт, я бы так радовался Но совершенно логично, если установить SIZE 2048 то в сообщении компилятора получаю Код:
Цитата:
Всё гениальное - просто!
Последний раз редактировалось Air; 28.08.2021 в 22:49. Причина: Дополнение |
||||
28.08.2021, 22:57 | #5 |
Участник клуба
Регистрация: 21.11.2007
Сообщений: 1,063
|
Код:
array buff2 {0, 1} Так понятней? P. S. Вы оптимизацию кода установите равную "0" (none). И посмотрите сколько будет предупреждений, если конечно они не отключены у Вас.
I am not a wizard, I am just learning.
Последний раз редактировалось Desc; 28.08.2021 в 23:08. Причина: Добавил P. S. |
28.08.2021, 23:13 | #6 | |
Участник клуба
Регистрация: 30.04.2007
Сообщений: 1,307
|
Цитата:
Если объявить uint8_t buff1[0]; То в коде ниже мы не можем обратиться к нулевому элементу массива. buff1[0] = 128; По причине того, что для него не выделена память. Например в высокоуровневых языках (С#, Delphi) такое действие приведёт к ошибке обращения к памяти. Типа Access violation .... В МК можно таким образом запортачить рабочие данные, если писать куда попало. Другими словами ваша запись array buff1 {0} неверна. Как и array buff2 {0, 1} неверна, потому что вы не выделили память под второй элемент массива. Позвольте узнать, это в каком языке такое вообще допустимо? (Кроме серверных скриптов PHP) P.S. Отключил. Предупреждения от системного модуля delay.... И то к делу не имеет отношения
Всё гениальное - просто!
Последний раз редактировалось Air; 28.08.2021 в 23:17. |
|
29.08.2021, 01:53 | #7 | ||
Участник клуба
Регистрация: 21.11.2007
Сообщений: 1,063
|
Цитата:
О регистрах речь не веду. Цитата:
Попробую иначе. Посмотрите что выведет код ниже в обычном консольном приложении. Код:
И получим Output: 0 0 // или будет мусор из ОЗУ 32767 65535 0 P. S. Код:
Код:
P. P. S. Что касается чтения из SpiFlash. Урезав буфер Вы ведь не перекрыли доступ к страницам. Плюс оптимизатор по объявлению uint8_t buff за Вас определил пространство. Вот и чтение происходит без проблем. Отключать предупреждения плохая идея. Не заметите просчеты. И конечный продукт даст сбой в самый не подходящий момент.
I am not a wizard, I am just learning.
Последний раз редактировалось Desc; 29.08.2021 в 02:32. Причина: Добавил P. S. + P. P. S. |
||
29.08.2021, 08:08 | #8 |
фрилансер
Форумчанин
Регистрация: 11.10.2019
Сообщений: 960
|
uint8_t buff[256]; - зарезервируется 256 байтов
uint8_t buff[1]; - зарезервируется 1 байт uint8_t buff[0]; - ничего не зарезервируется. "Работать" с таким "массивом" нельзя, это неопределённое поведение |
29.08.2021, 12:24 | #9 |
Участник клуба
Регистрация: 30.04.2007
Сообщений: 1,307
|
Алексей1153 Это я понимаю)
Так как места под массив не зарезервировано и не дай бог, в этот момент произойдёт прерывание, приоритетом выше текущего, в это место может записаться другая информация. Код:
Я вот что подумал. Мы говорим о разных видах памяти. Есть Flash, статическая, программируется во время прошивки МК. Есть RAM, привычнее ОЗУ. Память которая используется для вычислительных процессов, которая постоянно перезаписывается программой МК. Те. 8 бит, от типа данных uint8_t, о которых вы говорите, как раз таки пишутся во Flash (на первых скринах это видно) Логично, если объявить переменную uint32_t то займёт 32 бита. Но во Flash памяти, а не RAM. Суть моих манипуляций с макросом SIZE в том, что бы увидеть расход именно RAM (озу) памяти. Потому что её очень мало и нужно за частую прибегать к оптимизации, более рационально использовать массивы. А то, что сама переменная занимает место в статической памяти... Да и бог с ней =) Занимает она 8 бит или 32, не объясняет, почему программа работала стабильно. Суть данного поста не в том, что бы посчитать кто сколько чего занимает, а причины, почему данные передавались, почему на дисплее не было "мусора".
Всё гениальное - просто!
|
29.08.2021, 12:31 | #10 |
Участник клуба
Регистрация: 30.04.2007
Сообщений: 1,307
|
BDA
Хм, возможно потому что UART прерывание единственное во всём цикле работы. Отрисовку на дисплей я делал в основном потоке. Который даже не выполнятся, пока не разрешишь.
Всё гениальное - просто!
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Здравствуйте ! в чем проблема,почему почему время исполнения операций не работает ? | ion leahu | Помощь студентам | 6 | 23.11.2014 19:36 |
AVR. Почему одно прерывание блокирует другое? | Admin2 | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 1 | 27.07.2013 22:30 |
Формула ЕСЛИ не работает. Почему? | cutie_girl | Microsoft Office Excel | 3 | 25.10.2012 23:18 |
Скрипт не работает, если линкую локально, а работает если линкую на .. | keen_ | JavaScript, Ajax | 3 | 08.03.2012 07:58 |
AVR ATmega 128: почему не происходит переход? | Blondy | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 4 | 06.05.2011 01:28 |