реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Таблица переходов вместо Switch, Keil Си
Dog Pawlowa
сообщение Mar 23 2010, 22:02
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(AHTOXA @ Mar 24 2010, 01:54) *
Это отличный вариант, пока все обработчики хранятся в одном файле.

Ну почему, они отлично подключаются через заголовочные файлы.
Но автоматически не добавляются, ага.
Может это и хорошо? wink.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Mar 27 2010, 05:48
Сообщение #17


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(AndreyS @ Mar 23 2010, 23:10) *
оптимхизация включена (какой уровень сейчас не скажу да это и не важно).
...
Нахрена такая таблица я не понял. Компактно - да, быстро - нет.

Как это не важно?
У Вас какой режим оптимизации включен, по размеру или по времени?
А если по размеру? Вот он вам такой код и генерит.
Поставте О3, и включите опцию оптимизации по времени.
Возможно, и не понадобится вся эта канитель, что тут развели smile.gif
Go to the top of the page
 
+Quote Post
AndreyS
сообщение Mar 29 2010, 08:32
Сообщение #18


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Цитата(sonycman @ Mar 27 2010, 09:48) *
Как это не важно?
У Вас какой режим оптимизации включен, по размеру или по времени?
А если по размеру? Вот он вам такой код и генерит.
Поставте О3, и включите опцию оптимизации по времени.
Возможно, и не понадобится вся эта канитель, что тут развели smile.gif



Добрый день.

Тип оптимизации по времени с повторным использованием одинакового куска кода (сворачиват повторения в процедуры).

А канитель эта по любому нужна wink.gif


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 4 2010, 23:56
Сообщение #19


кекс
******

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



Цитата(AndreyS @ Mar 23 2010, 22:10) *
Теперь я создал например обработчик 10-го позиционного номера таблицы. И хочу что бы компилятор в таблице заменил адрес 10 ячейки этой таблицы. На асме я это регулировал оргом, тут с _at_ такая штука не проходит. а нужно мне это для дополнения обработчиков. Ну всего 256 комбинаций (у меня байт проверяется), из них 200 определено. И вот хочу еще 2 определить, что бы не искать позицию в таблице, я хотел что бы компилятор (по моему указанию) высчитал позицию адреса в таблице и туда этот адрес положил. А как вызвать функию по адресу из этой таблицы я знаю, спасибо.


А что мешает просто красиво задать массив, - с одной функцией в одной строке и коментарием в конце строки, который будет указывать номер текущей позиции:

Код
void CommonHandler()
{
}

void GetTimeHander()
{
  ...
}

void (*Handlers[])(void) =
{
    CommonHandler,      // 0
    CommonHandler,      // 1
    CommonHandler,      // 2
    CommonHandler,      // 3
    GetTimeHandler,     // 4
    CommonHandler,      // 5
...
    CommonHandler,      // 55
    CommonHandler,      // 56
    CommonHandler,      // 57
...
    CommonHandler,      // 254
    CommonHandler       // 255
};

И вручную следить за чистотой этого массива. Найти место для пары новых обработчиков когда все в чистоте не составит никакой сложности. Да и обратная операция - читать этот массив человеку который будет поддерживать код после вас будет легко, - ему не придется бегать к каждой функции и смотреть в какую позицию она загружена.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Apr 5 2010, 10:24
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(defunct @ Apr 5 2010, 02:56) *
А что мешает просто красиво задать массив, - с одной функцией в одной строке и коментарием в конце строки, который будет указывать номер текущей позиции:
...И вручную следить за чистотой этого массива.

Я делал так раньше, неудобно - слишком много переименовывать.
Как раз на днях заказчик попросил поменять последовательность функций в менюшке. Одно дело перетасовать имена функций, другое дело отслеживать физические индексы. Не говоря уже о том, чтобы добавить раздел в меню.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
RobFPGA
сообщение Apr 5 2010, 20:36
Сообщение #21


Профессионал
*****

Группа: Свой
Сообщений: 1 214
Регистрация: 23-12-04
Пользователь №: 1 643



Приветствую!


Цитата(AHTOXA @ Mar 24 2010, 00:54) *
Это отличный вариант, пока все обработчики хранятся в одном файле. Но иногда (часто) нужно, чтоб модуль при подключении автоматически добавлял свой элемент в таблицу. В случае фиксированной таблицы (с известным заранее числом элементов, типа таблицы векторов прерываний) - можно применить вариант, который я привёл. А вот для произвольной таблицы - я так ничего путного и не придумал.
А как было бы здорово, если бы модуль (.c файл) мог при его добавлении в проект, скажем, автоматически добавить несколько своих терминальных команд, пару переменных в конфиг, етцsmile.gif
Придумалось только для плюсов, через смесь шаблонов и макросов. Да и то не всё там гладко, накладные расходы по ОЗУ (не всё во флеше), и работоспособность зависит от порядка вызова глобальных конструкторов (не определён стандартом, емнимс).


