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

dxp

Свой
  • Постов

    4 564
  • Зарегистрирован

  • Посещение

  • Победитель дней

    14

Весь контент dxp


  1. Насчет обработки сигналов однозначно сказать нельзя, а вот управление объектами вполне себе вписывается в концепцию ОС+прикладной код. Ну, во-первых, есть ОS, а есть RTOS, которые суть подмножество более широкого понятия OS. И с RTOS все несколько не так, как принято считать - типа, ОС - неслабое нагромождение мегакода, непонятно зачем, непонятно как работающего. Почитайте книжку Ж.Лябрусса про uC/OS-II, мнение, скорее всего, изменится. Во-вторых, применимость OS вообще и RTOS в частности определяется не столько процессором, сколько прикладной задачей. Если есть возможность применять, то ОС (особенно с вытеснением) - большое удобство в работе, способ формализовать огранизацию потока управления программы и детерминировать время реакции на события (в случае выстесняющей). Если программер ленив, то ОС он пользоваться не будет, потому как, чтобы нормально работать с ОС, надо изучить ее особенности, принципы работы и проч., а ленивому - лень. :) А кто сказал, что этот АРМ большой? А вот Филипс делает АРМы (серия LPC) в копрусах LQFP48 (с шагом 0.5мм) и стоимостью меньше десяти зеленых, т.е. почти как какая-нить мегаАВР и заметно меньше упомянутых сигнальников. Осмелюсь предположить, что опасения необоснованы. Программа под RTOS работает на самом деле даже более надежно, т.к. используется проверенный многими реальными проектами код, взаимодействие между частями формализовано и реализовано на основе надежных, проверенных средств (семафоры и прочие средства межпроцессного взаимодействия). Скорость... Смотря, что имееть в виду под скоростью. Если подсчитывать такты от возниконовения запроса на прерывание до получения управления ISR'ом, то тут ОС не рулит. Но если речь идет о времени реакции на события и их обработку (подразумевая, что обработка события - относительно длительный процесс и не может быть размещен целиком внутри ISR), то вытесняющая RTOS порулит любую foreground-background (т.е. бесконечный цикл и ISR'ы) систему.
  2. IAR AVR 4.10A

    Обьясню - чем не нравится класс. 1 Как быть с внешними eeprom-ами ? Концепцию менять каждый раз ? Вдобавок, в некоторых проектах использовались оба типа. :huh: Какая разница? С внешним все равно не так работаете. И тут можно другую реализацию сделать. Впрочем, это к делу не относится. :) Да, переносимость - это единственное серьезное возражение, тут спорить не буду. Если она рулит, то деваться некуда. :) Но не удержусь от замечания, что С++ все больше и больше завоевывает позиции, и, как следствие, компиляторов тоже все больше и больше. Причем почти полноценных - с шаблонами, неймспейсами. Да нет вопросов - хочется располагать со смещением - располагайте. Хочется работать с отдельными байтами - пожалуйста, никто не запрещает. Я не понимаю, как это конфликтует с объявлением переменной с квалификатором __eeprom? Класс-то ведь не в EEPROM живет, он - в обычной памяти. А внутри него забиты адреса данных в EEPROM'е. Просто всю работу он инкапсулирует внутри себя. А данные создаете в EEPROM с помощью слова __eeprom с последующей инициализацией представления класса, где в конструкторе прописываете адреса на EEPROM. При этом нет проблем с созданием многобайтных типов (предположим, Вам понадобилось плавучку в EEPROM хранить или вообще разномастные данные - структуры). И полный статический (т.е. на этапе компиляции) контроль типов. Ну и распределяйте, никто не возражает. Только почему бы это не делать с помощью __eeprom. Речь о том, чтобы не лазить в EEPROM руками - для этого использовать интерфейсный объект. Но данные разместить (память выделить) отдельно руками, объявив все необходимое с помощью __eeprom, и проинициализировать интерфейсный объект адресами этих данных в EEPROM. Т.е. внутри класса должны быть указатели типа __eeprom typename *. Конструктор объекта должен требовать определенное количество и тип аргументов-адресов - если забудете что-то ему передать, компилятор ругнется. Безопасность использования выше. Дело не в том, что там было не полное определение реализации дано, а только идея. Дело в том, что согласно тому стилю, присущему С, в глобальной области видимости появится куча достаточно низкоуровневого кода (функции, переменные), работа с которыми, во-первых, неудобна (надо при работе постоянно держать в голове кучу левых сущностей), во-вторых, небезопасна (т.е. через некоторое время начинаешь забывать, что там к чему и легко что-то напутать). В случае класса вся работа сокрыта внутри - снаружи как раз простой и формализованный интерфейс - пользователь не видит всего этого внутреннего "ужаса" :), который не "грузит" ему мозги и не провоцирует на ошибки. :) К тому же, можно класс слелать шаблоном и не переписывать все это для разных типов. Один раз написал, и используй для разных типов. __eeprom тут попадает, как говорится, "в струю". :) В общем, не агитирую, по опыту знаю, это дело не нужное, т.к. каждый работает, опираясь на собственный опыт и знания. Но точку зрения изложил, может она послужит поводом где-то и пересмотреть позицию. :)
  3. Такие вещи (глобальное редактирование) выполняются там по схеме "выделяем-изменяем". Т.е. сначала надо выделить требуемые объекты, затем их все скопом можно изменить. Выделять можно: 1. руками индивидуально; 2. через Find Similar Objects - щелкаешь правой мышой на объекте, там появляется диалог, где выбираешь критерии. Важно не забыть внизу выставить нужные галки - главная тут "Select Objects" (он там может, например, не выделять найденные, а маскировать их). 3. Написать запрос (Query). Там для этого целый язык. Каким способом пользоваться, решать Вам. :) Первый подходит, когда надо пару-тройку объектов, находящихся в поле зрения, поменять. Второй - самый распространенный, - имхо, в Вашем случае он рулит. Встаешь на метку, щелкаешь правой мышой, там в критериях указываешь в поле Text значение Same. И галку Select не забыть выставить. И Scope = Currrent Document (а то он там - "...размахнись плечо, раззудись рука..." - может и сразу эн документов в оборот взять. :) ) Третий - когда надо что-то выделить по сложным условиям. Раньше я им еще пользовался, но теперь в DXP2004SP2 появилось глобальное редактирование пользовательских параметров, оно стало не так актуально. Теперь, после того, как выделили нужные объекты, запускаем Inspector (хоткей F11 по умолчанию), там вбиваем новое значение параметра. Все. :) По этой схеме там все и редактируется. Любые объекты, любые параметры. Просто и единообразно.
  4. IAR AVR 4.10A

    А чем не нравится класс? И чем это лучше? Неслабое нагромождение кода в глобаном scope. В то время как, написав класс, где для вашей переменной объявить массив копий в EEPROM, который и обслуживать: class TMyEEPROM_Var { public: TMyEEPROM_Var(); TMyEEPROM_Var(typename x); ... // остальной интерфейс private: __eeprom typename CopyArray[N]; }; Тут уж и проверки сделать при обращениях, и журналирование, и все необходимые операции определить. Т.ч. снаружи это будет просто как обычная переменная. А если уж хочется и отдельные копии смотреть, то и для них функцию определить - типа: typename TMyEEPROM_Var::get_copy(byte intex) { return CopyArray[intex]; } Но обращаться именно в EEPROM посредством __eeprom. Только это будет тоже скрыто внутри класса. А функции явные ee_read, ee_write - это явно излишне. :)
  5. Правильное желание. :) У, тут не с этого надо начинать. Начинать надо с изучения С. Взять для начала классиков "Язык программирования С" Ричи и Кернигана. Нормальный "боевой" код обычно пишут так, чтобы он был самодокументированным. Т.е. комментарии там ставят обычно для пояснения неочевидных моментов. Остальной код и так должен хорошо читаться - это же не ассемблер. :) Работа с портами и битами на С делается очень просто: порт - это, обычно, просто объект в памяти. Синтаксически работа с портом выглядит точно так же, как и работа с любой переменной. Например: P5OUT = 0x01; // загрузить в порт P4OUT |= 0x80; // установить в 1 старший бит порта P3OUT &= ~0x01; // установить в 0 младший бит порта Выражение P1IN & 0x02 возвращает 0 если второй бит в порту был равен 0 и число 0x02 в противном случае. Т.е. все просто. Другое дело, что порты - это не простая память, они, обычно, обладают свойством быть асинхронно изменяемыми (аппаратурой процессора), поэтому тут возможны грабли с оптимизацией. Для подавления оной порты обычно объявляются с квалификатором volatile (все это уже сделано прямо в заголовочных файлах, поставляемых в составе пакета)... Про саму volatile читайте в книжках, там все написано. Нормальные там примеры, они, как раз, иллюстрируют основные операции при работе с периферией - настройка, управление. А чего Вы хотите? В общем, хочется посоветовать в первую очередь обратить внимание на сам язык, его концепции, подходы - т.е. используемые парадигмы программирования. Когда эти вещи достигнут определенного уровня понимания, все станет на свои места. Уж работа с портами и битами вопросов вызывать точно не будет. :)
  6. Еще вдогонку (2 TriD) Еще в этом случае можно просто пропустить сообщения: пока просматривал новые, пришли еще более новые, а ты вышел и сказал, что "отметить все форумы прочитанными" - тогда он и новые пометит, как прочитанные, и ты об этом ничего не узнаешь. Это не есть гуд.
  7. А он новые сообщения показывает только из подписанных форумов или из всех?
  8. IAR AVR 4.10A

    У Вас типичная ошибка этапа проектирования: Вы неправильно выбрали тип для реализации требуемой Вам функциональности. enum тут не подходит. Если Вам нужно просто целое, то и используйте его. Если Вам не нравится, то целое - голое, без "обвески", то приделайте обвеску - напишите класс. Типа: class TSlon { public: TSlon() : Value(0) { } TSlon(int x) : Value(x) { } TSlon(const TSlon& x) : Value(x) { } void Increase() { Value++; if(Value > MAX_VAL) Value = 0; } // wrap around void Decrease() { Value--; if(Value < 0) Value = MAX_VAL; } // wrap around } void operator ++() { Increase(); } void operator --() { Decrease(); } operator int() { return Value; } ... // остальной интерфейс, если он требуется private: int Value; } Тут у вас будет максимум и там, и там. И производительность максимальная, и безопасность использования. Вообще-то, С++ для этого и придуман - чтобы сочетать скорость С с безопасностью и удобством более высокоуровевых языков. P.S. Вообще-то, интерфейсы с меню не так пишутся. Там удобно использовать иерархию полиморфных классов и виртуальные функции. Получается удобно, быстро, безопасно и расширяемо. P.P.S. И ничего не мешает делать так, как делали на прежнем пакете - включите С режим (не используйте ключи --ec++/--eec++) и будет вам щастье :), можете мучить этот енум как заблагорассудтся. Только уже если что, не компилятор не пеняйте. :)
  9. Вдобавок к Телесистемам и Электрониксу еще фидошные эхи посредством ньюсов (т.е. через newsgroups). Достоинства: удобный софт (писать сообщение в редакторе а-ля Бат все же удобнее, чем в мелком окошке формы. Плюс квотинг более простой, оперативный, наглядный и удобный), простота обслуживания - сказал синхронизовать и все. После только читай новые сообщения. Сообщения скачиваются на локальную машину, поэтому удобно пользоваться тем, у кого диалап. Трафик очень небольшой, для тех кому критично, тоже арумент. Открытость - согласно правилам фидоэх подписчики должны именоваться своими именами, а не никами. Это вносит больше порядка, дисциплинирует и позволяет "знать своих героев". Недостатки: интерфес сугубо текстовый, никакой графики нет. Проблемы с приаттачиванием файлов к сообщениям, посылаемым через инет - гейт это режет. Есть некоторый барьер с настройкой софта, который отсекает часть народу, поэтому контингент там почти стабилен. Есть некоторые тормоза со стороны ФИДО - там почта ходит по своим законам, и порой может ходить долго не понятно по каким причинам. Со стороны инета (через гейт, т.е.) все ходит бодро - оперативность сравнима с Телесистемами. Кстати, попутно хотел спросить у местных завсегдатаев совета, как лучше организовать работу с местными форумами? Форумов много, сообщений тоже прилично, все в разных местах. С одной стороны это хорошо - структурировано, порядку больше, с другой отлавливать руками довольно трудоемко и неудобно. Вот есть как бы два полюса: один - это форум на Телеситемах, где все в кучу свалено. Там хорошо, когда собщения максимально короткие, т.е. общение идет в виде чата (лучше всего, когда любое сообщение умещается в одно-двухстрочный заголовок). Но обратная сторона этого - ничего серьезно обсуждать невозможно. Другой полюс - фидоэхи/ньсгруппы. Там наоборот - все внутри сообщений, а заголовок (тема сообщения) служит для объединения в треды. По мне, удобнее всего сделано именно там: можно указать, чтобы прочитанные сообщения вообще не показывать, тогда после синхронизации видны только новые сообщения. Встаешь на сообщение, оно через некоторое время помечается, как прочитанное и в следущий раз не показывается. Т.е. все удобно выходит - ничего лишнего. Здесь я попытался тоже организовать подобно - подписался на несколько форумов, открываю страницу, где мои форумы, делаю обновление, оно показывает, которые обновились. Дальше иду по списку: открываю страницу с форумом, там открываю страницы с сообщениями. И тут есть два неприятных момента. Во-первых, как-то это все тяжеловесно. Во-вторых, если открыл страницу с сообщением, прочитал его и закрыл страницу, то она не маркируется как прочитанная. Для того, чтобы маркировалась, надо там внизу на кнопу "Ок" давить. Это как-то напрягает - забываешь об этом. Да и зачем специально на что-то нажимать, когда и так страницу открыли. В общем, посветуйте что-нить облегчающее жизнь. Опытом поделитесь, кто как делает?
  10. IAR AVR 4.10A

    Вам же совершенно правильно объяснили, что так делать в С++ нельзя. Перечислимый тип - он только представление имеет в виде целого, а суть у него иная. И идея, и реализация в С++ логичны. В отличие от С, где с enum'ом можно делать что угодно - какое вообще смысл в этом перечислении в С, не понятно! А в С++ объект перечислимого типа может принимать только значения своего типа. Прямое присвоение целого и арифметика запрещены. Сами посудите: вот есть у Вас enum TSlon { slon = 0, slonick = 3, mamont = 5 } Slon; Теперь Вы пишете: Slon = 2; Какому значению типа TSlon оно будет соответствовать? Правильно - несущетсвующему, т.е. налицо нарушение самой идеи перечислимого типа: ведь он только для того и заведен, чтобы создать и манагить некое подмножетство целых. Те, которые не описаны в нем, это невалидные значения. И компилятор при статическом контроле типов эффективно подавляет подобные ошибки. Аналогичная ситуация и с арифметикой - результат арифметической операции может порождать значение, отсутсвующее в перечислимом типе. Единственное, что enum связывает с преобразованиями типов и целыми - это неявное преобразование значения объекта перечислимого типа в целое. Если уж очень хоцца присвоить объекту enum'а целое. то можно пользоваться насильным приведением типа: Slon = (TSlon)2; Но применение явного приведения типа означает, что "компилятор в этом случае умывает руки и говорит: "Надеюсь, парень, ты знаешь, что делаешь!" (с). И вообще, как сказал один лобастый дядька, явное приведение типа обычно указывает на ошибку этапа проектирования. Т.е. в правильно спроектированном коде необходимости в использовании явного преобразования типа не возникает. Исключения составляют всякие низкоуровеневые вещи вроде работы с аппаратурой и прочие "финты ушами". Для того они и оставлены в языке. Но это не есть красивый правильный подход во всех остальных случаях. Привычка постоянно использовать явные преобразования - источник собственноручно разложенных граблей.
  11. К сожалению, это не всегда возможно. Иногда приходится на схемах что-то подписывать по-русски (в частности некоторые имена цепей на разъемах). Хотя сам я тоже не сторонник использования русского в САПР. И, например, в программах принципиально все комментарии пишу только по-аглицки. И стройнее получается, и проблем ни с кодировками, ни с тулзами нет. :)
  12. IAR AVR 4.10A

    Пользваться postlink'ом сегодня уже не рекомендуется. Это устаревшая тулза, оставленная только для совместимости. XLINK умеет выдавать все, что надо, как и было показано сообщением выше.
  13. Пардон, что вмешиваюсь, но timescale, AFAIK, имеет несколько опосредованное отношение к событиям и шагу моделирования. timescale задает просто размерность временнЫх единиц, используемых при симуляции (и дискретность отображения - то, что там через слэш пишется). А моделирование, по идее, в общем случае всегда получается event-driven - как и было уже сказано, cycle-driven есть частный случай. Т.е. симулятор всегда после события обновляет состояние моделируемой системы. А что там за событие - фронт ли клока или еще какое изменение - это уже другой вопрос. Кстати, ведь на симуляторе, будь он МоделСим или еще какой АктивХДЛ, :) можно моделировать и асинхронные системы. Тут cycle-driven вообще мимо. timescale же просто придает безликим цифрам #n более человеческий смысл - во временнЫх единицах.
  14. SignalTap - да, очень полезная вещь. А вот Memory Editor на деле мне не пригодился - он требует под себя один порт памяти. Т.е. если память используется в двухпортовом режиме, то приблуда эта бесполезна.
×
×
  • Создать...