В статье описаны приемы работы с 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. |