Я похожее делал для определения набора переменных в flash. Структуры задающие переменные (в разных модулях) при определении назначались в именованный сегмент памяти. При линковке все что в этом сегменте было определено складывалось в одну большую таблицу начало и размер которой известны. Естественно положить таким образом указатель в определенную позицию в таблице нельзя.

Успехов! Rob/
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 6 2010, 01:40
Сообщение #22


кекс
******

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



Цитата(Dog Pawlowa @ Apr 5 2010, 13:24) *
Я делал так раньше, неудобно - слишком много переименовывать.
Как раз на днях заказчик попросил поменять последовательность функций в менюшке. Одно дело перетасовать имена функций, другое дело отслеживать физические индексы. Не говоря уже о том, чтобы добавить раздел в меню.

Если смотреть в контексте использования для какого-то протокола из-вне (модбас / мэк101 / 104 и т.п. много всяких у кого 256 функций), где функции (большинство их) жестко определены стандартом. То существенно менять ничего не придется, никто функции протокола менять не будет. Функции могут только неспешно добавляться как и отметил автор ветки.

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

вместо таблицы голых функций.
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 03:05
Сообщение #23


Adept
******

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



Цитата(AHTOXA @ Mar 24 2010, 04:54) *
работоспособность зависит от порядка вызова глобальных конструкторов (не определён стандартом, емнимс).

С этим можно побороться с помощью паттерна Singleton.

Код
//---------------------------------------------------------------------------
template<typename T> class singleton
{
public:
    static T& Instance() { static T instance; return instance; }
};
//---------------------------------------------------------------------------


Использование:

Код
class TSlon { ... };


TSlon& slon = singleton<TSlon>::Instance();

// далее идет использование слона (синтаксически как обычный объект):
// при создании ссылки внутри singleton<TSlon> будет
// статически создан и проинициализирован объект внутри Instance(), поэтому
// ссылку можно безопасно использовать

Есть небольшие накладняки на создание статического объекта, но они небольшие - соизмеримы с вызовом конструктора. Работает этот прием очень хорошо.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Apr 6 2010, 07:02
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(defunct @ Apr 6 2010, 04:40) *
А для меню думаю куда удобнее и нагляднее ...

А я не исключаю включение в массив дополнительно к указателям на функции вспомогательной информации. Но для меня реализация всего интерфейса пользователя как единого автомата состояний получается гораздо прозрачнее и удобнее. Законченный фрагмент исходника должен поместиться на экране. Меньше ссылок, больше прямых действий. От "глобальной" индесации массива функций [state][event] я сделал шаг назад, к function[state].
Впрочем, я уже о своем, наболевшем - не перебдеть в структурировании smile.gif


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 07:45
Сообщение #25


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 09:05) *
Код
// при создании ссылки внутри singleton<TSlon> будет
// статически создан и проинициализирован объект внутри Instance(), поэтому
// ссылку можно безопасно использовать


А чем нам поможет замена глобального объекта на глобальный статический? В плане руления порядком вызова конструкторов? То есть, чем это отличается от простого объявления
Код
TSlon slon;
?
Имхо, без динамического создания объектов singleton совершенно бесполезен.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 11:14
Сообщение #26


Adept
******

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



Цитата(AHTOXA @ Apr 6 2010, 14:45) *
А чем нам поможет замена глобального объекта на глобальный статический? В плане руления порядком вызова конструкторов? То есть, чем это отличается от простого объявления

Вот зрасьте! В этом же вся фишка синглтона. Когда какой-то объект нуждается в объекте TSlon, то он создает (использует) ссылку, возвращаемую функцией Instance() шаблона singleton. А ссылка эта ссылается на статический объект, создаваемый внутри фукнции-члена Instance(). Таким образом, получается следующая схема: при первом вызове Instance() будет создан и проинициализирован статический объект требуемого типа (в нашем примере TSlon), все последующие вызовы будут возвращать ссылку на уже существующий объект. И не важно, кто первый дернул Instance(), думать об этом не надо. В этом и избавление от зависимости от порядка вызова конструкторов.

Цитата(AHTOXA @ Apr 6 2010, 14:45) *
Код
TSlon slon;
?
Имхо, без динамического создания объектов singleton совершенно бесполезен.

