IAR EW ARM: DBGU, хитрости в использовании printf |
![]() |
Добавил(а) microsin |
В статье описаны приемы работы с printf, DBGU, использование их в отладке. 1. Код и реализация printf скрыты от программиста, и иногда эта функция ведет себя непредсказуемо. Например, если вызывать printf в подпрограмме до основного цикла main, то ничего не выведется, но если в main, в основном цикле сделать несколько вызовов printf, то вывод появится. Единственный гарантированный метод, который позволяет побороть это - вывод текста в буфер с помощью sprintf, а затем вывод этого текста собственными процедурами напрямую в экран или порт DBGU. 2. Как перенаправить вывод printf, см. [2]. 3. Чтобы вывести с помощью printf знак процента %, нужно его продублировать: printf("%%"); //печатает % 4. Для отладочного вывода удобно использовать макрос trace_LOG (определен в файле trace.h). Например: //запускаем DBGU trace_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK); trace_LOG(trace_INFO, version_full); 5. Для чтения символов из отладочной консоли DBGU (это можно использовать для пользовательского интерфейса управления разрабатываемым прибором) можно использовать связку USART_IsDataAvailable и DBGU_GetChar, например: if ( USART_IsDataAvailable((AT91S_USART *)AT91C_BASE_DBGU) ) { DBGU_GetChar(); //делаем скриншот LED(1); ScreenShoot(); LED(0); } 6. Чтобы организовать гарантированный фоновый прием данных от порта DBGU, необходимо это делать по прерываниям. Прерывание USART DBGU (в отличие от обычного USART) обрабатывается через System interrupt (AT91C_ID_SYS, используется для обработки таймера PIT). Поэтому в обработчике PIT необходимо сделать также обработку порта DBGU (например, писать принимаемые с отладочной консоли символы в глобальный кольцевой буфер [1]). Например: void ISR_Pit(void) { // System Interrupt Handler volatile AT91S_DBGU *pDBGU= AT91C_BASE_DBGU; volatile unsigned int StatusDBGU; volatile unsigned int StatusPITS; StatusDBGU = pDBGU->DBGU_CSR; StatusPITS = PIT_GetStatus(); if (StatusPITS & AT91C_PITC_PITS) { // Check PIT Interrupt // Read the PIVR to acknowledge interrupt and get number of ticks. // Переменная timestamp отслеживает количество прошедших миллисекунд. // Это очищает PIT int source. timestamp += (PIT_GetPIVR() >> 20); // Handle PIT IRQ ... } if (StatusDBGU & AT91C_US_RXRDY) { // Handle DBGU RX ... } if (StatusDBGU & AT91C_US_ENDTX) { // Handle DBGU Tx ... } } [Ссылки] 1. Работа с кольцевым буфером. |