Jump to content

    

ARV

Свой
  • Content Count

    1181
  • Joined

  • Last visited

Community Reputation

0 Обычный

About ARV

  • Rank
    Профессионал
  • Birthday 03/30/1968

Контакты

  • Сайт
    http://arv.radioliga.com
  • ICQ
    252391897

Информация

  • Город
    Новочеркасск

Recent Profile Visitors

3594 profile views
  1. В протеусе даже возможно связать через USART МК с программой в винде и отлаживать сразу обе :)
  2. Планируется, что один раз и забыл. Но, вероятно, как у любой домашней самодельной автоматики, процесс усовершенствования затянется на неопределенный срок... т.е. определенное количество циклов вспомнил-отсоединил-присоединил-забыл все-таки будет...
  3. Такое, да вот только бы с шагом 2,54 мм... иначе все равно получается громоздко... мне для себя, для поделки...
  4. Я не настаиваю на винтах, просто ничего альтернативного на ум не приходит... У китайцев есть однорядные с шагом 2,54 мм зажимные - вот бы в 3 ряда такие... Особенно удачны те, что в центре фото 8pin - с боковым подключением проводов...
  5. Это что такое? Спасибо! Ищу, где именно такое теперь купить...
  6. Посоветуйте клеммничек или направьте в поисках... Хочу сделать некое устройство с большим количеством внешних подключений. То есть предполагаю к нему подклчать большое количество всяких проводных линий. Токи и напряжения на этих линиях мизерные - не более 20 вольт и ток до 100 мА, т.е. сечение проводов будет маленькое. Большинство линий двухпроводные, но и немалая часть трехпроводная, всего линий планируется порядка 40-45, и.е. общее количество контактныйх соединений можете себе представить - далеко за сотню. Хочется, чтобы все устройство было максимально компактным... Поэтому ищу клеммничек (винтовой или [быстро]зажимной), предназначенный для впаивания в плату, чтобы контакты были в три горизонтальных ряда... Ну примерно так как-то... Такое вообще бывает? Еще б и не дорого...
  7. Кстати, если кого-то вдруг интересует мой вопрос о том, надо ли ждать "промпта" при вводе СМС... Так вот, в документации на команду AT+CMGS модуля SIM800L написано: То есть текст сообщения следует сразу за <CR> без какого-либо упоминания промпта.
  8. Спасибо, это значительно облегчает мои муки.
  9. Вопрос об алгоритме работы SIM800L То ли это не отражено в документации, то ли я прозевал, где это описано, но есть однин вопросик. Как известно, в ответ на запрос чтения СМС модуль возвращает ответ в виде +CMGR: <преамбула><CR><LF><текст СМС><CR><LF><OK><CR><LF> Так вот, если в процессе вывода этого ответа поступит входящий звонок или новое СМС, сможет ли модуль выдать уведомление RING или иное в середине ответа CMGR? например, как-то так: +CMGR: <преамбула><CR><LF><RING><CR><LF><текст СМС><CR><LF><OK><CR><LF> ? Или он сначала завершит ответ, а потом сформирует поступившее уведомление? Это я к тому, надо ли в процессе анализа ответа на запрос СМС проверять поток на наличие "неожиданных" уведомлений? Очень не хочется разбираться с этим методом экспериментов, ведь искусственно создать такую ситуацию довольно сложно...
  10. А если метеорит упал в курятник? А если землетрясение? А если ядерная война? Всяких "если" можно придумать миллион. Расскажите мне про ваш идеальный проект, и я придумаю "если", которое вы не учли. Даже когда спутники делают, предусматривают тройное резервирвоание - казалось бы, все предусмотрено, что еще может быть? А все равно наступает такое "ещё", что как раз четвертого комплекта и не хватает. И что из этого следует? Никто никогда не делает тройной резерв на каждый из трех комплектов оборудования. То есть я хочу сказать, никто никогда не пытается предусмотреть все вероятные случайности, всегда ограничиваются наиболее вероятными. И граница приемлемости этой вероятности может быть разной: иной раз и 0,5 много, иной раз и 0,98 мало... Но требовать 1,0 - бессмысленно. Недостатки моего кода очевидны, и критика ваша практически всегда справедлива. Изначально я задавал вопрос совсем не об этом, но раз так завертелось, теперь вынужден заниматься пересмотром кода и переписыванием его. И советы мне вполне пригодятся, как ваши, так и другие, как минимум, в качестве стартовой точки для размышлений. И по мере обдумывания у меня возникают новые и новые вопросы, на которые наверняка последуют новые и новые советы и так далее... Что же делать, когда остановиться? Если допустить исключение динамического распределения памяти, это означает переделку 100% кода. Если отказаться от выбранного принципа приема сообщений от модуля, это означает переделку, пожалуй, 80% кода. Если отказаться от парадигмы RTOS - снова 100%.... просто вычистить косяки? Может, возьмете "шефство" надо мной, неучем? И в отдельно заведенной теме (а то я уже чувствую, как буфер терпения модератора переполняется и вот вот hard fault будет теме) продолжите меня воспитывать? ;) Я-то самоучка от еще ассемблера MCS51 и tasm - кроме нескольких книг, меня никто ничему не учил целенаправленно...
  11. Да, именно этот вариант я и считаю приемлемым. "Какой-то момент" явление редкое, и потому затормозить несколько задач на время завершения работы других - вполне допустимо. Именно из-за редкости такой ситуации. Делать же нормальным явлением ожидание семафора всякий раз, когда кому-то послал сообщение - это, с моей т.з. значительно хуже, это перечеркивает всю парадигму многозадачности. Это да, не всегда проверяю, хотя и стремлюсь к этому. Косяк, признаю. Еще раз: нет, нет и нет! Не стану утверждать, что всегда, но что НЕ всегда - однозначно! Само существование динамического распределения памяти, как явления, опровергает ваше утверждение. Даже в системах с ОЗУ в десятки гигабайт, даже в системах с виртуальной, теоретически ничем не ограниченной, памяти. К тому же статическое выделение одного буфера и последующая "передача" его то одному, то другому процессу, по сути своей ничем от динамического распределения не отличается. Семафоры и т.п. как раз и будут выполнять функции менеджера кучи. Только геморрою программисту больше. И "нормальность" ожидания другой задачи на каждом шаге работы с памятью де-факто превращает любую RTOS в кооперативку. Вот это самое "может" и является камнем преткновения: мы оба используем это слово, т.е. ориентируемся на некое допущение. Может быть != обязательно будет. Памяти должно хватать, но может и не хватить. И тогда наступает момент компромисса, о котором говорю я, а вы маскируете его мьютексами и семафорами: надо рассчитывать на наиболее характерную для конкретного девайса потребность в памяти, а не на предельно возможную (случай, когда ОЗУ в избытке, я опускаю по естественным причинам). В этом случае в наиболее типичном режиме будет использован [минимальный] оптимум памяти, а в наиболее "плохом" возникнет ожидание доступности нужного количества. Может, я это признал. Но не будет, поскольку конкретные условия таковы. Конечно, мне не помешает провести ревизию кода еще раз, чтобы гарантировать отсутствие реального разыменования NULL, а не возможного (т.е. всегда проверять результат mem_alloc). Преклоняюсь перед вашей тщательностью. Но, например, при управлении инкубатором, я никогда не проверяю на ноль значение температуры. Надеюсь, почему так, не стоит объяснять? (но объсню: потому что если температура в инкубаторе достигла нуля, абсолютно без разницы, зависнет ли терморегулятор или пересбросится). Ну, имхо, это слишком резко сказано даже для профессионала.
  12. Послушайте, разве то, что вы сказали, не то же самое, что сказал я? Какая разница, торчим мы в тупике по семафору, ожидая освобождения статического буфера, или по иной причине? При динамическом выделении мы в тупике вообще не торчим. Разве это не стоит того? По причине того, что static-буфер в одном модуле для одной задачи не "виден" другой задаче в другом модуле, соответственно, 10 буферов для 10 задач по 100 байт - это килобайт памяти. В то самое время кода вероятность того, что все 10 задач захотят занять каждая свой буфер одновременно, как правило, мала (особенно, если эти буферы служат для обмена сообщениями), и принципиально можно обойтись и динамически разделяемым буфером в 500 байт, а может и в 200. На моем собственном примере я убедился, что при статическом выделении буферов под обмен строками (учтем неоптимальность моего кода) при 4 задачах у меня остается свободными менее 800 байт ОЗУ, а с динамическим буфером в 640 байт уже 1200 байт свободно. Вот так и происходит экономия, и это с учетом расходов на служебные области... Как правило, я выхожу из себя, психую некоторое время. Так и моя задача, попав в неприятность из-за отсутствия кавычки, не повиснет навсегда, а просто прочихается и, в худшем случае, после WDT перезапустится. Тем более что ситуация, о которой вы говорите, скорее умозрительная, а не реальная. Нет, я вполне понимаю справедливость ваших слов "вообще", и, раз уж придется переписывать код, что-то изменю в этом направлении, но параноидально обвешивать все и вся контролями "исклюительных" ситуаций - явно перебор, вряд ли стану. Не смотря на то, что в современных системах почти всегда есть исключение при делении на 0, разве вы всерьез рассчитываете на то, что в вашей программе деление на 0 будет скорее закономерным, нежели редчайшим случаем? Или каждый параметр, входящий в любую из ваших функций, вы всегда подвергаете анализу на допустимость значений? Разум нам для того и дан, чтобы оценить степень риска в каждой ситуации, и, там, где вероятность беды не велика, пренебречь безопасностью в угоду чему-то иному. Разве не так?
  13. Когда памяти достаточно, её можно и не экономить. А когда ее не хватает, надо искать способ, как одну и ту же область памяти разделить на разные задачи, и тут динамическое распределение - единственный выход. Например, как можно отправить строку из одной задачи в другую, если память под строку не выделять динамически? Задача А, допустим, имеет статическую область (массив), сформировала там текст и отправила этот массив в задачу Б через сообщение. Пока задача Б не закончит работу со строкой, задача А не может задействовать этот массив для отправки сообщения задаче С. В итоге мы имеем тупик. При динамическом выделении тупик возникнет только в случае исчерпания кучи, что при должном её размере не должно возникать. Я так думаю... Теория именно так и говорит, согласен. А практика убеждает, что корректно написанного ПО не существует в природе. Бесконечное стремление к совершенству - пустая трата времени. Мой оператор ничего другого не передает, и, если верить оператору-информатору, не планирует ничего менять. Нужно ли мне закладывать в ПО моего устройства алгоритмы, рассчитанные на все варианты, которые МОГУТ быть? Не уверен... Угу, именно артефактов - явлений, исключительных, редких и необъяснимых. Вставлять в устройство еще неактивированную симку, закладывать в алгоритм вариант, когда она будет самоактивироваться... тогда еще и PIN надо автоматически "снимать" - на некоторых симках же он установлен, и не на всех обязан быть 0000, не так ли? У вас в ПО это учтено? Не проще ли ограничить число вариантов простым требованием устанавливать в устройство активированную симку со снятым запросом PIN и с уже ненулевым балансом? Производители автомобилей не закладывают в возможности авто варианты, когда пользователь вместо бензина нальет в бак дизель или вообще жидкость для омывания стеол, а ведь такое возможно В ТЕОРИИ... Производитель на лючке бака пишет "только А92 или выше" и ограничивается этим. ИМХО, разумный компромисс - это намного лучше, чем параноидальное стремление к идеалу надежности...
  14. Кстати, на счет разыменования NULL я был не прав: у меня в коде все правильно. Я об этом: CMD_HOOK(CUSD){ // находим первую кавычку в строке - это начало сообщения char *start = strchr(str,'"')+1; // TODO это вообще что такое?! зачем оно здесь? // находим последнюю кавычку - это конец сообщения char *end = strchr(start,'"'); *end = 0; if((start[0] == '0') && (start[1] == '0')){ // это UCS2-кодировка Здесь идет обработка уведомления, которое ВСЕГДа имеет такой формат +CUSD=1,"сообщение", поэтому поиск кавычек вполне корректен, как и последующий анализ 0-го и 1-го байта полученной строки. Варианта, когда кавычек нет или между ними нет строки - не существует. Я поспешил, когда признал тут проблему.
  15. Это хорошо, что вы критикуете мой код. Спасибо вам за время, потраченное на меня. Потому как сам я и ошибку с разыменованием NULL не заметил, и по поводу копирования подстрок туда-сюда тоже не обращал внимания. Все это стимулирует независимо от моего согласия с вашими подходами. Теперь, взглянув с вашей колокольни на свой код, я вижу, что функционально я не совсем разумно сконструировал свой проект. Например, у меня есть структура с номерами телефонов, и для отправки СМС я написал такую функцию: void sms_send(char *str, uint8_t num), где num - номер телефона в виде индекса в массиве номеров. И эта функция использует другую функцию gsm_send_cmd(char *cmd), вся роль которой сводится к добавлению перед cmd префикса "AT" и "\r" после, и все это уходит в USART. А подготовка cmd для этой функции заключается в куче strncpy или sprintf, чтобы собрать воедино номер телефона, тело сообщения и т.п. После вашей критики я понял, что слишком глупо сделал: для чего копировать номер телефона в строку, чтобы потом эту строку выдать в USART, если номер сразу можно выдавать в USART прямо из массива, где он и хранится?! и так далее - слишко много манипуляций со строками у меня, которые никакой пользы не несут. Так что польза несомненна... как и неизбежность значительных передлок. Вы же видели, что неоптимальность я отнес на счет обработки "верхнего уровня", а не "нижнего". Алгоритм "верхнего" я описал в трех пунктах, а до этого рассказывал о нем дважды или трижды словесно. И мне кажется, алгоритм весьма оптимален. Хотя, чем больше читаю ваши ответы, тем сильнее сомневаюсь в этом...