Еще как полезен: объект создается как статический внутри статической же функции-члена Instance(). И живет там все время, пока программа работает. Т.е. по сути как обынчый глобальный объект, но спрятанный внутри функции и предоставляющий доступ по ссылке (что синтаксически ровно как доступ к обычному объекту). Нету тут ни работы с кучей, ни выделения памяти на рантайме. Выделение памяти и инициализация производятся комилятором на основе правил языка в части статических объектов внутри функций (которые есть даже в голом С).


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 12:15
Сообщение #27


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 17:14) *
Вот зрасьте! В этом же вся фишка синглтона.


Упс. Я был уверен, что разница между статическим и глобальным объектом только в области видимости.
А ты хочешь сказать, что для статических объектов конструкторы вызываются не в списке глобальных конструкторов, а при первом вызове функции, в которой он содержится? Если так, то это супер! Надо проверитьsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 6 2010, 12:56
Сообщение #28


Adept
******

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



Цитата(AHTOXA @ Apr 6 2010, 19:15) *
А ты хочешь сказать, что для статических объектов конструкторы вызываются не в списке глобальных конструкторов, а при первом вызове функции, в которой он содержится? Если так, то это супер! Надо проверитьsmile.gif

Статический объект должен быть гарантировано проинициализирован до его использования. А где это делается - отдано на откуп реализации. Например:
Код
void f()
{
    int a = 10;
    ... // код функции
}

Реализация может быть разной. Самое простое - сунуть а в секцию, где помещаются глобальные переменные, и проинициализировать вместе с ними (IAR, помнится, так и делает) - разница тут будет только в области видимости. А можно тут вставить код, проверяющий первый вход в функцию, и вызывать инициализатор (это тот самый оверхед, про который я говорил, и который незначителен по сравнению с вызовом конструктора). Как делается реально в том или ином случае - это в ведении реализации (в случае с вызовом конструктора объекта пользовательского типа скорее всего делается по второму варианту). Главное, что поведение четко стандартизовано и это можно безопасно использовать.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Apr 6 2010, 17:57
Сообщение #29


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(dxp @ Apr 6 2010, 18:56) *
Главное, что поведение четко стандартизовано и это можно безопасно использовать.


Попробовал, получилось. Но далеко не сразу. Простая замена глобального объекта
Код
uart1_t uart1;

на ссылку:
Код
uart1_t& uart1 = singleton<uart1_t>::Instance();

Не прокатила. Потому что теперь вместо глобального объекта uart1 у нас получилась глобальная же ссылкаsmile.gif Порядок инициализации которой (на этот раз при помощи хитрого синглетона!) по прежнему не определён.
Пришлось везде, где используется uart1, заводить локальные переменные-ссылки
Код
uart1_t& localuart = singleton<uart1_t>::Instance();

и использовать их. Вот тогда всё заработало должным образомsmile.gif
Что касаемо накладных расходов, то они достаточно приличные:
Код
*с глобальным uart:
   text    data     bss     dec     hex filename
   4372       8    5792   10172    27bc ./exe/stm32-H103.elf
*с singleton<uart1_t>:
   text    data     bss     dec     hex filename
   4500       8    5800   10308    2844 ./exe/stm32-H103.elf

(Всё это gcc на stm32)

Я думаю, что для некоторых применений это хорошее решение, по крайней мере я намерен его применять.
(Или всё же new? smile.gif )


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 7 2010, 03:51
Сообщение #30


Adept
******

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



Цитата(AHTOXA @ Apr 7 2010, 01:12) *
Пришлось везде, где используется uart1, заводить локальные переменные-ссылки
Код
uart1_t& localuart = singleton<uart1_t>::Instance();

и использовать их. Вот тогда всё заработало должным образомsmile.gif

Конечно, именно так и надо делать, в этом и смысл. Точнее, глобальную ссылку завести тоже не лишне, но ее использовать по ходу программы, а вот в конструкторах - да, только локальные ссылки.

Цитата(AHTOXA @ Apr 7 2010, 01:12) *
Я думаю, что для некоторых применений это хорошее решение, по крайней мере я намерен его применять.
(Или всё же new? smile.gif )

Для new надо свой быстрый и не подверженный фрагментации менеджер памяти сделать. Если только для вышеописанных целей, то это будет еще больше накладных. А вообще такой мененжер памяти местами очень полезен. Надо будет сделать, как руки дойдут.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 13:38
Рейтинг@Mail.ru


Страница сгенерированна за 0.01527 секунд с 7
ELECTRONIX ©2004-2016