Нескольно простых вопросов о программировании AVR на Си.

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение MLX90640 »

Продвинутые микроконтроллеры имеют аппаратные ловушки (флаги ошибок) при таких операциях. На чистом Си без предварительных проверок такое невозможно, компилятор не отслеживает математику переменных. Если 0 - константа, то предупреждение выдаст. Иначе - нет.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

MLX90640, ну тема про AVR-ный Си.
На АВРках нет аппаратных ловушек.
Просто столкнулась, что надо немного математики покрутить с широким диапазоном параметров..... Придется руками проверять всё.....
Эхххх.. где мои любимые begin.... exception when ... then .... end;
Белая и Пушистая
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение WiseLord »

Количество кода, нужного на проверку делителя на ноль - ничуть не больше, чем добавить те же 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 на Си.

Сообщение Just_Fluffy »

WiseLord, деление на ноль - фиг с ним.
У меня будет квадратный корень, тригонометрия, включая тангенс и, возможно, будет еще экспонента, но тут еще не знаю.
И не хотелось бы проверять отдельно отрицательное для корня, +/-90° для тангенса, что б аргумент экспоненты был меньше 88.5 и т.д.
математика будет в одном блоке и хотелось получить либо результат, либо ошибку. Где она возникла - будет не особо важно....
Белая и Пушистая
Аватара пользователя
Roman Solovey
Прорезались зубы
Сообщения: 232
Зарегистрирован: Вт фев 05, 2019 17:20:08
Откуда: Днепр, Украина
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Roman Solovey »

подскажите как можно узнать длину массива хранящегося в progmem? У меня есть массив указателей(тоже в progmem) который хранит в себе указатели на массивы, но они разной длины, и вот их нужно передать в функцию вывода, но так же нужно знать размер.. И это не строка, по нуль символу парсить не получится(
костыль я уже придумал. в нулевом элементе каждого массива хранить его размер. но может есть что по изящнее?\
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

в си нельзя в общем случае по указателю определить размер области, на которую он указывает.
ваш костыль - не костыль, в вполне обычная практика.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

ARV, там же массивы прибиты гвоздями в progmem и скорее всего не меняются в run-time. Это ж не выделение памяти в куче.


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 на Си.

Сообщение Roman Solovey »

спасибо за подсказки)
с дефайнами морочнее будет. мне шрифт нужно к дисплею прикрутить, а это много символов)
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

Roman Solovey, если размер каждого символа одинаков - то множить код символа на размер. Если ширина разная - то оптимально в первом байте символа держать размер этого символа. Так все делают.
Плюс дополнительно, если отвести еще один байт на код символа - можно собирать в шрифт только нужные символы.
Белая и Пушистая
Аватара пользователя
Roman Solovey
Прорезались зубы
Сообщения: 232
Зарегистрирован: Вт фев 05, 2019 17:20:08
Откуда: Днепр, Украина
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Roman Solovey »

Плюс дополнительно, если отвести еще один байт на код символа - можно собирать в шрифт только нужные символы.

Немного не понял. это типа в программе которая генерит шрифты нужно выделить?
Одержать сто побед в ста битвах — это не вершина воинского искусства. Повергнуть врага без сражения — вот вершина.
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Just_Fluffy »

Roman Solovey, есть 2 подхода.
1. в шрифте сохранены все символы, цифры , англицкий алфавит, кириллический алфавит. Это порядка 160 символов.
И все эти символы хранятся в прогмем и занимают место.
А нам надо написать "ПРИВЕТ!" - из 160 символов нужно всего 7. И 153 символа просто занимают память.
2. В шрифте сохранены только нужные символы. Цена этого - + 1 байт к каждому символу - в этом бате хранится код.
И для надписи "ПРИВЕТ!" достаточно сохранить 7 символов всего.
но если вдруг придется написать, "ПРИВЕТ, ВАСЯ!" - то нужно будет выгружать заново не 7, а 12 символов.
Белая и Пушистая
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

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 на Си.

Сообщение KorbenDallas »

А кто подскажет, в голом Си (на МК) реально отловить деление на ноль, не проверяя делитель перед делением?
try... catch вроде ж только для плюсов....


