Перейти к содержанию
    

Хорошо, имеется некая структура данных (массив и индексы), по сути в этой структуре хранится весь контекст приемника. В чем заключается сложность обращения к этой структуре из обработчика прерывания? Ни в чем. Непонятно для чего может потребоваться еще что-то сохранять, когда просто попав в обработчик прерывания можно работать непосредственно с этой структурой данных (не затрагивая других структур данных).

 

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

 

   for(;;)
   {
      task1();
      task2();
      task3();
    }

 

Аналогично - все превращается в автомат и совершенно не читабельно. Тем более, что эта программа (это стек TCP/IP) как понимаете не самоцель, а лишь маленькая часть большой программы, а вы предлагаете весь софт писать вот так?

 

ЗЫ Наверное, надо другую тему организовать под названием "Какие у сапожников взгляды на искусство" ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не все переменные превращаются в статические. Статическими будут только переменные, которые необходимо хранить между входами в обработчик прерывания. По расходу памяти если сравнить с Вашим способом - "те же консервы, вид сбоку" :)

 

Насчет улучшения читаемости - для кого? Углядеть алгоритм работы многозадачной системы - всегда сложнее чем однозадачной.

 

Аналогично - все превращается в автомат и совершенно не читабельно. Тем более, что эта программа (это стек TCP/IP) как понимаете не самоцель, а лишь маленькая часть большой программы, а вы предлагаете весь софт писать вот так?

я не предлагаю так писать софт, я его так пишу.

 

for{;;}

{

DispatchLalala();

KernelDispatchblablabla();

DoSomethingElse();

sleep();

}

 

 

ЗЫ Наверное, надо другую тему организовать под названием "Какие у сапожников взгляды на искусство" ;)

:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По ходу написания возникло ещё несколько вопросов, Вы уж извините.

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?

Если да, то как вводить/выводить на разные устройства в одном проекте? Короче чуствую что я не знаю целую глобальную область и это удручает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Не рекомендуется использовать динамическое выделение памяти в программе для м/к. Соответственно, и реализовано оно в известных мне компиляторах AVR весьма примитивно.

Времени выделение не занимает.

2) Это пишется так: tip1->TimeLife--;

3) Стандартный сишный ввод-вывод, незачем изобретать велосипед. И возможностей у него более чем достаточно.

Переписать нужно putchar/getchar.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SasaVitebsk, если Вы склоняетесь к п. 1).б), то Вам и вовсе незачем пользоваться динамической памятью, используйте статический массив.

По поводу printf/scanf, кроме того, что Вам посоветовал vet, можно ещё воспользоваться вариантом sprintf/sscanf и работать со стрингами в ОЗУ если не хотите переписывать putchar/getchar (т. к. устройства ввода\вывода могут быть разные).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Не рекомендуется использовать динамическое выделение памяти в программе для м/к. Соответственно, и реализовано оно в известных мне компиляторах AVR весьма примитивно.

Времени выделение не занимает.

 

Это понял. Спасибо.

 

2) Это пишется так: tip1->TimeLife--;

 

Это как раз понятно. А объявление я правильно сделал или правильнее как в коментарии?

Компилятор при таком объявлении займёт память или нет и как это посмотреть?

 

 

3) Стандартный сишный ввод-вывод, незачем изобретать велосипед. И возможностей у него более чем достаточно.

Переписать нужно putchar/getchar.

 

Это понял. Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2) Это пишется так: tip1->TimeLife--;

Это как раз понятно. А объявление я правильно сделал или правильнее как в коментарии?

Компилятор при таком объявлении займёт память или нет и как это посмотреть?

Как в комментарии лучше.

Когда делаете явное приведение, это больше для себя, чтобы в будущем не забыть что имелось в виду.

Компилятору всё равно (посмотреть можно в листинге или при отладке).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, попробую разные варианты и доложу как получилось лучше. :) Ничто не помогает узнать язык лучше, чем опыт и испытание разных вариантов. :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Насколько я понял запись типа " *str++ " говорит что "надо извлечь символ и сдвинуть указатель", а не "инкрементировать значение по адресу". Поправте если я ошибся.

