Обсуждаем контроллеры компании Atmel.
Ответить

Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 14:11:58

есть почти готовый проект на Атмеге8. Чуть чуть не помещаюсь в память. Решил поробовать оптимизировать и пере собрать. И тут у меня возник такой вопрос:
Принцип разнесения проекта на отдельные файлы мне понятен.
Но зачем разбивать все по паре файлов (к примеру led.c и led.h)почему бы не писать все только в ***.h?

Прошу прощения, если вопрос глуповат, но простым поиском ответ не нашел.

Re: Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 19:08:59

В файлы .C пишут код функций, в заголовочные файлы .H - прототипы и определения, необходимые для доступа к функциям из других модулей .С что их вызывают.
Если свалить всё в кучу и в несколько модулей include-ить этот файл, то компилятор свалиться в ошибку так как увидит множественное переопределение одних и тех же функций и переменных.
В целом такой подход не запрещается стандартами Си и компилятором, но является плохой техникой программирования и этого следует избегать.

Re: Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 19:40:31

Я задал этот вопрос исходя немного из другой логики.
Как я пинимаю, все равно все инкюдится в оснойвной файл, к примеру main.c
Так что переопределений не будет.
При этом, в моем проекте старом, все разбито по 2 файла (*.с и *.h).
И когда в какой нибудь функции, вынесеной в другой файл, нужно получить доступ к переменным из основного файла их приходится определять в файле с функцией. По моему это тоже подъедает память.

Вот я и подумал, если *.h все равно инклюдятся в main.c то почему бы не сделать отдельный *.h с переменными, отдельные *.h на раздельные модули и функции и заинклюдить их в main.c
Или функции записанные в *.h и заинклюденные не будут вызываться в теле программы?

Добавлено after 1 minute 50 seconds:
Не знаю, понятно ли объяснил свою мысль.

Re: Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 19:58:24

В языке Си (не С++, а просто С) очень плохо обстоят дела с областью видимости. Всё, что объявили в .h файле, тут же считается глобальным. Поэтому, всё что пишите в .h файле и в каком порядке организуете их подключение, вообще никаким образом не влияет на размер генерируемого кода.
Более того, объявлять переменные в .h файле вообще не принято и приведет к ошибке компиляции, если попытаетесь инициализовать переменные там. В .h файл можно записать только "ссылку" на переменную с квалификатором extern, а сама переменная должна быть объявлена в .c файле. Переменные бывают глобальными, когда объявлены в .c файле вне любой функции, или локальными, объявленными внутри какой-либо функции. Локальные переменные функции (за исключением переменных с квалификатором static) будут "временными", существующими только во время выполнения функциии. Все глобальные переменные и локальные static постоянно занимают место в ОЗУ. Они и отъедают от ОЗУ постоянный кусок.

А у вас какой памяти то не хватает - ОЗУ или памяти программ?
Если проблема с нехваткой ОЗУ, то следует избегать большого числа глобальных переменных вне функций. Перепишите функции таким образом, чтобы внешние переменные передавались в функцию через параметры. Это несколько замедлит работу, зато освободит ОЗУ.

Re: Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 22:48:14

Не хватает памяти программ.

Re: Вопрос по программированию в ATMEL Studio 7

Чт май 19, 2022 23:34:03

Vovik-78 писал(а): нужно получить доступ к переменным из основного файла их приходится определять в файле с функцией.

сделайте файл main.h и вставьте туда декларацию переменных
extern uint8_t var1, var2, var3 и т.д.
Затем подключайте этот заголовочник ко всем файлам, нуждающихся в ваших переменных.

Можно почитать ещё тут http://microsin.net/programming/arm-tro ... xtern.html.

Vovik-78 писал(а):По моему это тоже подъедает память.

Не должно. Вроде как в атмел студио не совсем тупой компилятор.
Если есть сомнения, свалите содержимое всех интересуемых файлов в один main и скомпилируйте.

Я считаю что доступ функций к переменным - это последнее с чем надо возиться. Посмотрите, есть ли в проекте работа с float числами, деление, действия с 32-битными данными и другие тяжёлые мат. операции либо вызов библиотечных функций.

Re: Вопрос по программированию в ATMEL Studio 7

Пт май 20, 2022 08:52:05

Числа у меня целые, всего пару переменных 16 бит. Деление конечно есть, этих 16битных чисел на разряды индикаторов.

Re: Вопрос по программированию в ATMEL Studio 7

Пт май 20, 2022 11:13:57

Радикальное решение - переписать на асме, и ещё место останется - не катит, конечно?
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.

Re: Вопрос по программированию в ATMEL Studio 7

Пт май 20, 2022 11:33:51

Vovik-78 писал(а):Вот я и подумал, если *.h все равно инклюдятся в main.c то почему бы не сделать отдельный *.h с переменными, отдельные *.h на раздельные модули и функции и заинклюдить их в main.c
h-файлы инклюдятся там, где это нужно. фишка разделения проекта на отдельные c-файлы заключается в том, что каждый такой файл компилируется отдельно от других, и только в том случае, если компилятор (точнее, система сборки, но не суть важно) определит, что исходник изменялся с предыдущей компиляции. это повышает скорость сборки проекта при многочисленных правках кода.

что касается оптимизации, то тут важно понимать, о каком именно объеме "экономии" идет речь. если о паре байтов, то практически всегда есть возможность найти способ их сэкономить. если речь о десятке-другом байтов - то вероятность достаточно велика их найти. начиная примерно с сотни байт лучше задумываться о переводе проекта на новый МК с большим "простором".

из неочевидного, и чаще всего неизвестного новичкам, могу дать такие советы:
- попробуйте собрать проект с ключиком -flto для компилятора и линкера, на свежих версиях компилятора в моих проектах только это давало выигрыш до 100 байт и более;
- попробуйте -mrelax в опциях компилятора и -Wl,-relax для линкера - частенько даёт заметный выигрыш "из ниткуда";
- проверьте, что ваш проект собирается с опциями -ffunction-sections и -fdata-sections для компилятора и -Wl,-gc-sections для линкера - в определенных случаях это позволяет в разы сократить размер выхлопа!

Добавлено after 6 minutes 46 seconds:
да, еще одно: сделайте все функции, не вызываемые "перекрестно" из разных c-файлов, static - это тоже помогает в борьбе за байты flash

и последнее: если у вас есть глобальная переменная, которая инициализируется в момент объявления, т.е. типа такого static int var = 1;, подумайте 10 раз: оно действительно вам надо, чтобы эта переменная была НЕ НОЛЬ изначально? дело в том, что все ненулевые значения, присваиваемые глобальным (и/или static) переменным, увеличивают расход flash ровно на константу соответствующего типа, т.е. в приведенном мной примере это будет 2 байта.

и самое-самое последнее: помните, что все строковые константы ДВАЖДЫ занимают память: один раз в ОЗУ, второй раз во flash. это к экономии flash относится слабо, но вот к экономии ОЗУ - сильно.

Re: Вопрос по программированию в ATMEL Studio 7

Пт май 20, 2022 13:33:03

Радикальное решение - переписать на асме, и ещё место останется - не катит, конечно?
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.


Неее. Ну до асьмы мне еще далеко. Я и с СИ еще на вы.
Если правильно помню -12 файлов.

Добавлено after 7 minutes 54 seconds:
AVR - большое спасибо за развернутый ответ. Проверю все эти настройки.
Вы еще и мой земляк оказывается. )))
Ответить