|
Как правильно создать многофайловый проект, Ошибка при линковке |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
May 6 2007, 14:24
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(alux @ May 6 2007, 17:07)  void battery_charge(void) { FAST_charge(); } Описка. Найдите разницу в одной букве: Цитата void FAST_carge (void) { } И пожалуй не стоит писать в AVR->IAR, ибо сие ни к AVR ни к IAR отнрошения не имеет. P.S. И дублировать прототипы функций в headers это лишнее.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 6 2007, 14:46
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(jorikdima @ May 6 2007, 17:20)  хидеры то подключены, а в опциях проекта пути к ним прописаны? (если они по поддиректориям распределены) Все файлы (*.с, *.h) лежат в одной рабочей папке. Цитата(zltigo @ May 6 2007, 17:24)  И дублировать прототипы функций в headers это лишнее. Ошибся при наборе сообщения, уже исправил...
|
|
|
|
|
Dec 9 2007, 19:06
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Простите, решил сюда добавить, чтобы темы не плодить. Не так давно пишу на Си. За этот период сильно изменил свои подходы. Теперь проект разбиваю на файлы, которые логически закончены. Это даёт возможность многократного использования с минимальными изменениями. Но вот столкнулся с некоторыми проблемами в таком подходе. В принципе я о них уже читал в разных темах и общие указания слышал/запомнил.
Сама проблема возникает когда п/п из другого файла используется в прерывании, которое в main описывается. Как выходить из неё - вроде понятно. 1) Вообще убрать вызовы п/п. 2) перенести п/п в файл, где пишется прерывание.
Собственно меня интересует более общая тема. Как всётаки сделать так, чтобы и овцы целы и волки сыты. То есть вопросы следующие.
1) Правильным ли является подход с выделением логически законченного блока в отдельный файл со своим хедером. И если "нет" или "не совсем", то хотелось бы услышать как поступают проффессионалы. 2) Как использовать такие "почти библиотеки", чтобы уменьшить накладные рассходы и при этом сохранить красоту написания проги. 3) Является ли выигрышным в этом смысле вариант с С++ и созданием классов/объектов.
|
|
|
|
|
Dec 9 2007, 20:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(SasaVitebsk @ Dec 9 2007, 22:06)  Сама проблема возникает когда п/п из другого файла используется в прерывании, которое в main описывается. Как выходить из неё - вроде понятно. 1) Вообще убрать вызовы п/п. 2) перенести п/п в файл, где пишется прерывание. 3) объявить п/п через extern в соответствующем хидере. Цитата 1) Правильным ли является подход с выделением логически законченного блока в отдельный файл со своим хедером. И если "нет" или "не совсем" Правильным, тока для разрешения всех противоречий нужно еще иметь "главный" хидер в котором и объявляются основные настройки проекта и инклудятся все необходимые хидеры, ИМХО.
|
|
|
|
|
Dec 9 2007, 21:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(SasaVitebsk @ Dec 9 2007, 21:06)  п/п из другого файла используется в прерывании, которое в main описывается. Это как? Обычно обработчик прерывания описываю не в main, а в том же файле, что и остальные п/п соответстующего модуля. А зачем обработчик уносить в тот же файл, где и main? Или это архитектера вроде pic, когда одно прервание на все случаи? Плюсы помогут, ибо в них можно в заголовочном файле описать обработчик как inline.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 10 2007, 07:21
|
Местный
  
Группа: Участник*
Сообщений: 418
Регистрация: 20-08-07
Пользователь №: 29 930

