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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

Мой уютный бложик... заходите!
Реклама
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

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

Сообщение _dark »

ARV писал(а):если есть прототип в хедере или явно в модуле - да
сорри, конечно!
в *.h автоматом же прототипы пишу и его же (*.h) подключаю в *.с
уже и забыл об этом :))

зы
вот за что я люблю этот форум, что тут даже если и не прав, то просто поправят, без тролления :)
Реклама
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

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

Сообщение strengerst »

Функцию объявил, тип задан все равно что то не так.
СпойлерИзображение
Сама функция вызывается в прерывании

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

ISR(PCINT0_vect)
{//Отключаем прерывания от изменения сигнала на порта 
GIMSK&=~(1<<PCIE);
Timserstart();
}
Если функция описать выше ее вызова в самом начале то есть до прерывания то первое сообщение о неизвестном вызове функции убирается.
Вложения
функция2.png
(130.65 КБ) 361 скачивание
Последний раз редактировалось strengerst Чт ноя 24, 2016 12:22:49, всего редактировалось 1 раз.
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

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

Сообщение _dark »

1. где объявили?
2. она ничего не возвращает, оператор return где?

ps
не пробовали букварь по Си читать?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

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

Сообщение strengerst »

Функция нечего не возвращает по этому return не нужен.
1. где объявили?
. Все там же, предыдущий скрин.
Последний раз редактировалось strengerst Чт ноя 24, 2016 12:26:46, всего редактировалось 1 раз.
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Вы фунцию написали так, чтобы она возвращала unsigned char. Но не возвращаете, и чему-то удивляетесь.
Реклама
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

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

Сообщение strengerst »

А если мне не нужно нечего возвращать просто присвоить пару параметров и все.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

_dark писал(а):а это то (static void) зачем ему?
_dark писал(а):в *.h автоматом же прототипы пишу и его же (*.h) подключаю в *.с
В том-то и суть. Нет смысла выносить все функции в хидер - ведь не все они будут вызываться из других участков кода. Если функция чисто внутри модуля (а-ля приватная в C++) - лучше её просто в .c описать. А сделав её ещё и static, мы уже конкретно укажем компилятору, что нигде, кроме этого модуля, она больше использоваться не будет, что может ему помочь с оптимизацией кода (внутренняя компоновка)
strengerst писал(а):А если мне не нужно нечего возвращать
Я Вам сразу сказал - сделать её void. Но Вы почему-то unsigned char сделали.
Аватара пользователя
strengerst
Вымогатель припоя
Сообщения: 516
Зарегистрирован: Пт янв 18, 2013 15:11:02

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

Сообщение strengerst »

Я Вам сразу сказал - сделать её void. Но Вы почему-то unsigned char сделали.
Спасибо, вы правы действительно помогло ошибки исчезли,
Всем спасибо за оказанную помощь
Последний раз редактировалось strengerst Чт ноя 24, 2016 12:44:49, всего редактировалось 1 раз.
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

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

Сообщение _dark »

WiseLord писал(а): Нет смысла выносить все функции в хидер - ведь не все они будут вызываться из других место кода. Если функция чисто внутри модуля (а-ля приватная в C++) - лучше её просто в .c описать. А сделав её ещё и static, мы уже конкретно укажем компилятору, что нигде, кроме этого модуля, она больше использоваться не будет, что может ему помочь с оптимизацией кода.
это спорный вопрос
1. мы ничего не знаем о текущих задачах вопрошающего - где и откуда он ее вызывает еще
2. мы ничего не знаем о том как что у него будет меняться - где будет вызывать

- за себя могу сказать, что стандартное объявление всех функций модуля в *.h снимает много головной боли,
в свое время работая с keil он требовал прототип указывать в *.с, но чтобы использовать в др. модуле
нужно еще было объявить его же в *.h, что по "молодости" вызывало у меня недоумение и кашу в голове
- жизнь приучает писать, так, чтобы модуль можно было многократно использовать в разных проектах, по сути - библиотеки,
и что и когда понадобится я сам не знаю, поэтому все протоотипы в *.h
- достаточно посмотреть как объявляются прототипы в Borland или VS


