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

Cosmojam

Свой
  • Постов

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

  • Посещение

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


  1. Не, всё нормально со стеком. Ошибаюсь наверное в том что этот буфер выделяется на стеке вызывающей функцию задачи => стек всех задач должен быть больше на размер буфера. Поскольку работа с буфером ведётся внутри критической секции, то лучше сделать буфер в bss, заменить критическую секцию на мьютекс и возвращать мьютекс после записи буфера в очередь
  2. Спасибо за подсказки! Но кажется проблема не в самой функции, а в va_arg. Случайным поиском в сети нашёл http://www.menie.org/georges/embedded/printf-stdarg.html попробовал - тоже самое! В поведении ничего не поменялось. Попробую ещё варианты функции, но что-то кажется не поможет. По ходу надо делать syslog_write() с уже сформированной строкой на входе и оборачивать вызов в макрос где уже будет выделен буфер и вызван sprintf. -=UPDATED=- Как обычно по невнимательности ищу проблему не там где она есть. В одной из задач (TCP клиент на сокетах lwip) была такая конструкция: if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { syslog_write(LOG_ERROR, pcTaskGetTaskName(NULL), "Cannot connect to %s:%u", serv_addr.sin_addr.s_addr, ntohs(serv_addr.sin_port)); ..... Задача эта периодически убивалась и создавалась и периодически не могла подключиться к серверу что приводило к вызову syslog_write(). Но я забыл обернуть serv_addr.sin_addr.s_addr в inet_ntoa() - ведь там не строка с IP-адресом, а целое число в структуре. Это и приводило к попытке обращения к адресу в памяти который на самом деле является IP-адресом сервера в виде 32-битного интеджера (то самое число 0x201A8C0 оседающее в BFAR если поменять порядок байт на сетевой получится 192.168.1.2 - адрес сервера). TDD рулит :)
  3. Стека хватает - к гадалке не ходи. Пробовал безумные размеры выделять где "640кб всем хватит" А насчёт кучи на NXP-шном форуме подсказали http://support.code-red-tech.com/CodeRedWiki/redlib_v2_notes макрос CR_PRINTF_CHAR чтобы printf() не выделяла память в куче под всю строку, а печатала по-символьно. Не помогло. Да и ведь там про printf()говорится, которые выделяет память прежде чем напечатать строку в символьное устройство, а у меня vsnprintf() который печатает строку в буфер и не более переданного размера буфера. Т.е. куча ему пофигу покуда буфер на стеке задачи. Но если разместить буфер в bss (сделав его static) то никаких изменений в поведении не наблюдается. Если уж на то пошло посоветуйте достойный аналог vsnprint(). Вещественные числа не нужны, только целые со знаком и без и строки, и чтобы не пыталась выделять память без спроса
  4. Буфер записывается в очередь с максимальным таймаутом 2 секунды. Эту очередь читает другая задача с 0 приоритетом, которая собственно пишет данные на устройства хранения (для теста - printf на UART обёрнутый в critical region). Даже если выкинуть запись в очередь и не создавать задачу, которая её читает, то результат тот же самый - само наличие вызова vprintf c va_list в качестве параметра создаёт ошибки.
  5. Обёртка в макрос не помогла. Тоже самое. Не помог и рекурсивный мьютекс. Происходит Bus Fault, при этом в регистре BFAR записывается валидный адрес места где произошёл этот эксепшен. В этом регистре 0x201A8C0 что за пределами адресного пространства. В отладчике ловится последняя инструкция перед после которой произошёл эксепшен и это: Это main() и настройка портов для юарта. В регистре R6 после того как произошёл эксепшен лежит 0x201A8C0 Но как она оказалась в main() если уже все задачи запустились? Где-то косяк с указателями видимо Дизассемблер vsnprintf (в примере кода обычный указан vsprintf, но без разницы что обычный что с "n" и размером буфера) 0000ee08 <vsnprintf>: ee08: b5f0 push {r4, r5, r6, r7, lr} ee0a: b08f sub sp, #60; 0x3c ee0c: 4606 mov r6, r0 ee0e: 460c mov r4, r1 ee10: 4615 mov r5, r2 ee12: 2100 movs r1, #0 ee14: 2228 movs r2, #40; 0x28 ee16: a804 add r0, sp, #16 ee18: 461f mov r7, r3 ee1a: f001 f94d bl 100b8 <memset> ee1e: 230a movs r3, #10 ee20: 9307 str r3, [sp, #28] ee22: f06f 4300 mvn.w r3, #2147483648; 0x80000000 ee26: 9306 str r3, [sp, #24] ee28: 4b0d ldr r3, [pc, #52]; (ee60 <vsnprintf+0x58>) ee2a: 9604 str r6, [sp, #16] ee2c: 2600 movs r6, #0 ee2e: 1e62 subs r2, r4, #1 ee30: 9302 str r3, [sp, #8] ee32: a804 add r0, sp, #16 ee34: 4633 mov r3, r6 ee36: 9500 str r5, [sp, #0] ee38: 9701 str r7, [sp, #4] ee3a: f000 f9e9 bl f210 <__vfprintf> ee3e: 9b06 ldr r3, [sp, #24] ee40: 4604 mov r4, r0 ee42: 3b01 subs r3, #1 ee44: 42b3 cmp r3, r6 ee46: 9306 str r3, [sp, #24] ee48: db02 blt.n ee50 <vsnprintf+0x48> ee4a: 9b04 ldr r3, [sp, #16] ee4c: 701e strb r6, [r3, #0] ee4e: e003 b.n ee58 <vsnprintf+0x50> ee50: 4630 mov r0, r6 ee52: a904 add r1, sp, #16 ee54: f001 f954 bl 10100 <__flsbuf> ee58: 4620 mov r0, r4 ee5a: b00f add sp, #60; 0x3c ee5c: bdf0 pop {r4, r5, r6, r7, pc} ee5e: bf00 nop ee60: 0000e4f1 .word 0x0000e4f1 На ночь глядя это мало о чём говорит
  6. Всем привет! Подскажите где я не прав. Имеется примерно такой код для LPC1768 с FreeRTOS: uint_fast8_t syslog_write(SysLogRecordType type, const signed char * const threadname, const char *fmt, ...) { /* whatever */ char string[SYSLOG_MAXLINE] = {0}; taskENTER_CRITICAL(); va_list args; va_start(args, fmt); length = format_string(string, sizeof string, type, threadname, fmt, args); va_end(args); taskEXIT_CRITICAL(); /* whatever */ } Вызывается это из разных задач. Функция format_string(): static size_t format_string(char *buffer, size_t size, SysLogRecordType type, const char * const threadname, const char *fmt, va_list args) { /* whatever */ vsprintf(buffer, fmt, args); /* whatever */ } Проблема в том что когда syslog_write() вызывается в разных потоках, то в vsprintf() происходит HardFault (CFSR = 0x8200). Если заменить эту функцию на что угодно типа sprintf(buffer, "hi there") то всё работает стабильно. Т.е. связано это как-то с va_list. Я честно говоря плохо понимаю как эта фишка работае. При этом вызов её обёрнут в taskENTER_CRITICAL(); Если же syslog_write() вызывается только в одном потоке, то никаких проблем. Но стоит ему вызываться в разных вытесняющих друг друга - периодические фолты.
  7. Случайно наткнулся в сети и офигел. Целая куча камней, файловые системы, сеть, гуй, шелл - с ума сойти. Руки чешутся попробовать
  8. Меня когда-то BeOS так сильно впечатлила что это напрочь сломало детскую психику и поменял детскую мечту стать лётчиком на мечту стать гиком-инженером :D Haiku всякий раз как запускаю в виртуалке пробуждает те же чувства. Но к сожалению для embedded применения её необходимо допиливать, а это колоссальная работа, в то время как GNU/Linux уже готова к бою. Так же как мысль о промышленном применении ломается на поддержке софта. Может когда-нибудь присоединюсь к разработке ARM порта just for fun, но пока времени нет на это и заказчик не станет оплачивать сотни человекочасов на портирование этой ОС когда конкуренты сделают тоже самое в 10 раз дешевле и быстрее на линуксе.
  9. У меня на таком же иногда нет растра. Всё вроде включается, а изображения нет и так периодически то работает то нет. Если найдутся спецы по этим осциллам, то мне тоже напишите плз. Может получится удалённо починить :)
  10. Конечно, так всех толковых кандидатов распугаете :) http://lurkmore.to/%D0%A3%D0%BC%D0%B5%D0%B...%BE%D0%B4%D0%B5 Опять же, что это такое? Да любой вася почитав документацию сделает свой гуй с пушбатонном и чекбоксами. А если надо хороший гуй, то тут нужен дизайнер и требование от программиста умение программировать гуй - всё равно что требование пользоваться стеклоочистителями для водителя автомобиля Не верится что в околомосковских краях да ещё в Зеленограде может быть нехватка специалистов. У нас многие готовы идти на снижение зар.платы лишь бы заниматься интересными проектами, а не дибильными играми для хомячков.
  11. 2 года - это время которое занимаюсь этим профессионально (т.е. зарабатываю деньги). До это радиолюбитель+линуксоид со времён как смог поднять паяльник, из них ещё примерно 2 года как осмысленно ломал мышление радиолюбителя в пользу мышления разработчика, кстати, читая электроникс. Т.е. можно сказать за 4 года.
  12. Были мысли такие, но решил что "продать родину" и сесть в офис за ежемесячную зарплату успею всегда, а пока трудности и свобода привлекают больше. А Вам слабо к нам? ОЭЗ, производители PCB есть, травка зелёная да море голубое и помещения+кадры дешевле в несколько раз ;) Серьёзно. Ладно большие заводы, которые чудом выжили при перестройке, избавились от старпёров в топ-менеджменте и сейчас работают на своём месте, но чем привлекательна Москва для небольших стартапов и аутсорсеров?
  13. Самый быстрый способ - https://www.google.com/search?hl=en&new...c.1.SZtx9gFkW8A полно примеров с объяснениям, всё достаточно просто. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> int main(int argc, char *argv[]) { int sock = -1; unsigned short port = 9999u; struct sockaddr_in addr; sock = socket(AF_INET, SOCK_DGRAM, 0); if(sock < 0) { perror("socket"); return EXIT_FAILURE; } memset((void *) &addr, 0x00, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr*) &addr, sizeof addr) != 0) { perror("bind"); return EXIT_FAILURE; } int bytes = 0; char buffer[128] = {0}; while(bytes >= 0) { int addr_len = sizeof addr; bytes = recvfrom(sock, buffer, sizeof buffer, 0, (struct sockaddr*)&addr, &addr_len); if(bytes == 0) { printf("Transfer aborted by peer\n"); } else if(bytes < 0) { perror("recvfrom"); } else { if(strcmp(buffer, "Tell me something") == 0) { const char *ack = "Hello, world!"; sendto(sock, ack, strlen(ack), 0, (struct sockaddr*)&addr, sizeof addr); } } memset((void *)buffer, '\0', sizeof buffer); } close(sock); return EXIT_SUCCESS; } Это concurrent сервер т.е. все запросы в одном цикле, подходит для UDP. Для TCP обычно делают в цикле блокирующий вызов accept, который возвращает сокет для нового клиента и для этого клиента создаётся новый поток, либо асинхронный ввод-вывод с помощью select. По сокетам очень много в сети информации и примеров с объяснениями https://www.google.com/search?hl=en&new...c.1.98bOenqjQYs. Я, как ни странно, это более пристально изучал по книге "Johnson M. Hart - Windows system programming", к счастью сокеты в WinAPI не сильно изуродованы виндовыми тайпдефами для каждого случая жизни и венгерской нотацией.
  14. Можно как SBW отладчик использовать http://www.msp430launchpad.com/2011/10/pro...al-targets.html В CCS появится отладчик "TI MSP430 USB". Просто прошить не знаю как с MSP430*, а у мя неен получилось с помощью mspfet через ланчпад прошивать CC430*, зато получилось через Smart RF Studio.
  15. Вот этого не знаю уже, "пока прокатывает". Никаких сведений о фирме (ИНН-ы и пр) не указывается, лишь галочка что получатель есть "company" и её название, остальная процедура заказа идентична. В инвойсе единственное отличие от физ.лица - указание названия фирмы вместо просто имени получателя, всё остальное никак не отличается от физ.лица, хотя может есть ещё какие-то дополнительные документы где это указывается и которые не выдаются получателю - этого не знаю. Риск остаётся, но пока, тьфу-тьфу-тьфу, ЕМС-ом и обычной почтой 1000 резисторов и 100 микросхем проходят спокойно. Хотя в законе есть что-то про "товарные партии", но ничего нет про критерии отличия этих "товарных партий" от обычных. Слышал от друзей что некоторые барыги даже одежду на продажу таскают обычной почтой. В общем партии со счётом на десятки одного наименования в любом случае на свой страх и риск.
  16. При оформлении заказа выбирайте доставку USPS - EMS, цена будет порядка 35-60$ в зависимости от веса. Ограничение по стоимости - 400$ в таком случае и никаких проблем с нашей таможней т.к. ЕМС - это почтовая служба, а для них ограничение на инвойс выше 1000 евро. А то что 120$ - это UPS и помимо 120$ (минимум, дальше ещё от веса зависит) попадаете на растаможку при инвойсе более то ли 5000р то ли около того. И ещё одна тонкость у диджикея появилась недавно - работают только с юр.лицами. Прокатывает ИП (sole proprietorship по ихнему), в принципе никаких документов подтверждающих наличие ИП не требуют так что по идее можно просто указать что ты юр.лицо и в имени получателя указать "Sole proprietorship Vasily Pupkin"
  17. Не правда. Иниту не важно что внутри скрипта, главное чтобы был исполняемым и шабанг (#!/bin/sh) присутствовал. start/stop и пр. - это удобства http://www.debian-administration.org/articles/28 Бесконечный цикл в init-скрипте - плохая идея. Если просто из терминала приложение запускается и работает, а из инит-скрипта - нет, то смотрите в сторону окружения, может не хватает какой-то ещё программы ему, которая есть у юзера в PATH, но сама переменная PATH на момент запуска init не содержит нужного пути. Или библиотека какая Да, но что Вам дадут дата и время сборки приложения? Тогда уж time_t t = time(NULL); fprintf(stderr, "Application %s started %s\n", argv[0], ctime(&t));
  18. Имею опыт создания БПЛА из потолочного пенопласта, бальзы и скотча :) Кстати, не смейтесь, подобный уровень вполне ничотак http://www.arms-expo.ru/049057054048124050054049054054.html когда смотрели с ребятами фотки этого чуда, то отдельно понравился объектив "Canon" торчащий из отверстия в крышке размером с фотоаппарат прикрученной разными винтами. А сами модельки очень похожи на пенолёты что у нас в кружке ребята лет 10 лепят.
  19. А если callback-и сохранять указателем в каком-то глобальном массиве? Тогда у помидоров есть доступ только к глобальному массиву, но нет и не нужно знать об "объекте" на "метод" которого указывает конкретный элемент массива.
  20. Сталкивался с подобным на LPC17 + FreeRTOS + LwIP. Только не при остановке работы, а при закрытии сразу множества TCP-соединений. Гуглом нашёлся совет что это из-за некорректной обработки пакетов из очереди emac. С езернетом в STM32 дела не имел, не знаю точно как там, а в LPC17 решилось уменьшением кол-ва DMA буферов для входящих и исходящих фреймов.
  21. Поэтому надо применять современные облачные технологии т.е. удалёнка, причём есть варианты совсем недалеко ;)
  22. char - это обычное целое число размером достаточным чтобы вместить ASCII символ - 8 бит. В арифметике/логике идентичны int. Почитайте уже наконец K&R https://www.google.com/search?q=k%26r+c+pro...lient=firefox-a или любой другой букварь по Си.
  23. Да вообще в правилах надо пункт добавить: запрещается в любом виде говорить о "тяжелом нищенском существовании" разработчиков. Или хотя бы помечать такие темы тегом "УГ" чтобы случайно не открыть это "УГ" и не испортить настроение на ночь. Ну реально противно читать нытиков и "потребителей" жалующихся на плохую страну/низкую зарплату/плохое настроение тётки в жэке и т.п. Не только страну свою, но ещё и профессию готовы с г-ном смешать в мечтах об американской мечте. Прямо как зараза какая-то распространяется по форуму..
  24. Неспешно в хорошие руки. 1988 г.р. Профессиональный пробег 2 года. Прекрасное ускорение на новые технологии. Расход - договорной. К Вашим услугам всегда онлайн Redmine + Git репозиторий с исходниками. При возможности исходники документированы с помощью Doxygen. МК: LPC17, PIC12/16/18, MSP430 (CC430), STM32, AVR. Всегда рад изучению новых. ПК: Qt, Posix API, WinAPI, STL, Boost. Языки: English, C, C++, Asm, Bash, Scilab. Интерфейсы: Ethernet, USB, SPI... и Ко. ОС: FreeRTOS, GNU/Linux, Windows. На подходе: Altera (cyclone II), embedded linux (есть BeagleBoard-xM и Raspberry Pi) пока на прикладном уровне, ковыряю OpenEmbedded и читаю Linux kernel development. Скоро приедет телефон на андроиде и к скиллам добавится ява с андроидом. Приоритеты: микроконтроллеры, сети, кроссплатформенный софт. Могу разводить 2-сторонние платы в Eagle и сопровождать производство до готового устройства. Возможно долгосрочное сотрудничество. Есть ИП, безнал. Помогу разобраться с ТЗ и предложить лучшее решение для конкретно Ваших целей. Разговорный английский на достаточном для общения с нативами уровне. Связь: cosmojam на rambler точка ru.
×
×
  • Создать...