Вопрос по программированию в ATMEL Studio 7
Вопрос по программированию в ATMEL Studio 7
есть почти готовый проект на Атмеге8. Чуть чуть не помещаюсь в память. Решил поробовать оптимизировать и пере собрать. И тут у меня возник такой вопрос:
Принцип разнесения проекта на отдельные файлы мне понятен.
Но зачем разбивать все по паре файлов (к примеру led.c и led.h)почему бы не писать все только в ***.h?
Прошу прощения, если вопрос глуповат, но простым поиском ответ не нашел.
Принцип разнесения проекта на отдельные файлы мне понятен.
Но зачем разбивать все по паре файлов (к примеру led.c и led.h)почему бы не писать все только в ***.h?
Прошу прощения, если вопрос глуповат, но простым поиском ответ не нашел.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопрос по программированию в ATMEL Studio 7
В файлы .C пишут код функций, в заголовочные файлы .H - прототипы и определения, необходимые для доступа к функциям из других модулей .С что их вызывают.
Если свалить всё в кучу и в несколько модулей include-ить этот файл, то компилятор свалиться в ошибку так как увидит множественное переопределение одних и тех же функций и переменных.
В целом такой подход не запрещается стандартами Си и компилятором, но является плохой техникой программирования и этого следует избегать.
Если свалить всё в кучу и в несколько модулей include-ить этот файл, то компилятор свалиться в ошибку так как увидит множественное переопределение одних и тех же функций и переменных.
В целом такой подход не запрещается стандартами Си и компилятором, но является плохой техникой программирования и этого следует избегать.
Re: Вопрос по программированию в ATMEL Studio 7
Я задал этот вопрос исходя немного из другой логики.
Как я пинимаю, все равно все инкюдится в оснойвной файл, к примеру main.c
Так что переопределений не будет.
При этом, в моем проекте старом, все разбито по 2 файла (*.с и *.h).
И когда в какой нибудь функции, вынесеной в другой файл, нужно получить доступ к переменным из основного файла их приходится определять в файле с функцией. По моему это тоже подъедает память.
Вот я и подумал, если *.h все равно инклюдятся в main.c то почему бы не сделать отдельный *.h с переменными, отдельные *.h на раздельные модули и функции и заинклюдить их в main.c
Или функции записанные в *.h и заинклюденные не будут вызываться в теле программы?
Добавлено after 1 minute 50 seconds:
Не знаю, понятно ли объяснил свою мысль.
Как я пинимаю, все равно все инкюдится в оснойвной файл, к примеру main.c
Так что переопределений не будет.
При этом, в моем проекте старом, все разбито по 2 файла (*.с и *.h).
И когда в какой нибудь функции, вынесеной в другой файл, нужно получить доступ к переменным из основного файла их приходится определять в файле с функцией. По моему это тоже подъедает память.
Вот я и подумал, если *.h все равно инклюдятся в main.c то почему бы не сделать отдельный *.h с переменными, отдельные *.h на раздельные модули и функции и заинклюдить их в main.c
Или функции записанные в *.h и заинклюденные не будут вызываться в теле программы?
Добавлено after 1 minute 50 seconds:
Не знаю, понятно ли объяснил свою мысль.
Re: Вопрос по программированию в ATMEL Studio 7
В языке Си (не С++, а просто С) очень плохо обстоят дела с областью видимости. Всё, что объявили в .h файле, тут же считается глобальным. Поэтому, всё что пишите в .h файле и в каком порядке организуете их подключение, вообще никаким образом не влияет на размер генерируемого кода.
Более того, объявлять переменные в .h файле вообще не принято и приведет к ошибке компиляции, если попытаетесь инициализовать переменные там. В .h файл можно записать только "ссылку" на переменную с квалификатором extern, а сама переменная должна быть объявлена в .c файле. Переменные бывают глобальными, когда объявлены в .c файле вне любой функции, или локальными, объявленными внутри какой-либо функции. Локальные переменные функции (за исключением переменных с квалификатором static) будут "временными", существующими только во время выполнения функциии. Все глобальные переменные и локальные static постоянно занимают место в ОЗУ. Они и отъедают от ОЗУ постоянный кусок.
А у вас какой памяти то не хватает - ОЗУ или памяти программ?
Если проблема с нехваткой ОЗУ, то следует избегать большого числа глобальных переменных вне функций. Перепишите функции таким образом, чтобы внешние переменные передавались в функцию через параметры. Это несколько замедлит работу, зато освободит ОЗУ.
Более того, объявлять переменные в .h файле вообще не принято и приведет к ошибке компиляции, если попытаетесь инициализовать переменные там. В .h файл можно записать только "ссылку" на переменную с квалификатором extern, а сама переменная должна быть объявлена в .c файле. Переменные бывают глобальными, когда объявлены в .c файле вне любой функции, или локальными, объявленными внутри какой-либо функции. Локальные переменные функции (за исключением переменных с квалификатором static) будут "временными", существующими только во время выполнения функциии. Все глобальные переменные и локальные static постоянно занимают место в ОЗУ. Они и отъедают от ОЗУ постоянный кусок.
А у вас какой памяти то не хватает - ОЗУ или памяти программ?
Если проблема с нехваткой ОЗУ, то следует избегать большого числа глобальных переменных вне функций. Перепишите функции таким образом, чтобы внешние переменные передавались в функцию через параметры. Это несколько замедлит работу, зато освободит ОЗУ.
Re: Вопрос по программированию в ATMEL Studio 7
Не хватает памяти программ.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопрос по программированию в ATMEL Studio 7
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
Числа у меня целые, всего пару переменных 16 бит. Деление конечно есть, этих 16битных чисел на разряды индикаторов.
Re: Вопрос по программированию в ATMEL Studio 7
Радикальное решение - переписать на асме, и ещё место останется - не катит, конечно?
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопрос по программированию в ATMEL Studio 7
h-файлы инклюдятся там, где это нужно. фишка разделения проекта на отдельные c-файлы заключается в том, что каждый такой файл компилируется отдельно от других, и только в том случае, если компилятор (точнее, система сборки, но не суть важно) определит, что исходник изменялся с предыдущей компиляции. это повышает скорость сборки проекта при многочисленных правках кода.Vovik-78 писал(а):Вот я и подумал, если *.h все равно инклюдятся в main.c то почему бы не сделать отдельный *.h с переменными, отдельные *.h на раздельные модули и функции и заинклюдить их в main.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
Радикальное решение - переписать на асме, и ещё место останется - не катит, конечно?
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.
А на сколько файлов разбит исходник - это вопрос третьестепенной важности.
Неее. Ну до асьмы мне еще далеко. Я и с СИ еще на вы.
Если правильно помню -12 файлов.
Добавлено after 7 minutes 54 seconds:
AVR - большое спасибо за развернутый ответ. Проверю все эти настройки.
Вы еще и мой земляк оказывается. )))
