Нескольно простых вопросов о программировании AVR на Си.
Re: Нескольно простых вопросов о программировании AVR на Си.
Продвинутые микроконтроллеры имеют аппаратные ловушки (флаги ошибок) при таких операциях. На чистом Си без предварительных проверок такое невозможно, компилятор не отслеживает математику переменных. Если 0 - константа, то предупреждение выдаст. Иначе - нет.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
MLX90640, ну тема про AVR-ный Си.
На АВРках нет аппаратных ловушек.
Просто столкнулась, что надо немного математики покрутить с широким диапазоном параметров..... Придется руками проверять всё.....
Эхххх.. где мои любимые begin.... exception when ... then .... end;
На АВРках нет аппаратных ловушек.
Просто столкнулась, что надо немного математики покрутить с широким диапазоном параметров..... Придется руками проверять всё.....
Эхххх.. где мои любимые begin.... exception when ... then .... end;
Белая и Пушистая
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Количество кода, нужного на проверку делителя на ноль - ничуть не больше, чем добавить те же try/catch, если бы они и были. Но с точки зрения ресурсов, обходится гораздо дешевле.
Код: Выделить всё
x = (a+b+c)/(d+e);
# vs
div=d+e;
x = div ? (a+b+c)/div : 0;
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
WiseLord, деление на ноль - фиг с ним.
У меня будет квадратный корень, тригонометрия, включая тангенс и, возможно, будет еще экспонента, но тут еще не знаю.
И не хотелось бы проверять отдельно отрицательное для корня, +/-90° для тангенса, что б аргумент экспоненты был меньше 88.5 и т.д.
математика будет в одном блоке и хотелось получить либо результат, либо ошибку. Где она возникла - будет не особо важно....
У меня будет квадратный корень, тригонометрия, включая тангенс и, возможно, будет еще экспонента, но тут еще не знаю.
И не хотелось бы проверять отдельно отрицательное для корня, +/-90° для тангенса, что б аргумент экспоненты был меньше 88.5 и т.д.
математика будет в одном блоке и хотелось получить либо результат, либо ошибку. Где она возникла - будет не особо важно....
Белая и Пушистая
- Roman Solovey
- Прорезались зубы
- Сообщения: 232
- Зарегистрирован: Вт фев 05, 2019 17:20:08
- Откуда: Днепр, Украина
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
подскажите как можно узнать длину массива хранящегося в progmem? У меня есть массив указателей(тоже в progmem) который хранит в себе указатели на массивы, но они разной длины, и вот их нужно передать в функцию вывода, но так же нужно знать размер.. И это не строка, по нуль символу парсить не получится(
костыль я уже придумал. в нулевом элементе каждого массива хранить его размер. но может есть что по изящнее?\
костыль я уже придумал. в нулевом элементе каждого массива хранить его размер. но может есть что по изящнее?\
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
в си нельзя в общем случае по указателю определить размер области, на которую он указывает.
ваш костыль - не костыль, в вполне обычная практика.
ваш костыль - не костыль, в вполне обычная практика.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
ARV, там же массивы прибиты гвоздями в progmem и скорее всего не меняются в run-time. Это ж не выделение памяти в куче.
Roman Solovey, нууу... У вас массив массивов. С учетом того, что они в прогмеме - они, скорее всего, не меняются (вариант, когда вы из программы перешиваете память МК - не рассматриваем).
Есть смысл тогда размеры этих массивов задефайнить через sizeof на этапе написания программы.
И использовать эти дефайны в программе...
Ну или покажите код, как вы определяете эти массивы и расскажите, для чего нужен их размер?
Roman Solovey, нууу... У вас массив массивов. С учетом того, что они в прогмеме - они, скорее всего, не меняются (вариант, когда вы из программы перешиваете память МК - не рассматриваем).
Есть смысл тогда размеры этих массивов задефайнить через sizeof на этапе написания программы.
Код: Выделить всё
const int arr1[50] PROGMEM = {1,2,3....};
const int arr2[25] PROGMEM = {1,2,3....};
const int arr3[666] PROGMEM = {1,2,3....};
const int arr4[1984] PROGMEM = {1,2,3....};
#define ARR1_SIZE sizeof(arr1)
#define ARR2_SIZE sizeof(arr2)
#define ARR3_SIZE sizeof(arr3)
#define ARR4_SIZE sizeof(arr4)И использовать эти дефайны в программе...
Ну или покажите код, как вы определяете эти массивы и расскажите, для чего нужен их размер?
Белая и Пушистая
- Roman Solovey
- Прорезались зубы
- Сообщения: 232
- Зарегистрирован: Вт фев 05, 2019 17:20:08
- Откуда: Днепр, Украина
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
спасибо за подсказки)
с дефайнами морочнее будет. мне шрифт нужно к дисплею прикрутить, а это много символов)
с дефайнами морочнее будет. мне шрифт нужно к дисплею прикрутить, а это много символов)
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
Roman Solovey, если размер каждого символа одинаков - то множить код символа на размер. Если ширина разная - то оптимально в первом байте символа держать размер этого символа. Так все делают.
Плюс дополнительно, если отвести еще один байт на код символа - можно собирать в шрифт только нужные символы.
Плюс дополнительно, если отвести еще один байт на код символа - можно собирать в шрифт только нужные символы.
Белая и Пушистая
- Roman Solovey
- Прорезались зубы
- Сообщения: 232
- Зарегистрирован: Вт фев 05, 2019 17:20:08
- Откуда: Днепр, Украина
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
Плюс дополнительно, если отвести еще один байт на код символа - можно собирать в шрифт только нужные символы.
Немного не понял. это типа в программе которая генерит шрифты нужно выделить?
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
Roman Solovey, есть 2 подхода.
1. в шрифте сохранены все символы, цифры , англицкий алфавит, кириллический алфавит. Это порядка 160 символов.
И все эти символы хранятся в прогмем и занимают место.
А нам надо написать "ПРИВЕТ!" - из 160 символов нужно всего 7. И 153 символа просто занимают память.
2. В шрифте сохранены только нужные символы. Цена этого - + 1 байт к каждому символу - в этом бате хранится код.
И для надписи "ПРИВЕТ!" достаточно сохранить 7 символов всего.
но если вдруг придется написать, "ПРИВЕТ, ВАСЯ!" - то нужно будет выгружать заново не 7, а 12 символов.
1. в шрифте сохранены все символы, цифры , англицкий алфавит, кириллический алфавит. Это порядка 160 символов.
И все эти символы хранятся в прогмем и занимают место.
А нам надо написать "ПРИВЕТ!" - из 160 символов нужно всего 7. И 153 символа просто занимают память.
2. В шрифте сохранены только нужные символы. Цена этого - + 1 байт к каждому символу - в этом бате хранится код.
И для надписи "ПРИВЕТ!" достаточно сохранить 7 символов всего.
но если вдруг придется написать, "ПРИВЕТ, ВАСЯ!" - то нужно будет выгружать заново не 7, а 12 символов.
Белая и Пушистая
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
ARV, там же массивы прибиты гвоздями в progmem и скорее всего не меняются в run-time. Это ж не выделение памяти в куче.
ну и что? в массиве указатели на массивы, а какой размер того массива, на что показывает указатель - узнать нельзя. тот факт, что на самом деле размеры известны программисту, не делает их доступными программно.Есть смысл тогда размеры этих массивов задефайнить через sizeof на этапе написания программы.
что и требовалось доказатьДобавлено after 4 minutes 38 seconds:
шрифты делаются примерно так:
Код: Выделить всё
typedef struct {
uint8_t width;
uint8_t height;
uint8_t bytes[]; // массив неизвестного размера всегда последний
}symbol_t;по полям width и height вычисляется количество элементов массива bytes.
затем вы делаете массивы символов, заносите указатели в массив "алфавита" и т.д.
для пущей экономии можно сделать "алфавит" не полным, но тогда при выводе символа надо предусмотреть проверку вхождения символа в алфавит.
Добавлено after 7 minutes 56 seconds:
кстати, для более-менее свежих версий компилятора avr-gcc крайне рекомендую использовать префикс __flash для описания констант, размещаемых в памти программ, т.е. отказаться от PROGMEM, а заодно и от функций pgm_read_xxx. я об этом неоднократно писал уже - код становится более переносимым, лучше читается и в целом работать проще.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- KorbenDallas
- Встал на лапы
- Сообщения: 93
- Зарегистрирован: Пн окт 31, 2016 06:23:19
Re: Нескольно простых вопросов о программировании AVR на Си.
А кто подскажет, в голом Си (на МК) реально отловить деление на ноль, не проверяя делитель перед делением?
try... catch вроде ж только для плюсов....
try... catch вроде ж только для плюсов....
try/catch в С++ не отлавливает деление на ноль и вообще не имеет никакого отношения к этому.
отловить деление на ноль, не проверяя делитель перед делением?
Никак. Ни в С, ни в С++.
Последний раз редактировалось KorbenDallas Сб окт 08, 2022 23:17:36, всего редактировалось 1 раз.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
- Вась, а Вась, чем С++ от С отличается?
- 1
- ну правда, Вась?

