Jump to content

    

M0HAX

Участник
  • Content Count

    31
  • Joined

  • Last visited

Community Reputation

0 Обычный

About M0HAX

  • Rank
    Участник
  1. Привет всем! В документации по xTaskAbortDelay() конкретно не написано,что эта функция относится только к задачам с vTaskDelay(). Попытался xTaskAbortDelay() применить к задаче, которая уходит в спячку по vTaskDelayUntil(). В итоге получил постоянно вызываемую задачу с игнором задержки. Это недоработка FreeRTOS-а или просто связка xTaskAbortDelay & vTaskDelayUntil в принципе не должна работать совместно? Нашел в ответах. xTaskAbortDelay not updating pxPreviousWakeTime Хоть они обещали в декабре исправить доку, но я скачивал недавно - ничего не отражено
  2. Здравствуйте! Из демопакета FreeRTOS взял драйвер Ethernet для CORTEX LPC1768 и переделал под LPC2388. Имеем процедуру передачи данных: #define emacTX_DESC_INDEX (0) /* EMAC variables located in ETHERNET_RAM */ #define ETHERNET_RAM 0x7FE00000UL #define RX_DESC_BASE (ETHERNET_RAM) /* 0x7FE00000*/ #define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* =0x7FE00018, 2 * uint32_t, see RX_DESC_TypeDef */ #define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* =0x7FE00030, 2 * uint32_t, see RX_STAT_TypeDef */ #define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* =0x7FE00040, 2 * uint32_t, see TX_DESC_TypeDef */ #define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* =0x7FE00048, 1 * uint32_t, see TX_STAT_TypeDef */ /* RX and TX descriptor and status definitions. */ #define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) /* =0x7FE00000, =0x7FE00008, =0x7FE00010 */ #define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) /* =0x7FE00004, =0x7FE0000C, =0x7FE00014 */ #define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) /* =0x7FE00018, =0x7FE00020, =0x7FE00028 */ #define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) /* =0x7FE0001C, =0x7FE00024, =0x7FE0002C */ #define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) /* =0x7FE00030, =0x7FE00038 */ #define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) /* =0x7FE00034, =0x7FE0003C */ #define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) /* =0x7FE00040, =0x7FE00044 */ #define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) /* =0x7FE00048, =0x7FE00648, =0x7FE00C48 */ #define ETH_NUM_BUFFERS ( NUM_TX_FRAG + NUM_RX_FRAG + 1 ) /* There are in fact 2 more buffers than descriptors as the two Tx descriptors use the same buffer to speed up the uip Tx. */ ....................... void vSendEMACTxData( unsigned short usTxDataLen ){ unsigned long ulAttempts = 0UL; /* Check to see if the Tx descriptor is free, indicated by its buffer being NULL. */ while( TX_DESC_PACKET( emacTX_DESC_INDEX ) != ( unsigned long ) NULL ) { /* Wait for the Tx descriptor to become available. */ vTaskDelay( emacBUFFER_WAIT_DELAY ); ulAttempts++; if( ulAttempts > emacBUFFER_WAIT_ATTEMPTS ) { /* Something has gone wrong as the Tx descriptor is still in use. Clear it down manually, the data it was sending will probably be lost. */ prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) ); break; } } /* Setup the Tx descriptor for transmission. Remember the length of the data being sent so the second descriptor can be used to send it again from within the ISR. */ usSendLen = usTxDataLen - 1; TX_DESC_PACKET( emacTX_DESC_INDEX ) = ( unsigned long ) uip_buf; TX_DESC_CTRL( emacTX_DESC_INDEX ) = ( usTxDataLen | TCTRL_LAST | TCTRL_INT ); EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 ); /* uip_buf is being sent by the Tx descriptor. Allocate a new buffer. */ uip_buf = prvGetNextBuffer(); } и само прерывание __arm void vEMAC_ISR(){ unsigned long ulStatus; long lHigherPriorityTaskWoken = pdFALSE; ulStatus = EMAC->IntStatus; /* Clear the interrupt. */ EMAC->IntClear = ulStatus; if (ulStatus & INT_TX_ERR){ LEDSOn(_VD1); }; if (ulStatus & INT_RX_DONE){ /* Ensure the uIP task is not blocked as data has arrived. */ xSemaphoreGiveFromISR(xEMACSemaphore, &lHigherPriorityTaskWoken); }; if (ulStatus & INT_TX_DONE){ if (usSendLen > 0){ /* Send the data again, using the second descriptor. As there are only two descriptors the index is set back to 0. */ TX_DESC_PACKET( ( emacTX_DESC_INDEX + 1 ) ) = TX_DESC_PACKET( emacTX_DESC_INDEX ); TX_DESC_CTRL( ( emacTX_DESC_INDEX + 1 ) ) = ( usSendLen | TCTRL_LAST | TCTRL_INT ); EMAC->TxProduceIndex = ( emacTX_DESC_INDEX ); /* This is the second Tx so set usSendLen to 0 to indicate that the Tx descriptors will be free again. */ usSendLen = 0UL; } else { /* The Tx buffer is no longer required. */ prvReturnBuffer( ( unsigned char * ) TX_DESC_PACKET( emacTX_DESC_INDEX ) ); TX_DESC_PACKET( emacTX_DESC_INDEX ) = (unsigned long)NULL; }; }; portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); VICADDRESS = 0; } При вызове vSendEMACTxData в драйвере запоминается глобальная переменная usSendLen, затем после EMAC->TxProduceIndex = ( emacTX_DESC_INDEX + 1 ); вызывается прерывание с выставленным битом INT_TX_DONE в статусе. И вот здесь непонятно, почему так делается внутри "if". Ведь бит INT_TX_DONE означает, что уже все передано, но почему автор драйвера снова копирует эти же данные в следующий дескриптор и снова их передает? Ладно,если бы проверялся бит,отвечающий за ошибки передачи, и затем снова пакет бы передался заново, но тут получается так, что пакет передается повторно при каждой новой передаче. Не понимаю смысла этой глобальной переменной usSendLen. Она больше нигде не используется в драйвере. Может кто разъяснит?
  3. Был рабочий проект для IAR 5.41. Все запускалось, все работало. Поставил IAR 7.20.2(тоже самое и с IAR 7.30). Загрузил тот проект. Откомпилировал с теми же опциями. Запускаю отладчик и вижу удивительные вещи. Стандартная процедура инициализации тактового генератора не работает. /* инициализация тактового генератора */ SCS_bit.OSCRANGE = 0; // 0 = The frequency range of the main oscillator is 1 MHz to 20 MHz SCS_bit.OSCEN = 1; // 1 = The main oscillator is enabled, and will start up if the correct external circuitry is connected to the XTAL1 and XTAL2 pins. while(!SCS_bit.OSCSTAT); // ожидание выставления Зацикливается на while. Стал смотреть ассемблер. //------------------------------------------------------- // 115 /* инициализация тактового генератора */ // 116 SCS_bit.OSCRANGE = 0; LDR R0,??DataTable0;; 0xe01fc1a0 BL __aeabi_uread4 LDR R1,??DataTable0;; 0xe01fc1a0 BICS R0,R0,#0x10 BL __aeabi_uwrite4 // 117 SCS_bit.OSCEN = 1; LDR R0,??DataTable0;; 0xe01fc1a0 BL __aeabi_uread4 LDR R1,??DataTable0;; 0xe01fc1a0 ORRS R0,R0,#0x20 BL __aeabi_uwrite4 // 118 while(!SCS_bit.OSCSTAT); И сравнил с тем, что компилирует IAR 5.41 // 114 /* инициализация тактового генератора */ // 115 SCS_bit.OSCRANGE = 0; // 0 = The frequency range of the main oscillator is 1 MHz to 20 MHz LDR R0,??DataTable0;; 0xe01fc1a0 LDR R0,[R0, #+0] BICS R0,R0,#0x10 LDR R1,??DataTable0;; 0xe01fc1a0 STR R0,[R1, #+0] // 116 SCS_bit.OSCEN = 1; // 1 = The main oscillator is enabled, and will start up if the correct external circuitry is connected to the XTAL1 and XTAL2 pins. LDR R0,??DataTable0;; 0xe01fc1a0 LDR R0,[R0, #+0] ORRS R0,R0,#0x20 LDR R1,??DataTable0;; 0xe01fc1a0 STR R0,[R1, #+0] // 117 while(!SCS_bit.OSCSTAT); // ожидание выставления Вижу, что добавились процедуры __aeabi_uread4 и __aeabi_uwrite4. Раскрываем процедуру __aeabi_uwrite4 Та операция, которая выделена зеленым, приводит к тому, что выставленный уже бит OSCEN(и статус OSCSTAT тоже уже в 1) сбрасывается в 0, соответственно, сбрасывается и OSCSTAT. После этого благополучно прога зацикливается на проверке while(!SCS_bit.OSCSTAT); Поигрался с опциями в проекте - не помогло. Посмотрел листинги файла main.c, в котором происходит инициализация, в IAR 5.41 и IAR 7.20, но листинги с опциями оказались одинаковыми, т.е. компилятор в IAR 7.20 стал по другому компилировать. Листинг в IAR 5.41 # Cpu mode = arm # # Endian = little # # Source file = F:\ARM\LPC\5.41\Gazochrom\main.c # # Command line = F:\ARM\LPC\5.41\Gazochrom\main.c -D LPC2000_IAR -D # # IAR_LPC_2378_SK -D FREERTOS_OVER_7_4_2 -D DEBUG -D # # PACK_STRUCT_END= -lcN F:\ARM\LPC\5.41\Gazochrom\Debug\Li # # st\ -lB F:\ARM\LPC\5.41\Gazochrom\Debug\List\ # # --diag_suppress pa039,pa093,pe815,pe191,pa082,pe167,pe55 # # 0,pe111,pe174 -o F:\ARM\LPC\5.41\Gazochrom\Debug\Obj\ # # --no_cse --no_unroll --no_inline --no_code_motion # # --no_tbaa --no_clustering --no_scheduling --debug # # --endian=little --cpu=ARM7TDMI-S -e --fpu=None # # --dlib_config "F:\IAR Systems\Embedded Workbench # # 5.4\arm\INC\DLib_Config_Normal.h" -I # # F:\ARM\LPC\5.41\Gazochrom\ -I # # F:\ARM\LPC\5.41\Gazochrom\Include\ -I # # F:\ARM\LPC\5.41\Gazochrom\Portable\Include\ -I # # F:\ARM\LPC\5.41\Gazochrom\Connection\ETHERNET\Include\ # # -I F:\ARM\LPC\5.41\Gazochrom\Connection\USB\modules\ -I # # F:\ARM\LPC\5.41\Gazochrom\Connection\USB\app\ -I # # F:\ARM\LPC\5.41\Gazochrom\SDCard\Include\ -I # # F:\FreeRTOS\FreeRTOSV7.5.3\FreeRTOS\Source\include\ -I # # "F:\IAR Systems\Embedded Workbench 5.4\arm\INC\" # # --interwork --cpu_mode arm -On # # List file = F:\ARM\LPC\5.41\Gazochrom\Debug\List\main.lst # # Object file = F:\ARM\LPC\5.41\Gazochrom\Debug\Obj\main.o # Листинг в IAR 7.20 # Cpu mode = arm # Endian = little # Source file = F:\ARM\LPC\IAR_7\Gazochrom\main.c # Command line = # F:\ARM\LPC\IAR_7\Gazochrom\main.c -D LPC2000_IAR -D IAR_LPC_2378_SK -D # FREERTOS_OVER_7_4_2 -D DEBUG -D PACK_STRUCT_END= -lcN # F:\ARM\LPC\IAR_7\Gazochrom\Debug\List\ -lB # F:\ARM\LPC\IAR_7\Gazochrom\Debug\List\ --diag_suppress # pa039,pa093,pe815,pe191,pa082,pe167,pe550,pe111,pe174 -o # F:\ARM\LPC\IAR_7\Gazochrom\Debug\Obj\ --no_cse --no_unroll --no_inline # --no_code_motion --no_tbaa --no_clustering --no_scheduling --debug # --endian=little --cpu=ARM7TDMI-S -e --fpu=None --dlib_config "F:\IAR # Systems\Embedded Workbench 7.0\arm\INC\c\DLib_Config_Normal.h" -I # F:\ARM\LPC\IAR_7\Gazochrom\ -I F:\ARM\LPC\IAR_7\Gazochrom\Include\ -I # F:\ARM\LPC\IAR_7\Gazochrom\Portable\Include\ -I # F:\ARM\LPC\IAR_7\Gazochrom\Connection\ETHERNET\Include\ -I # F:\ARM\LPC\IAR_7\Gazochrom\Connection\USB\modules\ -I # F:\ARM\LPC\IAR_7\Gazochrom\Connection\USB\app\ -I # F:\ARM\LPC\IAR_7\Gazochrom\SDCard\Include\ -I # F:\FreeRTOS\FreeRTOSV7.5.3\FreeRTOS\Source\include\ --interwork # --cpu_mode arm -On # List file = F:\ARM\LPC\IAR_7\Gazochrom\Debug\List\main.lst # Object file = F:\ARM\LPC\IAR_7\Gazochrom\Debug\Obj\main.o Немного изменил операции на C. Стало выглядеть так SCS &= ~(1 << SCS_OSCRANGE); SCS |= 1 << SCS_OSCEN; while (!(SCS & (1 << SCS_OSCSTAT))); Но компилятор сделал тот же ассемблерный код с вызовами __aeabi-процедур, что и первоначально. Проблема не исчезла (( Мало того, что появилась куча операций дополнительных(минус скорости), так еще делает невозможным работу программы. ПС. Причина-то нашлась, но все равно вопросы остались Видать, новый компилятор стал более строг к директивам. Использовалась директива #pragma pack(1) . Описанная выше процедура подпадала под действие этой директивы, но компилятор от IAR 5.41 реагировал в данном конкретном месте программы иначе, чем компилятор от IAR 7.20.
  4. Получил новый комп, поставил Win7, iar7.20.2, последний segger-овский драйвер 4.94g к J-Link. Все заработало - грузится как надо.
  5. да, в выходные в книжке про кортекс прочитал это. В исходном файле после elf-заголовка лежит нормальный адрес стека согласно map-файлу. Похоже, эмулятор грузит с ошибкой, выдает сообщение Verify error at address 0x00000000, target byte: 0x20, byte in file: 0xB8 и более 200 ошибок. пока не могу разобраться, в чем проблема:питание,кабель и т.д. Еще есть вопрос. Загрузил эмулятор программу. Открываю дизассемблер. Отправляюсь в том окне смотреть,что лежит по адресу 0x00000000. Вижу,что то значение,которое загрузилось в SP, лежит по адресу 0x00000004. Вот это мне непонятно. Ведь значение SP должно лежать по адресу 0x00000000. Меня интересует, что может лежать по адресу 0x00000000 и почему там не значение SP(пусть хоть на данный момент и неправильное), откуда взялось такое смещение
  6. Имеется iar 7.20. Взял пример для Cortex LPC1549 из iar 7.30. Загрузил проект в iar 7.20. Отладчик J-Link ARM v8 (версия драйвера v4.94g). В проекте указал, что отладчиком явлется J-Link. При загрузке выдается предупреждение "--------------------------- Driver --------------------------- Warning: Stack pointer is setup to incorrect alignment. Stack addr = 0x030000B9 --------------------------- ОК ---------------------------" При этом подцеплен правильный icf-файл для LPC1549 /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x02000000; define symbol __ICFEDIT_region_RAM_end__ = 0x02008FDF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x1000; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section. ###ICF###*/ define symbol __CRP_start__ = 0x000002FC; define symbol __CRP_end__ = 0x000002FF; define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__] - mem:[from __CRP_start__ to __CRP_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CRP_region = mem:[from __CRP_start__ to __CRP_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; place in CRP_region { section .crp }; Т.е. CSTACK находится в диапазоне адресов [0x02000000 - 0x02008FDF]. А при загрузке вдруг SP получает значение 0x030000B9, а диапазон адресов [0x03000000 - 0x03008000] принадлежит 32kB boot ROM согласно даташиту. Отладчик затем догружается, но указатель отладчика встает на некий адрес программы и стоит там, не реагируя на пошаговые инструкции. В чем может быть дело? До этого работал с АРМ7 и iar 5.41, там немного по-другому, а тут столкнулся с этой проблемой. FLASH проца до этого стирал с помощью отдельного запуска j-link.
  7. FAT16/32 для ARM

    не зависит. может перестать обновлять даже,если 2 файла подряд запишишь на карточку. Между 2-мя файлами проверишь кол-во свободных кластеров,вроде норм, потом после 2-ого файла(карточку вообще не извлекал) проверяю - осталось прежнее число. Извлекаешь методом безопасного извлечения,втыкаешь, результат тот же ,печальный. Стираешь все файлы с карточки - тоже число не меняется, пока не отформатируешь заново. Счас поменяю кардридер,может здесь закрался подвох.. ПС. Точно, кардридер на компе - дерьмо, подключил другой кардридер - все ок. Пока такого эффекта не обнаружилось
  8. FAT16/32 для ARM

    Доброго дня! К АРМ2388 с FreeRTOS пристегнул FatFS. Юзаю Sd-карту SDHC Transcent 4Gb. Столкнулся с проблемой определения количества свободных кластеров на карточке. С помощью функции FatFS f_mkfs(0, 0, 1024) в устройстве форматирую карточку под FAT32. Затем мне надо было заполнить часть памяти мусором- стал записывать на компе (ОС WinXP) на карточку авишки. В процессе экспериментов выяснилось, что количество свободных кластеров, которые считываются с сектора 64 по смещению 0x1E8(Структура FSInfo), не изменяется. Причем сначала вроде меняются, а потом стопорится на каком-либо числе, даже стирания всех файлов не приводит к изменению этого числа. После записи каждого файла проверяю этот сектор с помощью Victoria, но при этом средствами Windows (свойства логическог диска) я вижу, что размер-то свободного места на карточке меняется... А в устройстве функция FatFS f_getfree("0:/", &SDMemoryRemains, &fs) дает такое же число(которое неизменяемое, т.е. неправильное). Почему такое происходит? Почему перестает обновляться количество свободных секторов в секторе 64 ? Я ж в устройстве на арме не могу каждый раз полностью пересчитывать кол-во свободных секторов- это занимает слишком много времени.
  9. ARM2388 и RTC

    Столкнулся с проблемой работы с часами реального времени: аж дни(в часах) бегут почти как секунды... ------------- Усе заработало!
  10. 1. Как я понял, стирать (командой 52) предварительно нет необходимости(но счас попробую), по крайней мере, написано в даташите, что Это цитата к команде "IAP Copy RAM to flash command". Т.е. как и показано в начальном посте,сначала выполняю команду 50, потом команду 51. 2. Прерывания запрещал тоже - эффекта не было. 3. "Разрешить запись" - это через CRP? Опять же,возможно, я неправильно понял, но написано,что CRP не влияет на IAP команды. IAP commands are not affected by the code read protection ------------------------------- Да,так и есть - после команды 52 запись сработала. Спасибо! Странно,что в даташите не написали,что для записи надо последовательно выполнить 4 команды: 50,52,50,51...
  11. Привет всем! Возникла проблема. Почему-то не программируется flash-память с помощью оперции IAP. Использую стандартный код #define IAP_LOCATION 0x7ffffff1 unsigned long iap_command[5]; unsigned long iap_result[3]; ........... iap_entry(iap_command, iap_result); // и др.команды Чтение версии загрузчика с помощью дает нужный результат,т.е. операция срабатывает. Например, хочу запрограммировать один 7-й сектор: iap_command[0] = 50; iap_command[1] = 7; iap_command[2] = 7; iap_entry(iap_command, iap_result); iap_command[0] = 51; iap_command[1] = 0x7000; iap_command[2] = (unsigned long)RAMbuffer; iap_command[3] = 4096; iap_command[4] = SYS_GetFsclk()/1000; iap_entry(iap_command, iap_result); Перед выполнением этих операций считываю содержимое сектора 7 и выбрасываю через com-порт на терминал После выполнения каждой операции на комп отправляется результат операции. Получаю код CMD_SUCCESS = 0,т.е. все хорошо, а затем считываю вновь содержимое сектора 0x7000. Получаю те же самые нули, что и были до программирования,т.е. сектор не запрограммировался... Не понимаю, что не так...
  12. pvPortMalloc

    Согласен, что так лучше - не надо будет в прерывании долго сидеть. Но если сделать внутри прерывания перед вызовом pvPortMalloc/vPortFree операцию taskENTER_CRITICAL() , а после вызова pvPortMalloc/vPortFree if (ulCriticalNesting) ulCriticalNesting--; , то все работает и внутри прерывания. Но это изврат, не спорю.
  13. pvPortMalloc

    Можно ли вызывать pvPortMalloc/vPortFree внутри irq-прерывании? Попытался и получил, что после его вызова в прерывании разрешается irq-прерывание в CPSR со всеми вытекающими печальными последствиями. Данное прерывание проходит как обычно через сохранение/восстановление контекста задач. Не нашел в документации, что pvPortMalloc нельзя вызывать из прерываний, или я что-то пропустил?
  14. Run Time Statistics

    Считываю с частотой 1 Гц vTaskGetRunTimeStats(); Иногда получаю, что всякие задачи имеют процентное время 870%, 254% и т.п. Потом вновь постепенно приходит к более-менее правдивым показаниям. И так повторяется с некоторым промежутком. Проверил с помощью отладчика -действительно прямо сразу после вызова vTaskGetRunTimeStats() в буфере лежат такие косячные цифры процентов. PS. Оказывается делал все правильно... почти.. ) При инициализации таймера для статистики необходимым словом запрограммировал не Prescale register, а Match Register.
  15. Я ж написал, что Да и зря на goto так наезжаете, ибо он часто помогает избавиться от излишнего кода и не нарушает логики в данном случае. Все irq-прерывания проходят через сохранение и восстановление контекста. Зачем мне нужны эти лишние операции, когда непонятно было успевает ли принять данные или нет система, да еще использовать внутри этого прерывания всякие функции freertos-а, да еще в конце прерывания контекст переключать из-за queue? На 1Мб usart получается не совсем медленным, однако. "break" выходит из case,однако. ";" - ну вот мне так нравится ) количество байт кадра известно становится только при приходе кадра. Да и не до dma было, ибо зачем новый геморой, когда dma еще не пользовался и не знаю, какие там косяки могут быть. Сначала так должно было заработать. Все это,конечно,лирика, но без эмулятора работает все четко..