3. насчет оптимизации, нет практически никакой разницы, за 15 лет не заметил ни разу, для оптимизации есть другие средства
- компилятор /линкер не включает все прототипы в код, а только используемые, остальное выбросит
но это ИМХО

4. объявление прототипа - правильная стратегия, совет двигать выше/ниже функции для новичка я бы не рекомендовал,
будет переучиваться, но потом :))
Последний раз редактировалось _dark Чт ноя 24, 2016 12:54:47, всего редактировалось 1 раз.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

_dark писал(а):насчет оптимизации, нет практически никакой разницы
есть большая разница между обычными функциями и static - я так понимаю, речь об этом шла. само собой, прототипы static функций в заголовочник выносить нет смысла, и даже может быть вредно.
_dark писал(а):объявление прототипа - правильная стратегия
стратегия-то правильная... но согласно исповедуемому мной принципу не всегда является необходимой :) нет нужды плодить сущности без реальной необходимости. понимание гораздо важнее.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
ptr128
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

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

Сообщение ptr128 »

_dark писал(а): - компилятор /линкер не включает все прототипы в код, а только используемые, остальное выбросит
Если бы прототипы куда-то попадали, что к Вам бы вся libc в полном составе в прошивку прилетала )
Прототипы вообще никуда не попадают, а служат исключительно для определения правильной конвенции вызова, контролем за типом возвращаемого значения и контролем за количеством и типами параметров.
В объектный файл, как доступные компоновщику идентификаторы, попадают имена всех функций и глобальных переменных модуля, кроме описанных как static и ссылки только на те внешние объекты (функции или глобальные переменные), на которые были ссылки в коде модуля.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

2 _dark: Правильная стратегия - объявление в .h файле прототипов только тех фукнций, которые будут использоваться снаружи. Тем самым мы формируем интерфейс, с помощью которого данный код (драйвер, что-то ещё) общается с внешним кодом.

Внутренние вспомогательные функции делать видимыми (посредством .h файла) снаружи - плохая практика. Все эти функции очень желательно сделать чисто локальными (static) и описывать в самом верху .c файла.

Собственно, в объектно-ориентированном программировании этот подход (инкапсуляция) является одним из базовых. Тут, конечно, речь о C, но актуальность самого принципа как можно сильнее изолировать код от мест, где он не используется, никуда не теряется..

При оптимизации разница есть. Как правило, объявление функции как static делает код меньше по размеру. Да, иногда эффекта нет, но только лишь потому, что компиляторы (тот же AVR-GCC) достаточно умные, и даже если функция описана в хидерах, но не используется, могут прозрачно делать её static (использовать внутреннюю компоновку).
Последний раз редактировалось WiseLord Чт ноя 24, 2016 13:01:38, всего редактировалось 1 раз.
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

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

Сообщение _dark »

ARV писал(а):есть большая разница между обычными функциями и static - я так понимаю, речь об этом шла.
а я понял, что о прототипах :)))

Добавлено after 13 minutes 32 seconds:
WiseLord писал(а): Внутренние вспомогательные функции делать видимыми (посредством .h файла) снаружи - плохая практика. Все эти функции очень желательно сделать чисто локальными (static) и описывать в самом верху .c файла.
Собственно, в объектно-ориентированном программировании этот подход (инкапсуляция) является одним из базовых. Тут, конечно, речь о C, но актуальность самого принципа как можно сильнее изолировать код от мест, где он не используется, никуда не теряется..
Посмотрите на свой любой исходник...
знакомо?

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

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h> 
когда вы подключаете хидером системные библиотеки, вы считаете, что неиспользуемые функции изолируете?
а чем ваши модули отличаются от них? мои ничем (ну кроме кривости написания :)) )
Аватара пользователя
ptr128
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

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

