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

Artkop

Участник
  • Постов

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

  • Посещение

Репутация

0 Обычный

Информация о Artkop

  • Звание
    Участник
    Участник
  1. Локальные переменные функции располагаются в регистрах общего назначения контроллера и при смене задачи сохраняются в область стека Register Context Storage. Соответственно при продолжении выполнения задачи этот контекст восстанавливается. Видимо как то так.
  2. Да, я ulink2 пользуюсь. Могу поставить 2 точки останова для двух задач RTX и у переменной queue видимо будут два разных адреса? Завтра на работе проверю. Спасибо за идею!
  3. То есть, локальная переменная функции становится локальной переменной задачи? Тогда если сделать локальный буфер внутри функции на много байт и вызвать ее из задачи, такая функция вполне может привести к переполнению стека! (В RL-RTX он по умолчанию 64 байта.) А функция RadiomModemSubsystem принимает на вход только номер модема, т.к. переменная queue - это номер очередь FIFO для пакетов радиомодема, и в месте вызова (в main) про подсистему обработки очередей ничего не известно. Для main она скрыта. (h файл соответствующий я не подключаю, там и так дофига всего подключено, сложно разобраться потом). Вот как это выглядит: void RadiomModemSubsystem(unsigned char numModem) { unsigned char queue = UNKNOWN_QUEUE; unsigned char *dataBuf = 0; switch(numModem) { case RADIO_MODEM_1: queue = MODEM_1_QUEUE; dataBuf = &Modem1Buffer[0]; break; case RADIO_MODEM_2: queue = MODEM_2_QUEUE; dataBuf = &Modem2Buffer[0]; break; default: return; } if (QueueIsEmpty(queue) == QUEUE_NOT_EMPTY) // если в очереди есть данные на отправку по радиомодему { FreeString(&dataBuf[0], BUF_MAX_SIZE); // очищаем буфер SetRadioModemToCtrlMode(numModem); SendCmdToRadioModem(RM_REQUEST_STATUS, &dataBuf[0], numModem); // отправляем команду ReceivePacketFromRadioModem(&dataBuf[0], numModem); // получаем статус модема // обрабатываем статус .. // .. SetRadioModemToDataMode(numModem); RetrieveDataFromQueue(&dataBuf[0], &sizeOfData, queue); // извлекаем пакет из очереди // оправляем пакет ... } } А буфер радиомодема dataBuf можно и так сделать: __task void modem2(void) { unsigned char Modem2Buffer[bUF_MAX_SIZE] = {0x00}; while(1) { RadiomModemSubsystem(RADIO_MODEM_2, &Modem2Buffer[0]); } } но тогда задачу нужно инициализировать с помощью ф-ии os_tsk_create_user (делать ей стек большой отдельно). В этом нет необходимости.
  4. Keil RL-RTX

    Всем привет! Использую операционку Keil RL-RTX. Определено две задачи, имеющие одинаковый приоритет и выполняющиеся параллельно: //---------------------------------------------------------------------------------------------------- /*! \brief Задача RTX для работы с радиомодемом 1, подключенным к порту uart 0 */ //---------------------------------------------------------------------------------------------------- __task void modem1(void) { while(1) { RadiomModemSubsystem(RADIO_MODEM_1); } } //---------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------- /*! \brief Задача RTX для работы с радиомодемом 2, подключенным к порту uart 2*/ //---------------------------------------------------------------------------------------------------- __task void modem2(void) { while(1) { RadiomModemSubsystem(RADIO_MODEM_2); } } //---------------------------------------------------------------------------------------------------- Как видно, задачи вызывают одну и туже функцию. Создается ли для каждой задачи свой экземпляр функции со своими локальными переменными? Вот эта функция: static unsigned char Modem1Buffer[bUF_MAX_SIZE] = {0x00}; static unsigned char Modem2Buffer[bUF_MAX_SIZE] = {0x00}; void RadiomModemSubsystem(unsigned char numModem) { unsigned char queue = UNKNOWN_QUEUE; unsigned char *dataBuf = 0; switch(numModem) { case RADIO_MODEM_1: queue = MODEM_1_QUEUE; dataBuf = &Modem1Buffer[0]; break; case RADIO_MODEM_2: queue = MODEM_2_QUEUE; dataBuf = &Modem2Buffer[0]; break; default: return; } // здесь управление и обмен с модемом } Интересует, что будет с переменными queue и *dataBuf. Задача modem 1 вызывает функцию RadiomModemSubsystem с параметром RADIO_MODEM_1. Для локальных переменных queue и *dataBuf выделяется память, идет выполнение. Задача modem 1 израсходовала свой квант времени и теперь выполняется задача modem 2. Задача modem 2 вызывает функцию RadiomModemSubsystem с параметром RADIO_MODEM_2 и для локальных переменных queue и *dataBuf выделяется новая память (то есть, это экземпляр функции для другой задачи), правильно? Не будет ситуации, что адреса локальных переменных совпадут, и мы перепишем буфер dataBuf и номера очереди queue другой задачи.
  5. LPC2478 в abort mode

    спасибо за совет! Начал разбираться. как понимаю, например это мне поможет http://electronix.ru/forum/index.php?showt...mp;#entry429864
  6. LPC2478 в abort mode

    Добрый вечер! Написал небольшой проект на основе EMAC в keil для LPC2478. Конфигурирую интерфейс, все ок. В бесконечном цикле жду прерывания по приему ethernet фрейма, но по этому самому прерыванию сваливаюсь в abort mode. Что интересно - пакет то приходит. Если при конфигурировании интерфейса не разрешать его прерывание в векторном контроллере прерываний, а опрашивать флаг MAC_INTSTATUS самому, то принятый пакет можно обрабатывать. Но хотелось бы все таки с прерываниями... Кто нибудь с подобным сталкивался?
  7. Genadi Zawidowski: Без volatile (и соответственно с включенной оптимизацией по скорости) строб получился 100нс! В пять раз короче! (компилятор IARовский)
  8. DmitryM: Да, и правда можно! D[0..7], CS, Read и Write есть! Правда необходимо добавить еще 2 линии. Но эти линии (команда/данные и reset) можно и в ручную дергать. Genadi Zawidowski: volatile используется для того, чтобы в обработчике прерываний изменять переменную. (я там запрещаю прерывание, типа такого (например для SPI) pSPI->SPI_IDR = AT91C_SPI_RDRF) Ну и компилятор не должен ее оптимизировать. Хотя вот написал это, а для PIOA никаких обработчиков еще нет, да и не будет наверное, и ничто параллельно выполнению основной задачи структуру PIO не изменит. И PMC я не правлю, только при включении и инициализации. Спасибо за наводки, будем думать!)
  9. Спасибо! Буду смотреть. Пока сделал так: pPIO->PIO_CODR = 0x400; pPIO->PIO_CODR = 0x1000; pPIO->PIO_ODSR = 0xFF; pPIO->PIO_ODSR = 0x00; pPIO->PIO_SODR = 0x1000; pPIO->PIO_SODR = 0x400; CS (это который 0x1000) длительностью 2 мк сек получился...
  10. Доброго времени суток! Необходимо соединить at91sam7se и дисплейный OLED модуль (контроллер SSD1305). Для этого надо написать софтверный протокол на PIO (8080 параллельный интерфейс). Разбираюсь.. Выяснил, что можно выставлять уровни ножек PIO (в моем случае PIOA) регистрами PIO_SODR и PIO_СODR. Но если делать это в программе, в ручную, то временные диаграммы получаются не пойми какими. Для синхронной записи используется PIO_ODSR, я правильно понимаю? Делаю так: //---------------------------------------------------------------------------------- volatile AT91PS_PIO pPIO = AT91C_BASE_PIOA; volatile AT91PS_PMC pPMC = AT91C_BASE_PMC; pPMC->PMC_PCER = (1<<AT91C_ID_PIOA); pPIO->PIO_PER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 | AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7 | AT91C_PIO_PA8 | AT91C_PIO_PA9 | AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 | AT91C_PIO_PA14 | AT91C_PIO_PA15; pPIO->PIO_OER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 | AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7 | AT91C_PIO_PA8 | AT91C_PIO_PA9 | AT91C_PIO_PA10 | AT91C_PIO_PA11 | AT91C_PIO_PA12 | AT91C_PIO_PA14 | AT91C_PIO_PA15; pPIO->PIO_OWER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 | AT91C_PIO_PA4 | AT91C_PIO_PA5 | AT91C_PIO_PA6 | AT91C_PIO_PA7; pPIO->PIO_ODSR = 0xFF; // pPIO->PIO_ODSR = 0x00; // Сформировал строб на 8битной шине //------------------------------------------------------------------------------------------------------------------------------------ Но длительность импульса получилась 600 нс. Как ее уменьшить?
  11. USB

    Всем доброго дня! Вот такой вот вопрос: Имеется конечная точка EP2, настроенная в режим Slave FIFO AUTOOUT. void TD_Init(void) { CPUCS = ((CPUCS & bmCLKSPD) | ~bmCLKSPD1) ; EP1OUTCFG = 0xA0; EP1INCFG = 0xA0; SYNCDELAY; REVCTL = bmNOAUTOARM && bmSKIPCOMMIT; SYNCDELAY; FIFORESET = 0x80; // reset all FIFOs SYNCDELAY; FIFORESET = 0x02; SYNCDELAY; FIFORESET = 0x00; SYNCDELAY; IFCONFIG = 0x03; // EP2CFG = 0xA2; SYNCDELAY; EP2FIFOCFG = 0x10; SYNCDELAY; OUTPKTEND = 0x82; SYNCDELAY; OUTPKTEND = 0x82; SYNCDELAY; // enable dual autopointer feature AUTOPTRSETUP |= 0x01; Rwuen = TRUE; } Какое состояние регистра EP2CS должно быть при включении питания? Дело в том, что при таком конфигурировании у меня EP2CS = 28 (То есть фифо FULL) Но ведь по включении там должно быть EP2CS = 04. (То есть EMPTY = 1) Или нет? Откуда там данные то возьмутся..
  12. АДИКМ, ошибка моя, все прошивается) Пытался прошить кнопочкой small EPPROM, а надо large 64k EPPROM) У меня же в свойствах проекта именно выставлено 64k ROM. Спасибо за ответы!
  13. Добрый день! Каким образом вы инициализируете EPPROM? Просто отключаете джампер и через сайпрессконсоль пишете в память? У меня после подобных манипуляций (на digilentовскую плату я впаял джампер (на схеме jp2)) без джампера грузится как EPPROM missing. После соединения джампера и попытки прошить консоль говорит - EPPROM not enabled..
  14. C дескрипторами все ок, та же прошивка, зашитая в ром, работает и определяется как надо. Возможно что то с адресацией не то, я в этом еще не очень разобрался.. И да, посмотрю EZUSB_Discon(), спасибо!
  15. USB

    Про этот раздел я и говорю. Там есть временная диаграмма чтения из FIFO мастером и описание. IDLE: When read event occurs, transition to State 1. STATE 1: Point to OUT FIFO, assert FIFOADR[1:0], transition to State 2. STATE 2: Assert SLOE. If FIFO-Empty flag is false (FIFO not empty), transition to State 3 else remain in State 2. STATE 3: Sample data on the bus, increment pointer by asserting SLRD for one IFCLK, de-assert SLOE, transition to State 4. STATE 4: If more data to read, transition to State 2 else transition to IDLE. STATE 1 как начнется? По выставленному флагу FLAGC (FIFO-Empty flag)? В мк приходят данные, он выставляет FIFO-Empty flag (Не пустой). Пусть ПЛИС реагирует на FIFO-Empty flag, выставляет SLOE, SLRD и читает. Так? :)
×
×
  • Создать...