Программирование ARM: решение проблем, FAQ IAR EW ARM: DBGU, хитрости в использовании printf Thu, March 28 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

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. Работа с кольцевым буфером.
2. IAR EW ARM: как перенаправить вывод printf и putchar.
3. IAR EWB ARM: форматированный вывод printf библиотеки DLIB.
4. Секреты printf

 

Добавить комментарий


Защитный код
Обновить

Top of Page