Jump to content

    

vshemm

Участник
  • Content Count

    167
  • Joined

  • Last visited

Community Reputation

0 Обычный

About vshemm

  • Rank
    Частый гость

Recent Profile Visitors

806 profile views
  • cpl

  1. Этот товарищ - Олег Цилюрик, на данном (и не только на данном) форуме известен под ником olej. ЕМНИП. Со всеми вытекающими.
  2. Да забудьте вы про системный тик :) Это всего лишь дополнительный периодический источник событий. Его может вообще не быть. В линуксе такая опция появилась в 2.6.16-17 ядре, т.е. много лет назад. Не говоря про другие системы. EDIT: вот неплохая отправная точка для гугления http://stackoverflow.com/questions/9775042...in-linux-kernel
  3. Прежде чем рассматривать таймеры, надо сделать несколько определений. Шедулер (планировщик) - это та часть ядра, которая отвечает за манипулирование списками тредов (нитей) в зависимости от их приоритета, политик планирования и пр. Свитчер - сущность, которая переключает контексты тредов, грубо говоря прозрачно для пользователя запускает один тред вместо другого (на данном цпу). Так вот, выполнение шедулера/свитчера может происходить по многим причинам, как-то: окончание кванта времени треда, засыпание треда в ядре, возникновение некоторых событий, которое ждет тред, фаза луны (при определенной политике планирования) и пр. Тики системного таймера - один из источников таких событий, но не единственный. Более того, его вообще может не быть (tickless system, в линуксе CONFIG_NO_HZ*). Как я понял, вы используете юзермодные POSIX таймеры (timer_create() etc) с доставкой сигнала по таймауту. При этом происходит примерно следующее: заводится ядерный таймер (не обязательно хардварный), по таймауту которого происходит прерывание. Обработчик этого прерывания посылает сигнал процессу, т.е. выбирает нужную нить и "будит" ее, после чего с ней разбирается шедулер в следующей точке решедулинга (например, при выходе из прерывания). Далее, нить в зависимости от текущего состояния, политики планирования, приоритета и пр. может пойти на выполнение - это решает планировщик. Ну и само переключение потом делает свитчер, тоже в определенный момент, не обязательно сразу. В вашем примере 50мс выдерживались потому, что не было сильной загрузки, т.е. большинство тредов спали, вот ваш обработчик сразу и выполнился. Попробуйте запустить while (1); с высоким приоритетом (а лучше с RT-приоритетом <100) - времена поплывут. Другие моменты, которые могут влиять на джиттер, связаны с доставкой сигналов: 1. POSIX требует, чтобы сигналы от таймеров и прочих io completion не терялись, поэтому используются так называемые realtime signals. Это означает, что сигналы складываются в хитрую приоретизированную очередь и доставляются в порядке приоритета (а внутри одного приоритета - в FIFO порядке). 2. Сигналы могут быть заблокированы. 3. Сигналы посылаются процессу, а выбор конкретной нити, которая их будет исполнять (единица планирования - нить) весьма нетривиален (хотя можно послать сигнал конкретной нити...). 4. Если выбранная нить мигрировала на другой CPU, отличный от того где выполняется прерывание от таймера, - пошлется IPI тому CPU на решедулинг, со всеми вытекающими. И это только то, что я с ходу вспомнил. Поэтому все стандарты (да и здравый смысл) говорят, что таймеры гарантируют исполнение обработчиков через время _не меньшее_ таймаута. Более строгой гарантии (верхней границы) вам никто не даст. И еще, при гуглении не читайте всякие ответы-мейл-ру. Википедия тоже не очень достоверна. Stack Exchange получше, но проигрывает статьям на lkml и официальной документации. А самый надежный источник - исходные коды + комментарии в них + common sense :)
  4. А кто вам сказал, что /linuxrc будет выполняться автоматически? См. http://lxr.linux.no/linux+v2.6.28/init/main.c#L817 Передайте параметр ядру init=/linuxrc EDIT: Ага, вы это уже сделали :) Проверьте сам linuxrc на предмет чем он будет исполняться (в начале должно быть нечто вида #!/bin/sh), а также сам шелл (куда он указывает, требуется ли для него внешние библиотеки или он слинкован статически, права доступа и пр.).
  5. Ситуация обстоит следующим образом. Есть стандарт POSIX, в котором указано, что timed_wait функции используют CLOCK_REALTIME. Есть другой стандарт POSIX (ADVANCED REALTIME), в котором ввели выбор clocksource для кондваров (pthread_condattr_setclock). Причем обязательно должен поддерживаться CLOCK_REALTIME, а CLOCK_MONOTONIC и пр. источники - опциональны. Так что вопрос к авторам стандарта, а не разработчикам сишных библиотек или ядра. Решаются данные проблемы незамысловато: через не-POSIX интерфейсы :) Например, в ядре linux задается относительное время, а в QNX, где драйверы исполняются как пользовательские процессы, ввели свои расширения - pthread_mutex_timedlock_monotonic(), sem_timedwait_monotonic() и т.п. Другими словами, код, зависящий от таких таймаутов считается драйверным и должен находиться в ядре/драйверах, а не в юзерспейсе (где со временем совсем туго) и не использовать POSIX. Примерно так. Почему в POSIX добавили CLOCK_MONOTONIC только для кондваров и обделили семафоры и мьютексы - другой вопрос, и тоже весьма интересный. Думаю, тут дело в функциональном назначении этих примитивов. EDIT: Как вариант, можете самостоятельно реализовать подобные расширения для юзерспейса, типа тех же pthread_mutex_timedlock_monotonic() и пр. :) А вот тут этот вопрос и рассматривается:
  6. По идее, п. 2) должен был сработать. .bss не сохраняется в объектном файле, а судя по размеру прошивки вы расширили секцию данных, либо массивы попали не в .bss. Покажите оригинальный u-boot.lds и измененный, а также правки (патч) для fat.c - может, и подскажем, что не так. Другие варианты: - заменить массивы в fat.c на указатели, которым присвоены необходимые виртуальные адреса (во внешней DRAM). Хак, но не кривее танцев с отдельными секциями для массивов. - Уменьшить максимальный размер кластера с 64к до, скажем, 8к. Тогда все влезет во внутреннюю DRAM, но SD карту придется форматировать с учетом размера кластера. - Вариант sasamy - отказаться от FAT, но тогда усложнится запись ядра на SD карту.
  7. Выбор там небольшой - network devices отдельный класс устройств, а KSZ8863 вообще phy device (PHY Abstraction Layer). Документация - /Documentation/networking/ MAC драйвер - /drivers/net/ethernet/freescale/ KSZ8863 драйвер - /drivers/net/phy/micrel.c Настройку свича проще всего сделать прошив в EEPROM KSZ8863 нужные настройки через i2c или spi (прямо из юзермода). Если EEPROM или i2c/spi отсутствуют на вашей борде, тогда настройку можно сделать через mdio bus (MII интерфейс) который точно подключен. Ну и может понадобиться пошаманить над /arch/arm/mach-imx для выделения ресурсов.
  8. А вы в \comedi\drivers\skel.c заглядывали? Там половина текста - комментарии что и как и зачем и когда реализовывать. И это актуальная инфа. В отличие от "книг по..". Так или иначе разбираться с этим придется, и чтение кода просто необходимо. Это нормально для инженера, перестаньте слушать маркетинговую чушь :) Ок, опишу свои действия, если бы мне поставили подобную задачу (при условии, что я такого раньше не делал). Первое - это провести исследование на предмет решения подобных проблем. Т.е. сразу же появляются варианты - raw driver, comedi, IIO, ZIO... Это пара часов. Далее, я бы изучил за и против данных подходов с точки зрения реальной задачи (для чего этот драйвер пишется, сроки, бюджет, кому он нужен, требования, срок жизни, стоимость поддержки и т.п.). Это день, максимум, два. В результате у меня на руках была бы _аргументированная_ точка зрения, почему я выбрал то и то. Все, далее согласование (если нужно) и кодирование. Профит. Конечно, это по-хорошему должны делать архитекты/техлиды или хотя бы сеньоры. А кодировать можно уже поручить и кодеру. А вы хотите, чтобы на форуме телепаты сказали как _вам_ лучше? Не бывает такого. А если и бывает, то либо лгут, либо ораторы идиоты, либо банальщина полная. Так что вперед, изучайте доки и код, направление задано. Это единственный путь :) З.Ы. Доки пошаговые есть, код есть, мейллисты (списки рассылки есть) - это не недостаток информации, а избыток :)
  9. Это тоже кернельный фреймворк :) Преимущества как и у любого фреймворка - дополнительный слой абстракции. Т.е. там уже есть понятия как девайсы, сабдевайсы, каналы, диапазоны измерений, ADC, DAC и т.п. с которыми работать удобнее, чем с read/write абстрактого драйвера. Зачем изобретать свой велосипед, если уже есть неплохой. Плюс, под камеди написано много софта (некоторый можно использовать как тесты). Плюс, в linux любят менять интерфейсы ядра, поэтому свой драйвер придется допиливать под разные версии; в камеди же этим занимаются мейнтейнеры и низкоуровневая часть (ваша) меняться не будет. Плата за это - раздутие кода, хоть в данном случае и небольшое. Изучать там не больше, чем изучать другие интерфейсы с ядром. В любом случае решать вам, может, действительно тупой драйвер будет лучше. Риалтайм проблемы тут не причем, RTAI отдельная песня, позволяющая виртуализировать ядро linux. Так вот, в камеди есть интерфейс для сообщения с этим супервизором. Фактически, это уже не линуксовый драйвер получится, а RTAI-шный (но умеющий общаться с программами в linux).
  10. Так, как указано здесь http://www.comedi.org/doc/driverwriting.html Т.е. берете скелетон драйвера и имплементируете все необходимые функции (attach, read/write etc). БОльшая часть работы по подгонке - это работа с железом.
  11. Есть, писали :) Comedi самый старый фреймворк, для него больше всего драйверов. К тому же, он поддерживает RTAI, что делает его весьма популярным (у буржуев, во всяком случае). Также он поддерживает все виды обмена - read/write, mmap, polling, triggering etc. Поэтому я и назвал его стандартом де-факто. Еще полезно посмотреть обсуждения в мейлистах как самого COMEDI, так и RTAI - там обсуждались почти все сценарии использования.
  12. UBIFS поддерживает wear leveling, что частично решает проблему износа. Конечно, флешку убить все еще можно, но тут ничего не поделаешь. С точки зрения равномерности износа делить NAND на разделы смысла не имеет, разве что так будет удобнее делать апгрейд неизменяемой части. К тому же, UBIFS поддерживает прозрачную компрессию, поэтому SquashFS существенной выгоды не принесет. В целом, описанный подход довольно грамотный, так обычно и делают. Но всегда есть нюансы :)
  13. В ядре (хоть и в staging) есть специальный фреймворк для подобных девайсов, ставший уже стандартом де-факто: http://www.comedi.org/doc/index.html
  14. В такой постановке задачи нет связи между минимизацией полосы пропускания и процессорного времени и риалтаймом. Так что либо уточните условия (какие еще задачи выполняет мк, кто еще использует канал связи и т.п.) или уточните что подразумевается под риалтаймовостью. А контролем целостности пренебрегать нельзя, имхо. У вас аппаратные ошибки могут возникать уже при эксплуатации из-за деградации оборудования или помех, например. Так что минимум CRC8 (при небольших пакетах; вообще, тут стоит граничить оверхед для типичного и/или максимального размера пакета). "Как упаковывать данные, какие хидеры им давать" и т.п. никто вам не скажет, пока не увидит software requirements :)
  15. Боюсь, что семантические отличия исключительно ваши. Мы вообще обсуждаем динамическую загрузку модулей (см. топик). В данном контексте лоадер - это код, который готовит некоторые данные для работы (данные - это как код и как собственно data). Лоадер пользуется внешним апи, типа чтения данных, выделения памяти и т.д. Реализация этого апи находится вне текущей абстракции, а "файловые системы", "живые юзеры" вообще тут никаким боком. Дока по L&L на примере ELF-а описывает как раз компоновку софта и последуещее развертывание на девайсе. Есть и другие форматы, но ELF настолько получился удачным и гибким, что решает в 95%. В любом случае, человек, хотя бы ознакомившийся с этой докой сможет сформулировать запрос в гугл :) Разница между "компьютерными системами" и "малыми встраиваемыми системами" заключается только в ресурсах. Т.е. надо дать определение, что такое малые встраиваемые. Моя эмпирическая оценка - это 64КБ RAM, если меньше, то нужны *очень* веские доводы для реализации динамической загрузки. Но никто даже в противном случае не мешает создать прошивку в виде эльфа, где уже бутлоадер (даже являющийся частью того самого эльфа) будет загружать всю систему (ОС + прикладнуха). Вообще, gcc + binutils + make + objcopy позволяет делать любые вещи, начиная от генерации под виндой опшнромов, досовских EXE- и COM-файлов и заканчивая велосипедами для контроллеров. Но это так, лирика. elf-loader есть как минимум в линуксе (тоже чистый и кросс), в BSD-like, QNX и т.д. Но они несколько громоздки для начального изучения, поэтому я позволю себе дать пару ссылок: prex и embox. Первый тоже кросс и MMU-независим, второй более наворочен, но требует MMU.