|
Новичок на С, Помогите разобраться со структурой проекта |
|
|
|
Feb 7 2006, 21:56
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Доброго времени суток. Помогите начинающему. Долгое время писал на асме для разных микропроцессоров. В том числе большие проекты. На IBM приходилось писать вспомогательные програмки на Delfi. "C" использовать не приходилось. В данный момент приходится осваивать для реализации крупного и длительного проекта. "С" так, как есть вариант впоследствии перейти на др. МП. Почитал, - синтаксис языка вполне понятен. Хоть сейчас в бой. Но нек. моменты не понятны. Во-первых, не хочу обидеть чьи-нибудь чувства, но более дебильной и запутанной IDE среды чем IAR Wb я не встречал. Но к этому привыкну. Скачал PDFы и сделал книжечки. По возможности изучил. Сделал маленькую прогу, но всё равно остался ряд вопросов по организации проги. 1) Как определять какие библиотеки включать? 2) Если необходимы прерывания достаточно ли такого объявления или необходимо что-то ещё (например переходы): #pragma vector=USART_RXC_vect __interrupt void rxint(void) { } 3) Как понимать следующие строки? (В смысле на языке высокого уровня) jmp_buf main_task; jmp_buf iprx_task; jmp_buf iptx_task; char iprx_rstack[8]; и вот эти пжлст #pragma vector=USART_RXC_vect __interrupt void rxint(void) { if (!setjmp(main_task)) //Запомнили контекст осн. задачи { longjmp(iprx_task,1); //Перешли в контекст IPrecive } } 4) Что необходимо описывать чтобы грамотно сделать проект в котором несколько файлов ".С" 5) При использовании кольцевого буфера правильнее открыть буфер в виде массива или использовать указатели. 6) Профи, если можно вышлите какой-нибудь файл(ы) исходников (можно не рабочих, урезанных или с ошибками) по которым я мог бы посмотреть структуру программы. Лучше с прерываниями. Обязуюсь не распространять и использовать в качестве учебных. Пожалуйста не присылайте слишком больших, а то я зароюсь.  Заранее благодарен. e-mail: sasa@c32dvina.com
|
|
|
|
|
 |
Ответов
|
Mar 17 2006, 17:59
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Я извиняюсь перед всеми. Надо было более детально разобраться в произошедшем, а потом писать. Спасибо всем высказавшимся. Скажу что изучал когда-то очень давно теорию компиляторов и ОС.  Но тогда мне это было не нужно и безинтересно. Тогда безгранично годсподствовала ОС ЕС ЭВМ и только0-только появилась СВМ! С каким бы я интересом послушил бы сейчас того препода! Такой класный был преподаватель ... Теперь по сути. Компилятор, очевидно, очень хороший. Местами великолепно "угадывает" как надо делать и прекрассно компилирует. Но некоторые фичи я пока не понимаю. 1) В процедуре обработки прерывания я не вызываю функций. (Прочитал в других ветках форума). Но если я пользуюсь переменными, объявленными как статические глобальные (вверху файла), то код получается значительно больший. Похоже компилятор пытается выделять локальные экземпляры переменных или что-то в этом духе. Обращение к этим переменным осуществляется ч/з указатель. Не совсем понимаю зачем это? Может чтобы дважды можно было вызвать? Если объявляешь статическими внутри функции, то код намного понятнее. А как надо объявлять? Я хочу чтобы от вызова к вызову переменные сохраняли своё значение. 2) Наблюдаю картину, что если арифметическое выражение сделать сложным, то компилятор начинает генерить сложный код. Получается что лучше разбивать операторы на более простые? 3) Мне необходимо в прерывании выполнить определённую операцию 18 раз. Можно сделать её путём логических операций. Но что бы ускорить процесс я решил воспользоваться табличным методом. Для этого сгенерировал соответсвующий массив. Вне данного прерывания этот массив использоваться не будет. Я объявил его в другом файле вместе с другими таблицами а в перывании объявил его как внешний. (Пробовал объявить его внутри прерывания, - компилятор ругается). Так вот обращение к этому массиву какое-то мудрёное. Может кто подскажет в чём дело? 4) На счёт одинадцати байт.  И правда и не совсем.  С одной стороны при обращении к битам происходит обращение только к одному байту! Причём обращение красивое!!! Но в распечатке листинга (релиз) я сейчас вижу следующее: // 70 } Flag; Flag: DS 1 DS 1 А раньше выделялось 11 байт. Вроде ничего не менял. Пробовал воткнуть STATIC, - не получилось. Кстати ко многим переменным добавляется ещё один байт. Это зачем? Пятое и пока последнее. Спасибо всем откликающимся. Я конечно постепенно приду к определённым результатам и самостоятельно, не отрывая Вас от Ваших дел, но мне кажется что данный форум читаю не только я, но и другие начинающие программисты С. И, мне хочется надеятся, что он будет полезен для многих, поскольку я пытаюсь ставить вопросы, так сказать, из жизни.
|
|
|
|
|
Mar 17 2006, 19:52
|