try/catch в С++ не отлавливает деление на ноль и вообще не имеет никакого отношения к этому.

отловить деление на ноль, не проверяя делитель перед делением?


Никак. Ни в С, ни в С++.
Последний раз редактировалось KorbenDallas Сб окт 08, 2022 23:17:36, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение ARV »

- Вась, а Вась, чем С++ от С отличается?
- 1
- ну правда, Вась?
:)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Мурик
Друг Кота
Сообщения: 3383
Зарегистрирован: Пн окт 11, 2010 19:00:08

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Мурик »

ARV, не 1, а True :)
Аватара пользователя
MLX90640
Опытный кот
Сообщения: 848
Зарегистрирован: Ср авг 03, 2022 05:22:56

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение MLX90640 »

Roman Solovey, для шрифтов массив данных символа делается либо одинакового для всех символов размера, либо размер массива данных каждого символа косвенно хранится в таблице описаний символов. Некоторые утилиты создания шрифтов (например Dot Factory) умеют создавать такие таблицы.
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Ivanoff-iv »

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:
Пример:

Код: Выделить всё

/*поиск в 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 на Си.

Сообщение Just_Fluffy »

Ivanoff-iv, так никакой разницы и нет. Только я предлагала просто держать рядом с массивами дефайны их размеров через sizeof, а вы предпочли инкапсулировать размер в вызов функции....
Вроде и красивее, но иногда проще обращаться к элементу массива напрямую, а не через функцию.
Но суть одна - инструментов определить размер массива нету. Для динамических надо самому помнить, сколько мы отгрызли памяти под массив. Для статических - в design-time где то сохранять размер. Через тот же sizeof, к примеру. И это нормальная практика.
Белая и Пушистая
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Нескольно простых вопросов о программировании AVR на Си.

Сообщение Ivanoff-iv »

так sizeof и дефайн на него ничего не хранят (по крайней мере там, где написаны), а лишь указывают на константу в памяти компилятора и говорить о том, что одна лежит к массиву ближе другой... :dont_know:
по мне так sizeof применять удобнее, т.к. она имеет параметр, через который её вызов можно автоматизировать... свою подменку тоже можно автоматизировать, но это сложнее

Добавлено after 8 minutes 38 seconds:
иногда проще обращаться к элементу массива напрямую, а не через функцию.
не спрю, напрямую ,конечно проще, но если надо както автоматизировать это обращение, например обратиться несколько раз одинаковыми методами да к разным массивам... то проще 1раз написать функцию... беда в том, что внутрь функции массив не передается, передается лишь указатель на него и sizeof становится бессилен.
Можно всю функцию написать в виде дефайна (т.е. по сути просто много раз продублировав код), каюсь я и так делал :) , оптимизатор, кстати, такой код ооочень хорошо ужимает :hunger: оверхеда практически не остается... (иногда прошивка даже компактнее получается... :shock: )
а можно (как я привел в примере) просто получить размер заранее и как параметр передать функции.

Добавлено after 7 minutes 52 seconds:
ПС: наличие функции не мешает обращаться напрямую... просто вне функции работают и sizeof и дефайн на него (а значит дефайн безполезен), а внутри функции если sizeof просто перестает работать, то дефайн продолжает отображать то, на что его направили.... это полностью убивает универсальность функции (зачем мне размер ARR1 если я работаю с ARR2 ? )

Добавлено after 27 minutes 29 seconds:
Ivanoff-iv, так никакой разницы и нет. Только я предлагала просто держать рядом с массивами дефайны их размеров через sizeof, а вы предпочли инкапсулировать размер в вызов функции....
ничего я не инкапсулировал... :oops: :))) это просто небольшая часть возможностей дефайна по облегчению написания кода, я даже имени ни одного из массивов не упомянул - всё подставляется и считается автоматически!

А дефайн без параметра или хотя-бы математической операции (чтобы что-то при сборке посчитать), без пользователького значения внутри (которому этот дефайн придает имя) ИМХО штука совсем безполезная... даже код понятнее такой дефайн не делает... :cry: зачем он?
у меня 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 на Си.

Сообщение ARV »

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

Мой уютный бложик... заходите!
Ответить

Вернуться в «AVR»