Jump to content

    

Digi

Свой
  • Content Count

    161
  • Joined

  • Last visited

Community Reputation

0 Обычный

About Digi

  • Rank
    Частый гость
  • Birthday 07/10/1978

Контакты

  • Сайт
    http://
  • ICQ
    177155423
  1. Ясное дело, что ошибка у меня. Виснет не мьютекс, а функция работы с СД картой. Зависала в цикле ожидания какого-то состояния с карты (уже не помню какого именно) внутри низкоуровневой функции. Причём это происходило при работе с несколькими файлами. Сейчас работаю в один момент времени только с одним файлом. Но это временно )) Да, обращения к СД у меня блокировались мьютексами, но тем не менее проблема была. Поэтому и спросил, как это правильно реализовать. Планирую переосмыслить и переделать как положено )
  2. Так пытался делать, но либо чего то упустил, либо что то ещё. Иногда при обращении к карте, функция (уже не помню какая) зависала внутри. А кто нибудь такое, в такой конфигурации, реализовывал ?
  3. Пишу проект на STM32 с использованием FreeRTOS и для доступа к SD карте - FAT FS. У меня в проекте есть несколько задач, из которых я планирую записывать информацию в файлы на SD. Лог файлы, результаты. Таких файлов 3. Например логи будут писаться (дописываться) сразу из нескольких задач в один файл. Как правильно и красиво реализовать такое обращение ?
  4. Нет, не запрещал. Меня интересовало сколько времени уходит на этот процесс при штатной работе. Пришёл к выводу: так как время нахождения в прерывании не превышает периода следования данных, то нет необходимости проверять в этом же цикле оставшиеся данные в FIFO.
  5. Измерял по осцилу )) с ножки GPIO. Давно мерил время переключения ноги, получалось около 100 нс Но мог и ошибиться
  6. Может неправильно выразился. Я измерял время выполнения кода внутри прерывания, время реакции на прерывание не измерял. Ещё для информации, программа и данные лежит во внешней SDRAM. Во внутренней пока не стал размещать, производительности хватает, а объем данных большой, внутренней памяти не хватает.
  7. Всем большое спасибо за замечания, советы и разъяснения. Да, код действительно тяжеловат, но со временем переделаю, как только придёт полное осознание происходящих процессов. Для информации: фактическое время обработчика составляет 16-25 мкс, этого достаточно до скоростей вплоть до 350 кбит/с. По поводу увеличения стека - сейчас стеки всех задач в два раза (было 0x1000 ). Возможно одной задаче его и не хватало. Время покажет. Сейчас в процессе работы смотрю место в стеке unused = task_stack_avail (uart422_task_s); Stack rcv 7472 Stack RS422 7504 Stack RS485 7500 Stack CTL 3376 Stack Print 7504 Вот что выдаёт.
  8. С мутексами вроде немного разобрался. Прога перестала падать при передаче большого,непрерывного потока данных. Создал три мутекса: irq, receieve, transmit. irq - повесил на прерывание, остальные соответственно блокируют обращения к данным обработчика приема и передачи соответственно. То есть я при начале работы с буфером приемника блокирую мутекс, а после снимаю блокировку. Если мне нужно принудительно пнуть прерывание приёма/передачи, то я отправляю mutex_signal(&current_uart->irq,0); Правильно ли я понял ? Код функций под спойлером. И ещё вопрос. Как понять, что приводит к краху ? Программа работает, никаких действий не произвожу. В интервале полчаса - несколько часов программа падает вот с такой ошибкой (Спойлер)
  9. Я же указал, МК - Multicore. Только дело тут не в скорости обработки (это уже следующий момент оптимизации, а в том что я криво написал код). Так как с uOS раньше не имел дела, пытаюсь разобраться в особенностях. в uart244_receiever ожидается прерывание, затем в uart422_rtx_proc я проверяю, есть ли данные для приёма, а вот то что после mutex_lock_irq (&u->receiver, RECEIVE_IRQ(u->port), 0, 0) он остаётся захвачен, не знал. Да, ассерты отключены. Про кривое использование мьютексов понял. Попробую исправить.
  10. Что бы не плодить сообщения, продолжу в этой теме. Продолжаю безуспешную войну с uOS. Сейчас вычищаю баги в проекте. Ситуация такая: Использую аппаратный UART в Multicore. Всё работает, но если поток данных по UART идёт сплошняком, есть предположения, что прерывание приходит чаще, чем проц успевает его обработать, то он уходит в функцию void mutex_activate (mutex_t *m, void *message) и остаётся там навсегда (крутится внутри while() ). Кто с этим сталкивался ? Как побороть и куда ещё посмотреть ? Ниже привожу инициализацию порта /* * Receive interrupt task. */ void uart422_receiver (void *arg) { uartpkt_t *u = arg; // Enable receiver & transmitter mutex_lock_irq (&u->receiver, RECEIVE_IRQ(u->port), 0, 0); enable_receiver (u->port); enable_receive_interrupt (u->port); debug_printf("Uart422 started.\n"); for (;;) { mutex_wait (&u->receiver); // Ожидаем событие по приему или по принудительному пинку для передачи #ifdef clear_receive_errors clear_receive_errors (u->port); #else if (test_frame_error (u->port)) { //debug_printf ("FRAME ERROR\n"); clear_frame_error (u->port); } if (test_parity_error (u->port)) { //debug_printf ("PARITY ERROR\n"); clear_parity_error (u->port); } if (test_overrun_error (u->port)) { //debug_printf ("RECEIVE OVERRUN\n"); clear_overrun_error (u->port); } if (test_break_error (u->port)) { // debug_printf ("BREAK DETECTED\n"); clear_break_error (u->port); } #endif uart422_rtx_proc(u); // Вызываем функцию обработчика события с USART // task_yield(); } } void uart422_init (uartpkt_t *u, small_uint_t port, int prio, unsigned int khz, unsigned long baud) { u->khz = khz; u->port = (port) ? (volatile unsigned*)(0xb82f3800) : (volatile unsigned*)(0xb82f3000); mutex_init(&u->receiver); /* Setup baud rate generator. */ setup_baud_rate (u->port, u->khz, baud); /* Create uart receive task. */ uart422_task_s = task_create (uart422_receiver, u, "uart422", prio, u->rstack, sizeof (u->rstack)); } Функция работы с портом static bool_t uart422_rtx_proc (uartpkt_t *u) { unsigned char tx_char=0; unsigned char c=0; if (test_get_receive_data(u->port, &c)) { mutex_lock(&u->receiver); switch (c) { case 0xff: break; ...... default: if (u->rx_packet.data_in_process==1) { if (u->rx_packet.addcode!=0) { c = c + 0xfd; // дополняем принятое значение u->rx_packet.addcode= 0; } u->rx_packet.pkt_buffer.p_buffer[u->rx_packet.ptr] = c; u->rx_packet.ptr = (u->rx_packet.ptr < MAX_CTL_SIZE) ? (u->rx_packet.ptr + 1) : u->rx_packet.ptr; // На всякий случай ограничим прием при переполнении u->rx_packet.crc= (u->rx_packet.crc + c) & 0xff; } break; } mutex_unlock(&u->receiver); } // ------------ Transmit section ------------------ // Check that transmitter buffer is busy. if (! test_transmitter_empty (u->port)) { return 1; } if (u->tx_packet.data_in_process==2) { // Функция для завершения передачи и перевода трансивера на приём // delay(25); // !!! возможно будет отжирать системное время по завершини передачи // RS485_SetRxMode(); u->tx_packet.data_in_process=0; disable_transmit_interrupt (u->port); u->tx_packet.total_packets++; mutex_unlock(&u->transmitter); // Снимаем блокировку return 0; } ...... } } return 1; } И сама функция в которой проц застревает (из uOS/main.c) (пробовал ставить UOS_SIGNAL_SMART =0, результат такой же) void mutex_activate (mutex_t *m, void *message) { task_t *t; mutex_slot_t *s; assert (m != 0); if (! m->item.next) mutex_init (m); while (! list_is_empty (&m->waiters)) { t = (task_t*) list_first (&m->waiters); assert2 (t->wait == m , "assert task %s(0x%x) wait %x activate from %x($%x)\n" , t->name, (unsigned)t , t->wait, m, (unsigned)message );//uos_assert_task_name_msg t->wait = 0; t->message = message; #if UOS_SIGNAL_SMART > 0 //получили сигнал, и жду захвата мутеха, потому пермещу нитку из ожидания сигнала в // захватчик мутеха if (t->MUTEX_WANT != 0) if (mutex_wanted_task(t)) continue; #endif task_activate (t); } ........
  11. Bus в Altium Designer

    Не буду плодить тему, просто оживлю "покойничка" )) Рисую в Altium многостраничную схему по ГОСТ. Дошло дело до расстановки NetLabel c одного листа на другом листе. В настройках проекта все цепи глобальные, у шин названия не проставлял. Но при установке NetLabel на втором листе Altium не видит его имя с первого, видит только цепи со второго. Например на первом листе цепь называется ADC1_D1, хочу поставить NetLabel на втором листе, выбрав его из списка. Но его там нет. Тем не менее если имя прописать руками, то в списке соединений всё корректно подключается. Вопрос: как сделать так, чтобы все цепи проекта были видны в списке выбора цепи, или нужно искоренить у себя такую привычку использовать такой выбор ?
  12. Хочу запитать антенный усилитель по кабелю. Какие есть минусы, если на стороне усилителя я не буду разделять питание и сигнал , а сразу подключу кабель к выходу усилителя, так как на второй схеме ? Рабочая частота 900 МГц, сигнал узкополосный. Длина кабеля 20 метров.
  13. Цитата(jcxz @ Feb 26 2018, 15:35) К прерываниям uCOS вообще никакого отношения не имеет. Кроме PendSV и немножко SysTick. У меня uOS а не uCOS, они немного разные как мне кажется. В uOS за обработку прерываний отвечают функции: mutex_lock_irq () Захват прерывания mutex_unlock_irq () Освобождение прерывания mutex_wait () Ожидание прерывания
  14. С этим разобрался. Заработало. Спасибо всем ответившим. Отдельное спасибо vatilin за подробные объяснения. По поводу задержки, я ее ставил просто как задержку. В реальной программе так не пишу. Ну и посмотрел я реализацию udelay в uOS, оказалось что она просто тупо ждет, и к сожалению она не аналог Sleep в RTOS. Теперь разбираюсь с прерываниями.... вроде как работают, но пока еще не привычно для меня.
  15. Пытаюсь запустить несколько различных задач на uOS которая поставляется совместно с пакетом MCStudio, но работает не так как ожидалось. Собственно никакой многозадачности не наблюдаю. Работает только та задача у которой наивысший приоритет. (В данном случае task ). Что я хотел получить: должны мигать три светодиода, и по приходу данных с UART должен заходить в обработчик uart_intr_hdl. Вроде как такая конструкция на RTOS STM32 работает корректно, но тут, на uOS никак не желает. Что я делаю не так ??? bool_t uart_intr_hdl(void *arg) { ch = get_received_byte(1); LedTgl(1); return 1; } void task1 (void *arg) { for(;;) { LedTgl(8); udelay(30000); } } void task2 (void *arg) { for(;;) { LedTgl(4); udelay(40000); } } void task (void *arg) { setup_baud_rate (1, KHZ, 115200); mutex_lock_irq (&receiver, RECEIVE_IRQ (1), &uart_intr_hdl, 0); enable_receiver (1); enable_receive_interrupt (1); transmit_byte(1, '*'); for (;;) { udelay(50000); LedTgl(2); } // for(;;) } void uos_init (void) { SYS_REG.CLK_EN.data = 0xFFFFFFFF; // включение тактовой частоты _init_ включает только минимум частот LedInit(); MFBSP2.DIR.data = 0x3ff; // переключаем LDAT2[7:4] в режим выхода task_create (task1, 0, "task1", 1, task1_space, sizeof (task1_space)); task_create (task2, 0, "task2", 2, task2_space, sizeof (task2_space)); task_create (task, "task", "task", 3, task_space, sizeof (task_space)); }