Сообщение ptr128 »

WiseLord писал(а):если функция описана в хидерах, но не используется, могут прозрачно делать её static (использовать внутреннюю компоновку).
Если функция не используется, то компилятору на нее искренне наплевать и компоновщик о том, что ее прототип был в модуле, даже не узнает.

К оптимизации описание static приводит только в тех случаях, когда компилятор может сам определить, что функция использует не все регистры, которые обязана сохранять вызывающая программа. А значит, часть регистров компилятор может не сохранять и/или не восстанавливать их значение после вызова. Отсюда следует (раз уж речь про AVR), что если static функция использует в коде все регистры R2–R17, R28, R29, то никакой оптимизации вы от компилятора не дождетесь.
В частном случае, незначительную оптимизацию можно получить и благодаря использованию RCALL вместо CALL.
Еще частный случай. Если static функция вызывается в пределах модуля только один раз, GCC сделает ее inline. То есть, в ассемблерном коде модуля, Вы ее вообще не обнаружите, как функцию.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Аватара пользователя
_dark
Встал на лапы
Сообщения: 93
Зарегистрирован: Чт апр 26, 2012 14:30:40
Откуда: под Москвой

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

Сообщение _dark »

ptr128 писал(а):
_dark писал(а): не включает все прототипы в код
Если бы прототипы куда-то попадали...,
конечно речь не о самих прототипах, не удачно выразился

ps
(мне можно я не программист :)) )

ptr128 спасибо, очень доходчиво, ... но не все верно
Последний раз редактировалось _dark Чт ноя 24, 2016 13:30:53, всего редактировалось 2 раза.
Аватара пользователя
ptr128
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

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

Сообщение ptr128 »

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

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

Сообщение ARV »

ptr128 писал(а):К оптимизации описание static приводит только в тех случаях, когда компилятор может сам определить, что функция использует не все регистры, которые обязана сохранять вызывающая программа.
касательно WinAVR (с более новыми версиями опыта нет) вы не полностью правы: компилятор/оптимизатор вполне может сам проинлайнить static функцию, если это будет соответствовать текущей стратегии оптимизации... но как правило большой эффект наблюдается для однократно вызываемых функций - они все инлайнятся по коду.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

_dark писал(а):когда вы подключаете хидером системные библиотеки, вы считаете, что неиспользуемые функции изолируете?
Когда я подключаю системные библиотеки, это значит, что я в коде использую только то, что описано в этих файлах, и не более того. Я не могу никак вызвать всю ту кучу функций, которые понаписаны в .с файлах этих библиотек, но не вынесены в .h, подключаемые мною.

Разработчик этих библиотек всё, что нужно программисту,описал в хидерах, а внутренний вспомогательный код оставил локальным. К тому же и я призываю - выносить в заголовки только нужные фцнкции, а не все подряд.
Аватара пользователя
ptr128
Вымогатель припоя
Сообщения: 606
Зарегистрирован: Чт окт 06, 2016 21:12:07
Откуда: Южное Бутово

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

Сообщение ptr128 »

ARV писал(а):компилятор/оптимизатор вполне может сам проинлайнить static функцию, если это будет соответствовать текущей стратегии оптимизации...
Теоретически. Если вы выключили оптимизацию по размеру кода (-Os), которая всегда включена во всех AVR IDE. Но разве Вы сами неоднократно не призывали такие ситуации тут не рассматривать?
ARV писал(а):но как правило большой эффект наблюдается для однократно вызываемых функций - они все инлайнятся по коду.
А я что писал?
ptr128 писал(а):Если static функция вызывается в пределах модуля только один раз, GCC сделает ее inline. То есть, в ассемблерном коде модуля, Вы ее вообще не обнаружите, как функцию.
Не ошибается только то, кто ничего не делает.
Тот, кто признает свои ошибки, на них учится.
Глупец же, упорствуя в своих заблуждениях, остается глупцом.
Ответить

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