|
|
  |
Новичок на С, Помогите разобраться со структурой проекта |
|
|
|
Feb 9 2006, 12:56
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата(defunct @ Feb 9 2006, 13:55)  Хорошо, имеется некая структура данных (массив и индексы), по сути в этой структуре хранится весь контекст приемника. В чем заключается сложность обращения к этой структуре из обработчика прерывания? Ни в чем. Непонятно для чего может потребоваться еще что-то сохранять, когда просто попав в обработчик прерывания можно работать непосредственно с этой структурой данных (не затрагивая других структур данных). Можно, однако это раздувает код, т.к. все локальные переменные превращаются в статические. А само сохранение регистров (и последующее восстановление) остается и никуда не девается. А так убиваем двух зайцев - код уменьшаем, улучшаем читаемость этого всего дела, т.к. весь алгоритм лежит последовательно, а не по кусочкам, выполнить то, выполнть это... Цитата Код for(;;) { task1(); task2(); task3(); } Аналогично - все превращается в автомат и совершенно не читабельно. Тем более, что эта программа (это стек TCP/IP) как понимаете не самоцель, а лишь маленькая часть большой программы, а вы предлагаете весь софт писать вот так? ЗЫ Наверное, надо другую тему организовать под названием "Какие у сапожников взгляды на искусство"
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Feb 9 2006, 13:42
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(Rst7 @ Feb 9 2006, 14:56)  Можно, однако это раздувает код, т.к. все локальные переменные превращаются в статические. А само сохранение регистров (и последующее восстановление) остается и никуда не девается. А так убиваем двух зайцев - код уменьшаем, улучшаем читаемость этого всего дела, т.к. весь алгоритм лежит последовательно, а не по кусочкам, выполнить то, выполнть это... Не все переменные превращаются в статические. Статическими будут только переменные, которые необходимо хранить между входами в обработчик прерывания. По расходу памяти если сравнить с Вашим способом - "те же консервы, вид сбоку"  Насчет улучшения читаемости - для кого? Углядеть алгоритм работы многозадачной системы - всегда сложнее чем однозадачной. Цитата Аналогично - все превращается в автомат и совершенно не читабельно. Тем более, что эта программа (это стек TCP/IP) как понимаете не самоцель, а лишь маленькая часть большой программы, а вы предлагаете весь софт писать вот так? я не предлагаю так писать софт, я его так пишу. for{;;} { DispatchLalala(); KernelDispatchblablabla(); DoSomethingElse(); sleep(); } Цитата ЗЫ Наверное, надо другую тему организовать под названием "Какие у сапожников взгляды на искусство" 
|
|
|
|
|
Feb 14 2006, 00:12
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
По ходу написания возникло ещё несколько вопросов, Вы уж извините. 1) Предположим у меня из rs232 в буффер грузятся различные структуры данных, их размер и тип определяются в момент загрузки. В процессе работы, обработанные структуры удаляются из буффера (удаляемая может находится внутри буфера). Я вижу два варианта работы с такими данными: а) Динамически размещаю каждую новую структуру и работаю с объявленными полями. Динамически удаляю. б) Один раз с пом. malloc выделить всю свободную память и работать с данными, как с байтами, производя преобразования на ходу вручную. Я как конченный ассемблерщик  склоняюсь конечно ко второму. Преимущество в простоте загрузки и очистки "мусора". Но прога в первом варианте будет выглядеть, по-моему, красивей.  Вопрос 1: Как много ресурсов будет зажирать постоянно дёргающиеся malloc/free. Будет ли эффективней работа со структурой. Вопрос 2: если я получаю адрес расположения структуры в указатель byte *Addr; и имею структуру типа описанной ниже. При этом я не хочу под неё выделять память. Я хочу иметь одну переменную-структуру и присвоить значение адреса чтобы иметь возможность работать с полями по законам соответствующей арифметики. Будет ли правильным такое объявление ... struct x1 { word TimeStart; // Время начала исполнения команды byte TimeMashtabTek, // Текущее значение масштаба для времени исполнения TimeMashtab; // Масштаб для времени исполнения word TimeLife; // Время исполнения команды с учётом масштаба int BegX,BegY, // Начало объекта (X,Y) SizeX,SizeY; // Размеры объекта (X,Y) signed char VecX,VecY; // вектор перемещения объекта (X,Y) } *tip1; ... и такая работа с ним. Если нет, то как сделать правильно tip1 = Addr; /* или типа ... "tip1 = (struct x1*) Addr; */ *tip1.TimeLife--; /* слово уменьшится на 1 */ Прошу не смейтесь, так как я плаваю и пока не "чуствую языка". 2) Что за всеобщая истерика с printf/scanf. Почему все так стремятся использовать эти процедуры? Что это даёт программисту (в смысле на микроконтроллере)? Если это действительно так важно, то как их использовать если поток I/O у тебя совершенно свой? В смысле есть ли какой нибудь Assign? Переписать Putc/Getc? Если да, то как вводить/выводить на разные устройства в одном проекте? Короче чуствую что я не знаю целую глобальную область и это удручает.
|
|
|
|
|
Feb 14 2006, 19:40
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(vet @ Feb 14 2006, 10:28)  1) Не рекомендуется использовать динамическое выделение памяти в программе для м/к. Соответственно, и реализовано оно в известных мне компиляторах AVR весьма примитивно. Времени выделение не занимает. Это понял. Спасибо. Цитата(vet @ Feb 14 2006, 10:28)  2) Это пишется так: tip1->TimeLife--; Это как раз понятно. А объявление я правильно сделал или правильнее как в коментарии? Компилятор при таком объявлении займёт память или нет и как это посмотреть? Цитата(vet @ Feb 14 2006, 10:28)  3) Стандартный сишный ввод-вывод, незачем изобретать велосипед. И возможностей у него более чем достаточно. Переписать нужно putchar/getchar. Это понял. Спасибо.
|
|
|
|
|
Feb 16 2006, 09:30
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(SasaVitebsk @ Feb 14 2006, 21:40)  Цитата(vet @ Feb 14 2006, 10:28)  2) Это пишется так: tip1->TimeLife--;
Это как раз понятно. А объявление я правильно сделал или правильнее как в коментарии? Компилятор при таком объявлении займёт память или нет и как это посмотреть? Как в комментарии лучше. Когда делаете явное приведение, это больше для себя, чтобы в будущем не забыть что имелось в виду. Компилятору всё равно (посмотреть можно в листинге или при отладке).
|
|
|
|
|
Feb 21 2006, 11:36
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(SasaVitebsk @ Feb 21 2006, 04:39)  1) Насколько я понял запись типа " *str++ " говорит что "надо извлечь символ и сдвинуть указатель", а не "инкрементировать значение по адресу". Поправте если я ошибся. Да. Цитата(SasaVitebsk @ Feb 21 2006, 04:39)  2) Нашёл как передаются параметры, но пока не нашёл как они хранятся в памяти. Меня интересует short int хранится младшим байтом вперёд? Вопрос непонятен. Параметры (аргументы функции) именно передаются, а не хранятся. Схемы есть разные, в версиях 1.хх была одна схема, начиная с 2.хх - другая. В ней, насколько помню, все, что влазит в 8 регистров с 16 по 23, передается в них (с учетом выравнивания, ессно), остальное через стек. Все это хорошо документировано. Цитата(SasaVitebsk @ Feb 21 2006, 04:39)  3) Если я планирую использовать крупные таблицы данных. 4 таблицы по 2-3 кб. Не хотелось бы их подключать в виде текстового массива-констант. Есть ли возможность подключить бинарный файл на этапе линковки? Как в данном случае определить и использовать адрес который получится на этапе линковки? Или может быть существует другой способ? Подскажите. Подключать бинарный файл можно, если он в формате UBROF.  Как сделать этот UBROF - пути все те же: скомпилить из сорца.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Feb 21 2006, 17:16
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(dxp @ Feb 21 2006, 15:36)  Вопрос непонятен. Параметры (аргументы функции) именно передаются, а не хранятся. Схемы есть разные, в версиях 1.хх была одна схема, начиная с 2.хх - другая. В ней, насколько помню, все, что влазит в 8 регистров с 16 по 23, передается в них (с учетом выравнивания, ессно), остальное через стек. Все это хорошо документировано. Я имел ввиду не передачу функции данных в виде параметра, а хранение этих данных в озу. например если я использую адрес на int, то он укажет на младший или на старший байт? В одном месте нашёл вариант сохранения структуры. Похоже младшим байтом вперёд. Ладно это проверим.
|
|
|
|
|
Feb 22 2006, 08:13
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(SasaVitebsk @ Feb 21 2006, 23:16)  Я имел ввиду не передачу функции данных в виде параметра, а хранение этих данных в озу. например если я использую адрес на int, то он укажет на младший или на старший байт? В одном месте нашёл вариант сохранения структуры. Похоже младшим байтом вперёд. Ладно это проверим. Указатель содержит адрес. Адрес - это просто местоположение в памяти. Обычно измеряется в байтах (8-битных). К размеру объекта, расположенного по адресу, сам адрес никакого отношения не имеет. К размеру имеет отношение тип указателя. Собственно, он (тип) для того и задается, чтобы компилятор мог правильно работать с объектом, адресуемым указателем. Для писания на С/С++, если не использовать хаки и всякие низкоуровневые финты ушами, а также если опустить вопросы отладки, ровно пофигу, как объекты располагаются в памяти физически. Комплятор их положил, пусть с ними разбирается. Конкретно EWAVR - да кладет объекты младшими байтами по младшим адресам.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Mar 1 2006, 11:07
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
DXP ты всё правильно понимаешь, но я писал на ASMе даже для IBM, поэтому писать "без финтов ушами" ещё надо научиться.  А надо. Очень надо. Я хочу чтобы прога получилась минимально зависима от кристала. Теперь новый вопрос. Если Вы не возражаете. Я хочу во флеш разместить несколько массивов. И масив указателей на эти массивы. Вот такое объявление будет правильным? Если нет, то как? const byte __flash fnt0_6x8[224] = { .... }; const byte __flash fnt1_8x8[224] = { .... }; const word __flash fnt3_10x10[224] = { .... }; const word __flash fnt3_11x13[224] = { .... }; const void __flash *symbol[3] = {&fnt0_6x8,&fnt1_8x8,&fnt2_10x10,&fnt3_11x13};
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|