Jump to content

    

VslavX

Свой
  • Content Count

    1046
  • Joined

  • Last visited

Posts posted by VslavX


  1. не только, даже у stdlib ужасный код. Посмотрите на листинг memset/memcpy и т.д. - каждая функция под несколько сотен байт.

    Он не ужасный - приличная (с учетом взаимного выравнивания источника и приемника, и с использованием копирования блоками) memcpy()

    не может быть крошечной.

     

    Для чипа с 512К Flash может и приемлемо, но для STM32F100C4 пришлось переписать.

    Ну если размер кода совсем критичен, то такой вариант вполне возможен.

     

  2. развития у NXP просто нет. Применили 1764 - ну 1765 можно поставить

    ИМХО, не все там так гладко. По софту с LPC1768 на LPC1788 переходится довольно коряво. Куча мелких не бросающихся в глаза изменений. Регистры потасовали, GPIO настраивается по-другому, тактирование другое и еще всякое. При переходе 1768->1788 разочаровался - ожидался мгновенный запуск, а пришлось таки повозиться.

    У ST32F2xx однозначно лучше Ethernet контроллер (тут в этой ветке про это писал уже, на сегодня плюшки все опробованы практически - реально вкусные). А вот USB device у STM32F2xx довольно самобытные. Первый раз такое вижу - все принимаемые пакеты валят в одно FIFO, с вытекающими последствиями, когда надо выполнить SET FEATURE STALL например (и есть у меня некоторое подозрение что в ST-шной библиотеке код написан для этой функции не очень верно). Прикручивал USB-device Intel/Samsung/Atmel/Freescale/NXP - везде конечные точки отдельные, со своими независимыми FIFO. Про хост вообще молчу - тоже самобытное извращение вместо стандартных OHCI/EHCI. Там вообще, похоже USB куплен у Синопсиса в виде IP-модуля и прикручен с далеко не косметическими швами (модуль походу 64-битным выглядит). Документация тоже явно патчилась с готовой - много незаимплеменченого выкинуто, но пара непонятных/нерабочих битов в документации осталась. Еще SPI у STM32 помедленнее - без DMA (не подходит DMA - надо в потоке принятые данные анализировать) тормозит, не получается без пропусков его загрузить в режиме поллинга. У LPC там FIFO было встроенное в SSP, шустро работало - пока анализируем очередной байт, SPI работает параллельно.

    KINETIS хорош безусловно.

    Сейчас Атмел еще "поднимает голову". Из Cortex-M3 у них SAM3X интересный - SDRAM контроллер, Ethernet (старый, правда, без плюшек), USB HS (трансивер на борту). Но традиционно - питание наружу торчит в двух уровнях (оно с SAM7 все так тянется - цоколевка такая же у новых серий). Еще пугают новым комбайном - SAM4E - где будет "все-все-все". Поживем - увидим.

     

  3. Не вижу смысла в переписывании заголовочных файлов. К примеру, в stm32f2xx.h все регистры и биты описаны, близко к техническому руководству, зачем же их "обзывать" иначе? Другое дело - дополнить чем-то... Лучше пройтись по этому заголовку, глядишь, на умное решение натолкнешься...

    ИМХО, готовые хидеры тоже как бы имеют право на жизнь. Тогда разработчик их принимает "как есть", не парится насчет их формата и не устраивает "хомячковых драм онлайн" типа "гадский разработчик не знает про битовые поля".

    С другой стороны, если есть уже куча своего софта, уже отлаженного и вылизанного, портируемого на разные чипы, и все уже разложено по полочкам - то почему бы новый контроллер не встроить в эту систему полочек.

    Это как штаны - можно открыть шкаф и бросить комом, а можно аккуратно сложить и положить на полку (или даже повесить на вешалку). Результат то один - штаны в шкафу, вот только слегка по-разному они там лежат.

    Собственно писать свои хидеры недолго, у меня основное время тратится на чтение документации и вникание в нее. Новополученная информация закрепляется еще и в письменном виде - такая вот особенность со студенческих лет у меня - при подготовке к экзаменам исписывал еще бумаги в 2-3 раза больше чем объем конспекта. Поэтому лично для меня переписывание хидеров достаточно полезно - дальше работать с контроллером мне проще. Ну и удовольствие от того, что "мои штаны аккуратно висят на вешалке". (Не, в реальном шкафу джинсы таки часто комом :biggrin:)

    И еще момент. Софт-то усложняется и усложняется. Сотни тысяч сишных строк. И если постоянно "пихать штаны комом" то в шкафу появляется неряшливая куча, которую может оказаться достаточно тяжело разгребать.

     

  4. а как вы предлагаете делать на HD?есть такие камеры с хорошими параметрами и мелким размером?

    Вроде есть, нагугливал HD-регистраторы с внешними HD-камерами (внутрисалонными, не IP67), насчет интерфейса не скажу.

     

    для спячки при вынимании ключа,все автомагнитолы имеют 3-й провод(кажется жёлтый),который подключают к замку зажигания.

    Нет, у меня (VW) только CAN. Выключается не при выключении зажигания, а именно при вынимании ключа. То есть приехал, мотор заглушил (ключ повернул) - музычка продолжает играть. И только когда собрался уходить - вынимаешь ключ, магнитола глохнет.

    По теме - купил бы CAN-онизированный навигатор+регистратор в формате 2DIN, желательно на общераспространненной платформе - типа Andriod или WinCE/Mobile. А не попадается пока.

     

  5. Добавлю еще один недостаток: качество кода, примеров, знание принципов программирования, языка С отавляет, мягко говоря, желать...Понятия bit-field, enum NXP незнакомы, количество "magic number" зашкаливает... Простие меня электрики, но это ваш стиль. Другими словами, софтвер НЕПРОФЕССИОНАЛЕН!

    Да, и вайла описания битое у NXP нет! У Atmel с этим серьезных проблем не обнаружил.

    Ужос-то какой! Гадский NXP не написал хидеры в приятном Вам стиле.

    Если микроконтроллер берется в разработку плотно и надолго (на несколько проектов/серию, не для "халтурки"), то хидеры вообще-то желательно написать полностью "под себя" самому. Внести свою систему обзывания регистров, битов в регистрах, размещения определений в секциях, учесть особенности компилятора(-ов). Попутно, создавая хидер, внимательно прочесть документацию (когда обзываешь биты - так или иначе читаешь за что они отвечают и как работают) и получить более-менее полное представление об аппаратуре. Для начала можно описывать не все блоки - а только нужные, и потом расширять хидер по мере освоения новых блоков. Угу, это сначала долго, требует кропотливого труда, но потом проблем сильно меньше обычно и при наличии в работе полудюжины архитектур мозгам потом сильно проще работать в едином, собственноручно созданном формате.

    ИМХО, если компания/разработчик профессионалы (опытные, уже занимается софтом для контроллеров некоторое время), то обычно есть свои наработки в виде выбранной RTOS, стеков USB/TCP и прочего, и от контроллера требуется только соответствовать заявленным техническим характеристикам, и иметь более-менее удобоваримую документацию. На софтовый мусор, предлагаемый производителями, как правило можно не смотреть - это для хомячков, глючное, непортируемое, часто с лицензионными ограничениями.

     

  6. До суда прибор еще нужно продать. Без волшебных букв HD просто не купят.

    Да, без HD с ценой $500+ не купят. Я, кстати, ищу себе 2DIN голову, чтобы работала как навигатор и DVR, сопрягалась с телефоном по BT, и еще при этом по CAN с авто интегрировалась - рулилась кнопками с руля, и впадала в спячку при вынимании ключа зажигания (сейчас так штатная магнитола делает). Так пока не нашел ничего подходящего. По "навигатор+регистратор" всякая ерунда гуглится, в 2DIN почти нету ничего.

     

  7. Версия 5.41 - генерирует нормально. Мда, никак оно на 6.x перейти не получается, серьезно будем рассматривать GCC от CodeSourcery/Mentor.

     

     

    Глючат именно циклы с предусловием

    Что-то с тестированием в ЯР плоховато. Такие косяки можно автоматическими тестами выловить. Скомпилируй и запусти на реальном железе - все быстро вылезет.

     

  8. Речь не о кривости алгоритма а о разной его работе при отключенной и включенной оптимизации в компиляторе.

    про степень согласен, но тогда баг скорее всего бы не вылез :-)

    Ну я вообще-то осторожно намекал что там, скорее всего, еще косяки есть, а не только "бросившиеся в глаза".

     

    деление - писалось под ARM7TDMI, там нет аппаратного деления, был бы вызов библиотечной функции

    А почему не устраивает библиотечная функция? Недостаточно быстрая для использования при выводе строки? Ну если уж такие требования к скорости, то надо было бы рассмотреть алгоритмы быстрого деления на константу (через умножение, Кнут, том 2). И сделать две явные версии - для процессоров с аппаратным делением и без (а при использовании библиотеки это автоматом).

     

    ИМХО, разумным (чтобы не заводить таблицу из 10000 слов) по скорости для вывода в ASCII числа 0-9999 было бы одно деление на 100 с остатком, и вывод двух чисел 0-99 (частного и остатка) по готовой табличке ('00' .. '99'). В этом одном делении, даже универсальном (не константу, на любое число) программном в библиотечной функции, было бы максимум 8 итераций цикла деления. Сравните со своими средним количеством циклов 20 (циклы вычисления степени не учитываем).

     

    break - просто мне он не нравится, так же как и return из середины функции.

    OK, имейте лишнюю проверку условия, раз уж нравится (за скорость уже не боремся?). И необходимость полной ревизии цикла, если условие в цикле надо будет изменить. "return" - то несколько из другой оперы.

     

    ЗЫ: Я тоже думаю что 99% компилятор тут не при чем. "Листинг в студию, сестра!" ©

  9. Была в проекте написана простая функция преобразования числа uint32 в строку

    Вы меня извините, но это далеко не простая функция, сразу бросаются в глаза алгоритмические косяки:

     

    - вычисление степени 10 в цикле (facepalm)

    (это можно сделать таблицей, да и вообще без степеней можно обойтись)

     

    - вычисление очередной цифры циклом вычитания (facepalm)

    (про деление автору ничего неизвестно?)

     

    - выход из цикла с лишним сравнением условия (l=1) (facepalm)

    (банальный break там просится)

     

    ИМХО, тут не в компиляторе "собака порылась".

     

  10. Поскольку тема для меня актуальна, позволю себе задать вопрос. Вы как устройства на шине распознавали/нумеровали. По заранее подготовленному списку, или просто проходились по адресам в цикле? Как поступали, если на шине присуствовало несколько одинаковых устройств?

    Увы, до автоматической энумерации мы тогда не доросли. Адреса на устройствах назначались админами вручную - или с пользовательского интерфейса (на некоторых девайсах были клавы/индикаторы/память конфигурации) или банально полем перемычек (ака джамперы). Поскольку конфигурация сети менялась не так уж часто, и количество изделий было у пользователей ограничего (макс конфигурация это до трех сотен изделий на ~20 ветках RS-485, но таких кастомеров было единицы), то проблем это не создавало.

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

    Сканер проходился по всему диапазону адресов, находил все активные устройства и составлял список, который уже можно было подсунуть как базу для остального софта. А дальше там уже были зачатки PnP - девайс сам рассказывал о себе, говорил чего у него "на борту" есть, и мастер-софт уже решал как им рулить.

    PS. На сегодня RS-485 у нас практически помер - вместо него 10/100BASE-TX.

  11. Название шины можно оставить предыдущим: USB (Utopian Serial Bus).

    ..

    Кто что думает? Правда тему надо будет в ОФФТОП сносить)

    Да уже подумали. В 1993-ем году еще.

    В нашем изделии был RS-485, и надо было родить протокол для привязки полусотни изделий на общей разделяемой шине к одному PC. Схема с арбитражем доступа и обнаружений коллизий на расстояниях в сотни метров надежно не работает - уже влияет омическое сопротивление проводки, поэтому пришли к схеме мастер-слейв. На роль мастера, ессно, назначился PC. Потом начали протокол рожать - сначала канальный уровень, потом сетевой, потом уже и до приложения дошли. А потом вышла спецификация USB 1.x и когда я ее почитал - я буквально впал в ступор, потому что канальный уровень USB на 90% совпадал с тем что мы придумали. В итоге - предлагаемый путь "взять RS-485 и сделать все по (своему) уму" лично мной пройден, независимо и еще во времена когда ФИДО не каждый день ходило, не то что инет. И в результате, как ни странно, получился протокол, очень похожий на USB. :biggrin:. Естественно, группа экспертов USB-форума свой вариант получше и поглубже проработала, но ту же самую задачу на канальном уровне мы с ними решили практически одинаково.

    USB - на сегодня это массовый стандарт. Да, сложноватый, не самый простой для реализации, но идеология там весьма толковая. И увы, во многих имплементациях есть ошибки и глюки. Питание слабовато, но это относительно. И единый стандарт гораздо лучше чем "колхоз" всяких проприетарных интерфейсов, распаек, разъемов и протоколов. Уже за одно это USB можно куда угодно поцеловать. И, имхо, не стоит сравнивать RS-485 с USB - у них разные ниши. Все равно что сравнивать фермерский пикап с городской "поповозкой".

     

  12. Вы хотите прямо этот сайт запустить на своей втроенной железке и выставить голой ж... в Интернет? :cranky: Набега хакеров не боитесь?

    ИМХО набега хакеров надо боятся если сервер основан на открытых/широкоизвестных вещах, в которых можно поковыряться и поискать уязвимости. А если все самописное и железо физически недоступно (только через сетевые сервисы), то хакеры не так уж нестрашны. Ну за ДДОС-ят, в худшем случае - это не совсем вопрос к серверу/железке. Интересно было бы сделать, например, дефейсинг на сервере, у которого ресурсы все в программной памяти микроконтроллера (ну типа LPC17). Теоретически понятно - нужно как-то удаленно грузануть свой код в RAM и получить управление. Но практически - без наличной прошивки и много-много времени на ее вдумчивое изучение на предмет "дырок" - малореально.

     

  13. Мне нужен не простейший, а достаточно полноценный.

    А что в Вашем понимании полноценный? Иногда "полноценный" Web-сервер может быть весьма суровым и выдвигать неслабые требования к хостингу.

     

  14. Функция возвращает температуру в градусах +20. То есть нулевое значение соответствует -20С, значение 45 соответствует +25С.

    Функция io_adc_convert() возвращают целое беззнаковое 12-битное значение считанное с канала АЦП.

    #define	IO_ADC_TBAT_VSENSE_25		1750	// типичные 1.41V при 25C   (3.3V опорное АЦП)
    #define	IO_ADC_TBAT_SLOPE_100		534	// типичные 430mV на 100C  (3.3V опорное АЦП)
    
    IO_CALL_TYPE
    DWORD
    IO_CALL_OPTION
    io_apm_temp(void)
    {
       DWORD ret;
    
       ret = io_adc_convert(ADC_MUX_TBAT);
       if (ret > IO_ADC_TBAT_VSENSE_25)
       {
           ret = ((ret - IO_ADC_TBAT_VSENSE_25)*100)/IO_ADC_TBAT_SLOPE_100;
           if (ret > 45)
           {
               ret = 0;
           }
           else
           {
               ret = (25 + 20) - ret;
           }
       }
       else
       {
           ret = ((IO_ADC_TBAT_VSENSE_25 - ret)*100)/IO_ADC_TBAT_SLOPE_100;
           ret += 20 + 25;
       }
       return ret;
    }
    

     

  15. Так как переключение контекста происходит в прерывании с наименьшим возможным приоритетом (PendSV с приоритетом 0xFF), то можно не запрещать прерывания, а поднять нижнюю границу обслуживаемых прерываний.

    Дело в том что часто критическая секция именно организуется для защиты данных разделяемых с обработчиком прерываний - тут только запрет прерываний и поможет. Если данные в критической секции разделяются только между задачами - то лучше уже использовать синхрообъекты RTOS - мутексы, семафоры или события. Еще, иногда, если код в критической секции очень быстрый и короткий, то из соображений быстродействия вполне можно критическую секцию организовать на tn_interrupt_xxxx(). Пример (не самый удачный для Cortex с его ldrex/strex):

    HAL_SYSTEM_CALL
    DWORD
    HAL_CALL_OPTION
    hal_interlocked_inc(
       PDWORD  var)
    {
       DWORD lock, ret;
       lock = hal_lock_interrupt();
       ret  = *var + 1;
       *var = ret;
       hal_unlock_interrupt(lock);
       return ret;
    }
    

    Запрет переключения между задачами тоже можно реализовать независимо от порта - через tn_task_change_priority() (банально задрать приритет до максимального в системе), но оверхед обычно больше чем на мутексе, например. Не говоря уже о interrupt_xxxx().

     

  16. Правильней так (пример от IAR-а)

    Ну насколько я знаю - в оригинальном порте TNKernel так и сделано, только переменная OldState спрятана внутри макроса. В своей модификации RTOSе я использую идеологию IAR-овского примера - с явным сохранением состояния.

     

     

  17. Какие протоколы? Какие сложно реализовать?

    Сложность понятие относительное, зависит от того какие опции протоколов нужны и от общей архитектуры. Если нужны только ARP/IP/ICMP/UDP без особых наворотов (без IP-опций, без фрагментирования, не заморачиваясь с фичами типа zero-copy) то можно даже не напрягаться и взять уже что-то готовое. Но мне был нужен минимальный комплект ARP/IP/ICMP/UDP/TCP/DHCP/AutoIP/DNS/HTTP/SSDP, да в разные проекты, да на долгую перспективу, да endainess-portable, да на работе вытерпели (читать - дали время, повезло мне) - поэтому решил сделать свой.

    На 2008-ой год, когда писалась основная часть, изучал многие готовые стеки (uIP, lwIP, Niche, ka90, tinet, OpenTCP) . На мой взгляд самый внятный это lwIP. Поэтому если свой стек нет возможности писать - то я бы остановился на lwIP, тем более что его в последнее время развивать стали.

     

  18. Сложно серверную сторону на железе поднять?

    Несложно, клиентскую тоже несложно. Если нужен сервер - то ждете соединение (listen), принимаете его (accept) и на новом TCP соединении просто осуществляете прием с отбрасыванием всех поступивших данных (естественно на уровне приложения, а не стека), при желании измеряете текущую скорость на стороне сервера, когда соединение закрывается - цикл можно повторить. Никаких специальных данных в потоке iperf не требует.

     

    стек вы реализовывали или готовый использовали?

    Реализовывал свой, ничего из готового на тот момент не устраивало.

     

  19. Я смотрю, зацепил я Вас в той теме со стеком. Цифры у Вас явно выше тогдашних, поздравляю :)

    Ну не то чтобы зацепили, но критично на свой код посмотреть заставили :)

     

     

     

    Если эти 100 Мбит на практике не нужны, то лучше направить свою энергию в более конструктивное русло.

    TCP/IP стек - это универсальный кубик, его можно применить в любом проекте, не ограничивая себя теми,

    где "эти 100 Мбит на практике не нужны". Например этот же "кубик" у меня стоит в проекте где и гигабита маловато.

     

  20. что-то около 8Mbit/s в каждую сторону. Для железки 168МГц — сносно?

    Маловато будет. Сегодня закончил разработку драйвера для EMAC STM32Fxxx, с опциональной/отключаемой поддержкой аппаратных сумм - сам драйвер более 4 тыс строк, с использованием RTOS. На F207@120МГц результаты такие (поток в одну сторону, iperf-ом мерялось):

    С отключенными суммами (скорость указана в "полезных" байтах TCP-соединения, теоретический предел порядка 96 мбит/сек):

    - прием от PC - 95.7 мбит/сек, загрузка процессора 77 процентов (23 в IDLE остается еще)

    - передача на PC - 87.8 мб, загрузка процессора 59 процентов (41 в IDLE)

    С включенными аппаратными суммами:

    - прием от PC - 95.7 мбит/сек, загрузка процессора 55 процентов (45 в IDLE)

    - передача на PC - 88.4 мб, загрузка процессора 51 процентов (49 в IDLE)

     

    Разница в 1%~. Действительно разницы нет HW или SW checksum.

    Как показывают приведенные цифры - заметная разница вылазит только на относительно больших скоростях. Ваши потоки на порядок меньше, соответственно и разница тоже на порядок меньше (22 процента разделить на 10 - пару процентов и выходит). Справедливости ради надо заметить, что я обломался с написанием обработки специфических ошибок DMA передатчика и в обоих случаях (с суммами и без) контроллер работает в режиме Store-And-Forward, этим я объясняю недостижение передатчиком теоретического максимума в 96 мбит/сек.

     

  21. А здесь пару строк записи в регистры заменяют огромными библиотеками.

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

     

  22. О хранении на серверах. Гм-гмм... Вещь конечно неплохая. В определенных случаях.

    Только... Как-то не доверяю я носителям, не находящимся в моей физической доступности.

    Угу. У нас тут органы недавно файлообменник местный завалили - ex.ua. Так нашлись уникумы которые там свои личные фото и видео хранили. А что - удобно, на винты не тратиться, на железо не тратиться, админить и поддерживать свой сервачок не надо. Ну и все материалы, ессно, тю-тю.