2) Нашёл как передаются параметры, но пока не нашёл как они хранятся в памяти. Меня интересует short int хранится младшим байтом вперёд?

3) Если я планирую использовать крупные таблицы данных. 4 таблицы по 2-3 кб. Не хотелось бы их подключать в виде текстового массива-констант. Есть ли возможность подключить бинарный файл на этапе линковки? Как в данном случае определить и использовать адрес который получится на этапе линковки? Или может быть существует другой способ? Подскажите.

 

Заранее благодарен.

Изменено пользователем SasaVitebsk

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Насколько я понял запись типа " *str++ " говорит что "надо извлечь символ и сдвинуть указатель", а не "инкрементировать значение по адресу". Поправте если я ошибся.

Да.

 

2) Нашёл как передаются параметры, но пока не нашёл как они хранятся в памяти. Меня интересует short int хранится младшим байтом вперёд?

Вопрос непонятен. Параметры (аргументы функции) именно передаются, а не хранятся. Схемы есть разные, в версиях 1.хх была одна схема, начиная с 2.хх - другая. В ней, насколько помню, все, что влазит в 8 регистров с 16 по 23, передается в них (с учетом выравнивания, ессно), остальное через стек. Все это хорошо документировано.

 

3) Если я планирую использовать крупные таблицы данных. 4 таблицы по 2-3 кб. Не хотелось бы их подключать в виде текстового массива-констант. Есть ли возможность подключить бинарный файл на этапе линковки? Как в данном случае определить и использовать адрес который получится на этапе линковки? Или может быть существует другой способ? Подскажите.

Подключать бинарный файл можно, если он в формате UBROF. :) Как сделать этот UBROF - пути все те же: скомпилить из сорца. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3) Если я планирую использовать крупные таблицы данных. 4 таблицы по 2-3 кб. Не хотелось бы их подключать в виде текстового массива-констант. Есть ли возможность подключить бинарный файл на этапе линковки? Как в данном случае определить и использовать адрес который получится на этапе линковки? Или может быть существует другой способ? Подскажите.

Бинарный файл на этапе линковки можно подключить.

См. опции линкера Config\Raw binary image

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос непонятен. Параметры (аргументы функции) именно передаются, а не хранятся. Схемы есть разные, в версиях 1.хх была одна схема, начиная с 2.хх - другая. В ней, насколько помню, все, что влазит в 8 регистров с 16 по 23, передается в них (с учетом выравнивания, ессно), остальное через стек. Все это хорошо документировано.

 

Я имел ввиду не передачу функции данных в виде параметра, а хранение этих данных в озу. например если я использую адрес на int, то он укажет на младший или на старший байт?

В одном месте нашёл вариант сохранения структуры. Похоже младшим байтом вперёд. Ладно это проверим.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я имел ввиду не передачу функции данных в виде параметра, а хранение этих данных в озу. например если я использую адрес на int, то он укажет на младший или на старший байт?

В одном месте нашёл вариант сохранения структуры. Похоже младшим байтом вперёд. Ладно это проверим.

Указатель содержит адрес. Адрес - это просто местоположение в памяти. Обычно измеряется в байтах (8-битных). К размеру объекта, расположенного по адресу, сам адрес никакого отношения не имеет. К размеру имеет отношение тип указателя. Собственно, он (тип) для того и задается, чтобы компилятор мог правильно работать с объектом, адресуемым указателем. Для писания на С/С++, если не использовать хаки и всякие низкоуровневые финты ушами, а также если опустить вопросы отладки, ровно пофигу, как объекты располагаются в памяти физически. Комплятор их положил, пусть с ними разбирается. Конкретно EWAVR - да кладет объекты младшими байтами по младшим адресам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, идентификатор массива сам является указателем. Правильно будет {fnt0_6x8, fnt1_8x8, fnt2_10x10, fnt3_11x13};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...