- 1
- ну правда, Вась?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Нескольно простых вопросов о программировании AVR на Си.
ARV, не 1, а True 
Re: Нескольно простых вопросов о программировании AVR на Си.
Roman Solovey, для шрифтов массив данных символа делается либо одинакового для всех символов размера, либо размер массива данных каждого символа косвенно хранится в таблице описаний символов. Некоторые утилиты создания шрифтов (например Dot Factory) умеют создавать такие таблицы.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Нескольно простых вопросов о программировании AVR на Си.
Roman Solovey, я тоже применяю дефайн, но немного иначе
1) допустим, есть функция, работающая с массивом F(Arr), внутри которой надо знать его размер...
2) создаю для функции обёртку вида: #define _F(Arr) F(Arr, sizeof(Arr))
3) в дальнейшем вызываю её... (внутрь функции размер приходит 2м аргументом)
ПС) недостаток метода - для массивов из элементов инт надо размер делить на 2: #define _F(Arr) F(Arr, sizeof(Arr)/2)
Добавлено after 5 minutes 44 seconds:
Пример:
размер вычисляется во время компиляции и в прошивку попадает только готовое к употреблению число
(-1 я вынес из функции, так оказалось немного удобнее и немного уменьшило прошивку в моем случае)
ПС: посмотрел по сторонам и нашел, как от этого недостатка избавиться:
sizeof(Array)/sizeof(Array[0]);
или
sizeof(Array)/sizeof(*Array);
дадут именно количество элементов массива, а не его размер в байтах
Добавлено after 17 minutes 7 seconds:
Just_Fluffy, в чем разница между sizeof(arr1) и #define ARR1_SIZE ? и то и то дефайн... (только один системный, а второй пользовательский, причем ни какими преимуществами не обладающий...)
Добавлено after 52 minutes 49 seconds:
Оно не будет работать с динамическими массивами, но тут про них речь и не идёт
1) допустим, есть функция, работающая с массивом F(Arr), внутри которой надо знать его размер...
2) создаю для функции обёртку вида: #define _F(Arr) F(Arr, sizeof(Arr))
3) в дальнейшем вызываю её... (внутрь функции размер приходит 2м аргументом)
ПС) недостаток метода - для массивов из элементов инт надо размер делить на 2: #define _F(Arr) F(Arr, sizeof(Arr)/2)
Добавлено after 5 minutes 44 seconds:
Пример:
Код: Выделить всё
/*поиск в int[] */#define findint(_Arr,_value) (searchInArrayInt (_Arr, (sizeof(_Arr)/2)-1, _value))
/*поиск в char[]*/#define findchar(_Arr,_value) (searchInArrayChar (_Arr, (sizeof(_Arr)-1), _value))(-1 я вынес из функции, так оказалось немного удобнее и немного уменьшило прошивку в моем случае)
ПС: посмотрел по сторонам и нашел, как от этого недостатка избавиться:
sizeof(Array)/sizeof(Array[0]);
или
sizeof(Array)/sizeof(*Array);
дадут именно количество элементов массива, а не его размер в байтах
Добавлено after 17 minutes 7 seconds:
Just_Fluffy, в чем разница между sizeof(arr1) и #define ARR1_SIZE ? и то и то дефайн... (только один системный, а второй пользовательский, причем ни какими преимуществами не обладающий...)
Добавлено after 52 minutes 49 seconds:
Оно не будет работать с динамическими массивами, но тут про них речь и не идёт
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Just_Fluffy
- Вымогатель припоя
- Сообщения: 532
- Зарегистрирован: Ср июн 29, 2022 16:25:45
Re: Нескольно простых вопросов о программировании AVR на Си.
Ivanoff-iv, так никакой разницы и нет. Только я предлагала просто держать рядом с массивами дефайны их размеров через sizeof, а вы предпочли инкапсулировать размер в вызов функции....
Вроде и красивее, но иногда проще обращаться к элементу массива напрямую, а не через функцию.
Но суть одна - инструментов определить размер массива нету. Для динамических надо самому помнить, сколько мы отгрызли памяти под массив. Для статических - в design-time где то сохранять размер. Через тот же sizeof, к примеру. И это нормальная практика.
Вроде и красивее, но иногда проще обращаться к элементу массива напрямую, а не через функцию.
Но суть одна - инструментов определить размер массива нету. Для динамических надо самому помнить, сколько мы отгрызли памяти под массив. Для статических - в design-time где то сохранять размер. Через тот же sizeof, к примеру. И это нормальная практика.
Белая и Пушистая
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Нескольно простых вопросов о программировании AVR на Си.
так sizeof и дефайн на него ничего не хранят (по крайней мере там, где написаны), а лишь указывают на константу в памяти компилятора и говорить о том, что одна лежит к массиву ближе другой...
по мне так sizeof применять удобнее, т.к. она имеет параметр, через который её вызов можно автоматизировать... свою подменку тоже можно автоматизировать, но это сложнее
Добавлено after 8 minutes 38 seconds:
Можно всю функцию написать в виде дефайна (т.е. по сути просто много раз продублировав код), каюсь я и так делал
, оптимизатор, кстати, такой код ооочень хорошо ужимает
оверхеда практически не остается... (иногда прошивка даже компактнее получается...
)
а можно (как я привел в примере) просто получить размер заранее и как параметр передать функции.
Добавлено after 7 minutes 52 seconds:
ПС: наличие функции не мешает обращаться напрямую... просто вне функции работают и sizeof и дефайн на него (а значит дефайн безполезен), а внутри функции если sizeof просто перестает работать, то дефайн продолжает отображать то, на что его направили.... это полностью убивает универсальность функции (зачем мне размер ARR1 если я работаю с ARR2 ? )
Добавлено after 27 minutes 29 seconds:
это просто небольшая часть возможностей дефайна по облегчению написания кода, я даже имени ни одного из массивов не упомянул - всё подставляется и считается автоматически!
А дефайн без параметра или хотя-бы математической операции (чтобы что-то при сборке посчитать), без пользователького значения внутри (которому этот дефайн придает имя) ИМХО штука совсем безполезная... даже код понятнее такой дефайн не делает...
зачем он?
у меня sizeof() всегда рядом с массивом лежит (хоть и только в мыслях)....
Добавлено after 7 minutes 1 second:
ПС вот так смысл появится:так в дефайне будет именно количество элементов массива, а не занимаемый им размер памяти.
А вот так ещё интересней: так этот дефайн к любому (статическому) массиву применить можно
по мне так sizeof применять удобнее, т.к. она имеет параметр, через который её вызов можно автоматизировать... свою подменку тоже можно автоматизировать, но это сложнее
Добавлено after 8 minutes 38 seconds:
иногда проще обращаться к элементу массива напрямую, а не через функцию.
не спрю, напрямую ,конечно проще, но если надо както автоматизировать это обращение, например обратиться несколько раз одинаковыми методами да к разным массивам... то проще 1раз написать функцию... беда в том, что внутрь функции массив не передается, передается лишь указатель на него и sizeof становится бессилен.Можно всю функцию написать в виде дефайна (т.е. по сути просто много раз продублировав код), каюсь я и так делал
оверхеда практически не остается... (иногда прошивка даже компактнее получается... а можно (как я привел в примере) просто получить размер заранее и как параметр передать функции.
Добавлено after 7 minutes 52 seconds:
ПС: наличие функции не мешает обращаться напрямую... просто вне функции работают и sizeof и дефайн на него (а значит дефайн безполезен), а внутри функции если sizeof просто перестает работать, то дефайн продолжает отображать то, на что его направили.... это полностью убивает универсальность функции (зачем мне размер ARR1 если я работаю с ARR2 ? )
Добавлено after 27 minutes 29 seconds:
Ivanoff-iv, так никакой разницы и нет. Только я предлагала просто держать рядом с массивами дефайны их размеров через sizeof, а вы предпочли инкапсулировать размер в вызов функции....
ничего я не инкапсулировал... А дефайн без параметра или хотя-бы математической операции (чтобы что-то при сборке посчитать), без пользователького значения внутри (которому этот дефайн придает имя) ИМХО штука совсем безполезная... даже код понятнее такой дефайн не делает...
у меня sizeof() всегда рядом с массивом лежит (хоть и только в мыслях)....
Добавлено after 7 minutes 1 second:
ПС вот так смысл появится:
Код: Выделить всё
#define ARR1_SIZE (sizeof(arr1)/sizeof(arr1[0]))А вот так ещё интересней:
Код: Выделить всё
#define quantity(ARR_NAME) (sizeof(ARR_NAME)/sizeof(ARR_NAME[0]))Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Нескольно простых вопросов о программировании AVR на Си.
только все это бесполезно, если адрес массива неизвестной длины берется не по имени массива, а по указателю
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!