Частый гость
 
Группа: Свой
Сообщений: 175
Регистрация: 26-01-06
Из: Sevastopol
Пользователь №: 13 664

|
Цитата(Old1 @ Mar 17 2006, 20:53)  Компилятор глобальные переменные по умолчанию помещает в SRAM, поэтому и обращается к ним через указатель, времени это занимает больше, если сравнивать с обращениями к регистровому файлу или к io-регистрам (поэтому обычно рекомендуют стараться меньше использовать глобальные переменные). Для того чтобы уменьшить время выполнения обработчика прерывания можно посоветовать объявить глобальную переменную как регистровую или разместить ее в неиспользуемых io-регистрах. Ответ большей частью верный, но непонятный для начинающих. Попробую пояснить. Имеем три вида переменных в языке C: 1) Глобальные, объявленные на внешнем уровне. 2) Локальные статические, объявленные внутри функции и сохраняющие свои значения между вызовами. 3) Локальные автоматические, объявленные внутри функции и не сохраняющие своих значений. Переменные (1) компилятор размещает в SRAM. Слово register конкретным компилятором для глобальных переменных не будет удовлетворено, так как неизвестно, что с этими регистрами сделают другие функции. Для размещения глобальной переменной в регистре есть опция конкретного компилятора lock registers и ключевое слово __regvar (см. документацию). Залочив несколько регистров (то есть, зарезервировав их под статические переменные), вся программа и используемые библиотеки должна быть откомпилирована с такой же опцией, иначе на стадии линковки будет ошибка. Есть еще вариант размещения констант в памяти программ - const __flash, но это не относится к изменяемым переменным. Кстати, зарезервировать регистры под переменные мало: надо еще и явно разместить их там (см. документацию). Иначе будет только хуже или, как минимум, не лучше. А хуже потому, что компилятор ограничен в использовании всех свободных регистров, а если там ничего не разместили, то выигрыша не будет. Не все переменные следует делать регистровыми - это зависит от их использования, надо пробовать. Иногда на одной переменной выигрыш десятки байтов, на другой - почти ничего, а на третьей получаем даже проигрыш. Локальные статические переменные (2) компилятор также размещает в SRAM (из ответа можно понять, что нет). Отличие от (1) - только в области видимости (конкретная функция). Все справедливо и в отношении игнорирования слова register. __regvar использовать, скорее всего, тоже не удастся: насколько помню, компилятор допускает его применение только для глобальных переменных. Почему обращение к локальным static менее эффективно, чем к глобальным - не скажу, не видя фрагмента кода. Локальные автоматические переменные (3) - вот тут возможны варианты. Классически эти переменные размещаются в стеке, расположенном тоже в SRAM. Однако в данном случае компилятор и без всяких слов register будет пытаться разместить максимум автоматических переменных в регистрах. Сохранять их между вызовами не нужно, а есть достаточное количество регистров, которые функция может использовать и не обязана сохранять (см. документацию). Работа с регистрами обычно эффективнее, это верно. Но использовать минимум глобальных переменных рекомендуют вовсе не по этой причине, а из соображений стиля программирования и читабельности программ. Остальное более-менее вторично и зависит от конкретных особенностей компилятора. Тут есть много нюансов. Например, единственный вызов функции без параметров, занимающий слово (2 байта) может очень неслабо увеличить размер некоей функции. Почему? А потому что вызванная функция может использовать половину регистров, и весь выигрыш от размещения локальных auto переменных в регистрах будет съеден необходимостью их сохранить перед этим вызовом, а потом восстановить. Почему компилятор использует обращение через "указатель"? Ряд команд специально сделан для работы с индексированными данными. Например, в регистровую пару Z может быть загружен начальный адрес структуры, а потом к ее членам можно обращаться одной командой через Z+смещение. Компактно и удобно. Этот прием компилятор может использовать и для доступа к локальным переменным, и для глобальных с целью экономии кода. Насчет сложного кода в выражениях: заочно ответить нельзя. В таких случаях надо писать иначе: вот фрагмент 1 (кусок кода), вот фрагмент 2 (кусок кода). Первый занимает на 20 байтов больше. В чем причина? Иногда ответить на этот вопрос вообще нельзя, не видя описания переменных и т.п. Часто просто удобнее писать по частям, заводя по ходу дела промежуточные переменные. Не следует беспокоиться: при высоких уровнях оптимизации компилятор так или иначе не будет хранить то, что дальше по тексту не требуется. А читабельность это может поднять. Про массивы в прерывании. То же самое. Не видя кода, нельзя сказать, почему компилятор "ругается". Как минимум, следует указывать сообщение об ошибке. А сэкономить можно много как. Например, объявить таблицу как const __flash, разместив ее тем самым не в SRAM (которое заполняется кодом инициализации из того же flash при запуске программы), а непосредственно во flash. Правда, доступ будет чуть сложнее, но зато таблица не займет оперативной памяти, что иногда важнее. А, кстати, а как на самом деле объявлялась таблица внутри? Надеюсь, что static? Иначе бедному компилятору пришлось бы ее инициализировать при каждом входе в функцию... Может, это и не понравилось? В общем, код в студию. 11 байт: то же самое. Бесцельно компилятор не выделяет лишние байты в конце. Причина обычно всегда есть. Но без фрагмента текста понять ее сложно. Мало кто на этом форуме умеет гадать на кофейной гуще Цитата(SasaVitebsk @ Mar 17 2006, 21:38)  Цитата(Old1 @ Mar 17 2006, 22:53)  Компилятор глобальные переменные по умолчанию помещает в SRAM
Компилятор в любом случае помещает эти переменные в SRAM. Но в первом описанном случае помещает ещё и указатели на эти переменные. Ну и обращается к ним ... соответственно. Компилятор не помещает их в SRAM, если явно указано, например, char __regvar __noinit c @ 15; При этом глобальная переменная c будет размещена не в SRAM, а в регистре, который мы обязаны залочить на уровне всего проекта опцией компилятора или IDE. Тут ответ был совершенно правильный. А размещать для статических переменных еще и указатели на них, помимо самих переменных... помилуйте, ради чего? Повторю, что не видя конкретного кода в конкретном контексте, сказать на 100% просто невозможно, можно лишь гадать.
|
|
|
|
Сообщений в этой теме
SasaVitebsk Новичок на С Feb 7 2006, 21:56 Pat Цитата(SasaVitebsk @ Feb 7 2006, 23:56) 2... Feb 7 2006, 22:48 defunct Цитата(SasaVitebsk @ Feb 7 2006, 23:56) 1... Feb 7 2006, 23:04 SasaVitebsk Спасибо всем за ответы и присланные примеры. Ещё б... Feb 8 2006, 01:40 defunct Цитата(SasaVitebsk @ Feb 8 2006, 03:40) 1... Feb 8 2006, 02:50  dxp Цитата(defunct @ Feb 8 2006, 08:50) Компи... Feb 8 2006, 07:07 Pyku_He_oTTyda ЦитатаСкачал PDFы и сделал книжечки
Не поделитесь,... Feb 8 2006, 05:29 Эрик SasaVitebsk!
Я тоже начал осваивать IAR Embed... Feb 8 2006, 10:02 _artem_ По пункту 3 :
Предполагаю что setjmp запоминает ре... Feb 8 2006, 12:47 Rst7 Цитата(_artem_ @ Feb 8 2006, 14:47) По пу... Feb 8 2006, 13:17 defunct Цитата(Rst7 @ Feb 8 2006, 15:17) Гм, да м... Feb 8 2006, 22:45 dxp Цитата(defunct @ Feb 9 2006, 04:45) Вопро... Feb 9 2006, 06:10 Rst7 Цитата(defunct @ Feb 9 2006, 00:45) Тогда... Feb 9 2006, 08:22  defunct Цитата(Rst7 @ Feb 9 2006, 10:22) Теперь п... Feb 9 2006, 11:55   Rst7 Цитата(defunct @ Feb 9 2006, 13:55) Хорош... Feb 9 2006, 12:56    defunct Цитата(Rst7 @ Feb 9 2006, 14:56) Можно, о... Feb 9 2006, 13:42 SasaVitebsk Ещё раз спасибо всем ответившим.
Перевариваю.
... Feb 9 2006, 11:56 SasaVitebsk По ходу написания возникло ещё несколько вопросов,... Feb 14 2006, 00:12 vet 1) Не рекомендуется использовать динамическое выде... Feb 14 2006, 06:28 IgorKossak SasaVitebsk, если Вы склоняетесь к п. 1).б), то Ва... Feb 14 2006, 07:30 SasaVitebsk Цитата(vet @ Feb 14 2006, 10:28) 1) Не ре... Feb 14 2006, 19:40 IgorKossak Цитата(SasaVitebsk @ Feb 14 2006, 21:40) ... Feb 16 2006, 09:30 SasaVitebsk Спасибо, попробую разные варианты и доложу как пол... Feb 16 2006, 17:30 SasaVitebsk 1) Насколько я понял запись типа " *str++ ... Feb 20 2006, 22:39 dxp Цитата(SasaVitebsk @ Feb 21 2006, 04:39) ... Feb 21 2006, 11:36 IgorKossak Цитата(SasaVitebsk @ Feb 21 2006, 00:39) ... Feb 21 2006, 17:14 SasaVitebsk Цитата(dxp @ Feb 21 2006, 15:36) Вопрос н... Feb 21 2006, 17:16 dxp Цитата(SasaVitebsk @ Feb 21 2006, 23:16) ... Feb 22 2006, 08:13 SasaVitebsk DXP ты всё правильно понимаешь, но я писал на ASMе... Mar 1 2006, 11:07 dxp Цитата(SasaVitebsk @ Mar 1 2006, 17:07) Т... Mar 1 2006, 14:04  defunct Цитата(dxp @ Mar 1 2006, 16:04) Во-первых... Mar 1 2006, 18:26   IgorKossak Цитата(defunct @ Mar 1 2006, 20:26) Цитат... Mar 1 2006, 18:33    dxp Цитата(IgorKossak @ Mar 2 2006, 00:33) Ци... Mar 3 2006, 05:30  SasaVitebsk Цитата(dxp @ Mar 1 2006, 18:04) Во-первых... Mar 2 2006, 18:13   Balaganov Цитата(SasaVitebsk @ Mar 2 2006, 20:13) v... Mar 2 2006, 20:48   dxp Цитата(SasaVitebsk @ Mar 3 2006, 00:13) b... Mar 3 2006, 05:43 vet Нет, идентификатор массива сам является указателем... Mar 1 2006, 11:24 vet ЦитатаВо вторых если я хотел сделать массив указат... Mar 2 2006, 18:19 SasaVitebsk отсутствует ...\avr\bin\nwtdavr.dll... Mar 3 2006, 09:53 dxp Цитата(SasaVitebsk @ Mar 3 2006, 15:53) о... Mar 3 2006, 10:57 appsoft Сообщение об отсутствии nwtdavr.dll наблюдал в рез... Mar 3 2006, 11:10 SasaVitebsk Цитата(SasaVitebsk @ Feb 14 2006, 23:40) ... Mar 5 2006, 16:22 beer_warrior KomG->Pict это уже сам по себе указатель т.е. з... Mar 5 2006, 17:28 SasaVitebsk Пользуюсь книгой Шилдт"Полный справочник по С... Mar 5 2006, 21:23 vet Так и нужно. Можно без скобок. Mar 5 2006, 21:49 SasaVitebsk "vet" твой ответ добавил мне уверенности... Mar 5 2006, 22:20 defunct Цитата(SasaVitebsk @ Mar 6 2006, 00:20) И... Mar 6 2006, 00:36 SasaVitebsk Чувствую, что я скоро всем надоем, и отвечать мне ... Mar 7 2006, 01:26 defunct Цитата(SasaVitebsk @ Mar 7 2006, 03:26) М... Mar 7 2006, 02:18 dxp Цитата(SasaVitebsk @ Mar 7 2006, 07:26) Е... Mar 7 2006, 04:51 osnwt Цитата(SasaVitebsk @ Mar 7 2006, 03:26) И... Mar 7 2006, 20:56  defunct Цитата(osnwt @ Mar 7 2006, 22:56) Код ret... Mar 7 2006, 22:22   osnwt Цитата(defunct @ Mar 8 2006, 00:22) Цитат... Mar 7 2006, 22:41    osnwt ЦитатаЯ вот тут подумал, чем надеяться на оптимиза... Mar 8 2006, 11:27     defunct Цитата(osnwt @ Mar 8 2006, 13:27) Увы, не... Mar 8 2006, 12:31      osnwt Цитата(defunct @ Mar 8 2006, 14:31) После... Mar 8 2006, 13:59 SasaVitebsk Беседа была интересная. И я планирую проверить н... Mar 11 2006, 17:24 osnwt Если вопросы ко мне - попробую ответить.
Цитата(S... Mar 11 2006, 19:47 beer_warrior ЦитатаТретий. Насколько сложно программу написанну... Mar 11 2006, 21:51 osnwt Цитата(beer_warrior @ Mar 11 2006, 23:51)... Mar 11 2006, 22:05 defunct Цитата(SasaVitebsk @ Mar 11 2006, 19:24) ... Mar 11 2006, 23:51 osnwt Цитата(defunct @ Mar 12 2006, 01:51) Я бы... Mar 12 2006, 01:38  defunct Цитата(osnwt @ Mar 12 2006, 03:38) Кроме ... Mar 12 2006, 01:53   osnwt Цитата(defunct @ Mar 12 2006, 03:53) Цита... Mar 12 2006, 14:23 beer_warrior 2 osnwt
ЦитатаКак пояснил Кристиан, gcc не рассчит... Mar 12 2006, 11:23 SasaVitebsk Похоже даже максимального уровня оптимизации мне б... Mar 16 2006, 21:19 vet Цитата(SasaVitebsk @ Mar 17 2006, 00:19) ... Mar 16 2006, 22:21 osnwt Цитата(SasaVitebsk @ Mar 16 2006, 23:19) ... Mar 17 2006, 10:53 beer_warrior Цитатапочему компилятор так упорно применяет коман... Mar 16 2006, 21:55 alekseykoj У IAR синтаксис обычный для языка С. Т.е описание ... Mar 17 2006, 14:19 osnwt Цитата(alekseykoj @ Mar 17 2006, 16:19) У... Mar 17 2006, 14:41 SasaVitebsk Цитата(Old1 @ Mar 17 2006, 22:53) Компиля... Mar 17 2006, 19:38 SasaVitebsk osnwt спасибо за расширенный ответ. Детали и нюанс... Mar 19 2006, 13:05 osnwt Цитата(SasaVitebsk @ Mar 19 2006, 15:05) ... Mar 19 2006, 14:32  osnwt Цитата(osnwt @ Mar 19 2006, 16:32) *p++ (... Mar 19 2006, 18:38 defunct Как говорит уважаемый АП - лучше написать два раза... Mar 19 2006, 16:50 SasaVitebsk Я это обнаружил с самого начала, но решил посмотре... Mar 19 2006, 20:27 osnwt Цитата(SasaVitebsk @ Mar 19 2006, 22:27) ... Mar 19 2006, 23:04 SasaVitebsk Спасибо всем помогавшим. Сегодня в общих чертах пр... Mar 20 2006, 18:19 SasaVitebsk Подскажите спецы (IAR). Компилятор очищает перемен... Mar 22 2006, 10:48 SasaVitebsk Подскажите спецы (IAR). Компилятор очищает перемен... Mar 22 2006, 11:03 defunct __no_init ? Mar 22 2006, 11:17 SasaVitebsk Спасибо.
Сегодня ине глючит у меня. Поэтому топик ... Mar 22 2006, 12:29 defunct Цитата(SasaVitebsk @ Mar 22 2006, 14:29) ... Mar 22 2006, 13:09 SasaVitebsk Всё ещё сложнее чем Вы думаете. И вто же время д... Mar 22 2006, 20:42 defunct 1. избавляться от "дыр" в массиве можно ... Mar 22 2006, 21:37 SasaVitebsk В массиве только указатели на "команды".... Mar 23 2006, 21:39 defunct Цитата(SasaVitebsk @ Mar 23 2006, 23:39) ... Mar 23 2006, 23:30 SasaVitebsk Нашёл функцию "memcpy" скорее всего это ... Mar 24 2006, 14:42 osnwt Цитата(SasaVitebsk @ Mar 24 2006, 16:42) ... Mar 25 2006, 07:08 defunct /offtop
ЦитатаА всётаки что на счёт программы. Та... Mar 24 2006, 15:42 SasaVitebsk Цитата(defunct @ Mar 24 2006, 19:42) Как ... Mar 25 2006, 16:01 SasaVitebsk А вот вопрос для понимания. Почему компилятор сохр... Mar 27 2006, 10:07 beer_warrior Правильный ответ 2.
Индексной адресацией удобно бе... Mar 27 2006, 11:23 SasaVitebsk Такой вот вопрос:
При входе в подпрограмму передаю... Apr 2 2006, 09:42
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|