|
Цитата(Непомнящий Евгений @ Dec 10 2007, 09:26)  Просветите плиз - что такое "п/п"? Видимо подпрограмма.... Она же - функция... Немного не С-шная терминология, но суть практически та же... В Фортране к примеру - были функции, кторые возврвщали значение и void-функции, которые не возвращали значение или что почти то же самое обычно - возвращали пустое значение... Еще в некоторых других языках использовалась такая терминология.
Сообщение отредактировал Николай Z - Dec 10 2007, 07:24
|
|
|
|
|
Dec 10 2007, 07:34
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Что такое подпрограмма - я в курсе  Просто не сообразил, что п\п - это ее сокращение. Спасибо. Цитата(Сергей Борщ @ Dec 10 2007, 00:56)  Это как? Обычно обработчик прерывания описываю не в main, а в том же файле, что и остальные п/п соответстующего модуля. А зачем обработчик уносить в тот же файл, где и main? Ну например, чтобы не зависеть от конкретного прерывания. Тогда в модуле (а точнее в хидере) я пишу inline-функцию, а само прерывание делаю в основной программе, дергая из его обработчика эту функцию. Вместо inline-функции в С можно использовать макрос.
|
|
|
|
|
Dec 11 2007, 06:17
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Dec 10 2007, 00:56)  А зачем обработчик уносить в тот же файл, где и main? Это дело вкуса. Я вижу это так. Если железно ясно, что - используется прерывание - и это универсальное решение, то прерывание имеет смысл иметь в модуле, где осуществляется реализация. Если : - хочется иметь main как диспетчер, в котором видна вся логика функционирования - main небольшой по размеру - возможны изменения (без прерывания или с прерыванием), то лучше обработчик прерывания в main. В дальнейшем, когда все устаканится или размер main станет неприличным по размеру, можно его перенести.
|
|
|
|
|
Dec 11 2007, 09:51
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alexander55 @ Dec 11 2007, 08:17)  Если : - хочется иметь main как диспетчер, в котором видна вся логика функционирования Если это ARM, то в main достаточно заносить адреса обработчиков (объявленных как extern) в нужные регистры контроллера прерываний. Тела самих обработчиков в main() не нужны. Если это проц без контроллера, то у него скорее всего вектора жестко распределены за периферией, и выбор вектора просто однозначен - в main нечего диспетчерить. Если хочется иметь выбор из нескольких одинаковых периферийных модулей (UART, например), то можно попробовать так: Код в Hardware.h указываем #define RS232_MODULE USART1 #define RS485_MODULE USART0
в RS232.c: #pragma RS232_MODULE##_UDRE_vect interrupt void RS232_transmit_handler() {
} //опять main.c не у дел Наконец, если используются плюсы и обработчик - метод класса, то код этого метода с атрибутом inline размещается в заголовочном файле, а в main.cpp пишется "обертка": Код __irq void RS232_Handler() { RS232.Handler(); } или #pragma USART1_UDRE_vect interrupt void RS232_transmit_handler() { RS232.Handler(); } при этом обработчик делается private, а функция-обертка объявляется другом класса. Но при желании эти обертки уносятся в файл соответствующего модуля и можно снова применить первый вариант. Цитата(alexander55 @ Dec 11 2007, 08:17)  В дальнейшем, когда все устаканится или размер main станет неприличным по размеру, можно его перенести. Мне кажется, что всякие методики проектирования создают именно для того, чтобы по возможности исключить такую непроизводительную работу. Хотя, конечно, идеала не существует и процесс был и будет итеративным. Но количество итераций можно попытаться уменьшить.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 11 2007, 10:29
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Сергей Борщ @ Dec 11 2007, 12:51)  Наконец, если используются плюсы и обработчик - метод класса, то код этого метода с атрибутом inline размещается в заголовочном файле, а в main.cpp пишется "обертка": Код __irq void RS232_Handler() { RS232.Handler(); } или #pragma USART1_UDRE_vect interrupt void RS232_transmit_handler() { RS232.Handler(); } Я это и имел ввиду. Цитата(Сергей Борщ @ Dec 11 2007, 12:51)  в main нечего диспетчерить. Это не совсем диспетчеризация и даже может совсем не диспетчерезация. Приятно сразу понять логику работы всей системы глядя на один модуль. Детали находятся за рамками и если требуются, то понятно, где это можно посмотреть (глядя на модуль). Второй смысл - это скажем так "просмотр синхронизации потоков и распределенных приложений". Во выдал.
|
|
|
|
|
Dec 11 2007, 10:58
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Я, собственно так и работаю. И думал так все.  В смысле "main" главная или основная. В main.h описываю основные переменные проекта. Например частоту проца и прочее. Этот хидер включаю во все хидера составных частей проекта (В данном последнем это Kls3x4.h, timerhw.h, lcd44780.h, wake.h). В каждом из составляющих хидеров определяются внутренние константы и объявления данного модуля и прототипы функций. В самой main.c описывается вся программа опирающаяся на составные части. Прерывание описывается в main.c Прерывание - метки времени. То есть там целый набор.  в том числе вызовы опроса клавиатуры. Вот и получается - засунуть её в Kls3x4.с некрасиво (там логически законченная библиотека) а при применении в main - есть накладные. Собственно само по себе, естественно, это проблему не вызывает. Данное прерывание обрабатывается раз в 10мс и, честно говоря мне до лампочки что там весь контекст сохраняется. Я просто на будущее. Чтобы оценить кто как работает с оформлением и структурой программы. Ведь не маловажная причина перехода на Си - это читаемость программы её структурированность и возможность неоднократного применения модулей. По крайней мере я так рассматриваю. А опыта пока не хватает. Это я вижу хотябы по тому, что у меня от проекта к проекту пока меняются некоторые моменты оформления. Думаю конечно скоро всё устаканится. Спасибо за советы.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|