Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC2388 CAN freeRTOS
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Androliz
Плата с lpc2388 под управленим freeRTOS. Получаю сообщение по CAN1 - вваливаюсь в обработчик прерывания. Если дальше выполнять пошагово в дебаггере (jtag) то всё хорошо работает, но если запустить (RUN), то раз в ~10 сообщений вываливается в Pabt. Причём вываливается после выхода из обработчика прерывания. В R14(LR) при этом чаще всего 0x286e9b12.
Поскольку прерывание может пробуждать другие task'и, то оформлял как оформлено прерывание от UART след. образом:

vCAN_ISREntry

portSAVE_CONTEXT ; Save the context of the current task.

LDR R0, =vCAN_ISR ; Call the ISR routine.
MOV LR, PC
BX R0

portRESTORE_CONTEXT ; Restore the context of the current task -
; which may be different to the task that
; was interrupted.



Далее текст главной функции прерывания:

void vCAN_ISR(void) //__irq
{
portBASE_TYPE xHigherPriorityTaskWoken;
CANStatus = CAN_RX_SR;
if ( CANStatus & (1 << 8) )
{
CAN1RxCount++;
xHigherPriorityTaskWoken = CAN_ISR_Rx1();
}

if ( CAN1GSR & (1 << 6 ) )
{
/* The error count includes both TX and RX */
CAN1ErrCount = (CAN1GSR >> 16 );
}

VICVectAddr = 0; /* Acknowledge Interrupt */

/* Actual macro used here is port specific. */
portEXIT_SWITCHING_ISR(xHigherPriorityTaskWoken);
}

И подпрограмма обработки приёма по CAN

portBASE_TYPE CAN_ISR_Rx1( void )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

xCANMsg * pMsg = ( xCANMsg * ) pvPortMalloc( sizeof( xCANMsg ) );

if(pMsg == 0){
vSerialPutString( NULL, "No memory avalible", 25);
xSerialPutChar( NULL, CR, comNO_BLOCK);
while(1){};
}
pMsg->Frame = CAN1RFS;
pMsg->MsgID = CAN1RID; // ID //change by gongjun
pMsg->DataA = CAN1RDA; // Data A
pMsg->DataB = CAN1RDB; // Data B

xQueueSendToBackFromISR( receiveCANQueue, ( void * ) &pMsg, &xHigherPriorityTaskWoken);

CAN1RxDone = TRUE;
CAN1CMR = 0x04; // release receive buffer
return xHigherPriorityTaskWoken;
}
FormatCft
Цитата
В R14(LR) при этом чаще всего 0x286e9b12.

Это для какого режима проца смотрели?
Androliz
Цитата(FormatCft @ Dec 5 2008, 17:09) *
Это для какого режима проца смотрели?


Для abort
Сменил настройки MAM с disabled на fully enabled - сообщений стало гораздо больше проходить перед Pabt.
FormatCft
Цитата(Androliz @ Dec 5 2008, 20:59) *
Для abort
Сменил настройки MAM с disabled на fully enabled - сообщений стало гораздо больше проходить перед Pabt.

Может здесь ответ есть?
zltigo
Цитата(FormatCft @ Dec 5 2008, 19:20) *
Может здесь ответ есть?

В приведенном коде своих проблем для начала выше головы.
1.Всякой мути надергано и сляпано из каких-то исходников sad.gif
2.Выделение динамической памяти в обработчике прерывания без всякой надобности да еще и не освобождается при этом.
3.Для копирования в очередь передается не указатель на CAN буфер а указатель на этот указатель..
4.Вызов каой-то мутной печати из обработчика..
5......
Androliz
Цитата(zltigo @ Dec 6 2008, 02:18) *
В приведенном коде своих проблем для начала выше головы.
1.Всякой мути надергано и сляпано из каких-то исходников sad.gif
2.Выделение динамической памяти в обработчике прерывания без всякой надобности да еще и не освобождается при этом.
3.Для копирования в очередь передается не указатель на CAN буфер а указатель на этот указатель..
4.Вызов каой-то мутной печати из обработчика..
5......


извините, возможно я не совсем (или совсем не) разбираюсь в теме, но у меня есть следующие возражения:
пункт3:
поскольку объекты сообщения типа xCANMsg занимают в памяти 16 байт, то накладно было бы их копировать по значению (а в очереди freeRTOS данные по значению и копируются - Items are queued by copy not reference), следовательно я храню в очереди указатель.
Объявление очереди:
receiveCANQueue = xQueueCreate( 40, sizeof( struct xCANMsg * ) );//содержит указатели на xCANMsg
В
Цитата
а указатель на этот указатель

Из описания API работы с очередями с freeRTOS.org:
portBASE_TYPE xQueueSendToBackFromISR(
xQueueHandle pxQueue,
const void *pvItemToQueue,
portBASE_TYPE *pxHigherPriorityTaskWoken
);
где pvItemToQueue - A pointer to the item that is to be placed on the queue. The size of the items the queue will hold was defined when the queue was created, so this many bytes will be copied from pvItemToQueue into the queue storage area.
Следовательно, если я хочу поместить указатель на xCANMsg в очередь, я должен передать указатель на него, т.е. указатель на указатель.

пункт2: Я не знаю как можно по-другому организовать приём сообщений от CAN и постановку их в очередь. Если "просто" обьявить переменную типа xCANMsg и передать указатель на неё в очередь, то следующее принятое сообщение затрёт предыдущее, поскольку будет записываться на то же место. Или может быть я заблуждаюсь?
Насчёт освобождения памяти - я его освобождаю в том task'е, где я обрабатываю это сообщение:

if( xQueueReceive( receiveCANQueue, &( pRecMsg ), ( portTickType ) 1 ) )
{
//mirror message
pMsg->Frame = pRecMsg->Frame; // 29-bit, no RTR, DLC is 8 bytes
pMsg->MsgID = pRecMsg->MsgID; // CAN ID
pMsg->DataA = pRecMsg->DataA;
pMsg->DataB = pRecMsg->DataB;
//free memory pRecMsg
vPortFree(pRecMsg) ;
CAN1_SendMessage( pMsg ) ;
}

пункт4: вполне согласен. Вопрос: как печатать сообщения: оформлять отдельный task с очередью, в которую передавать указатели на строки, которые нужно распечатать и из task'a их печатать?

Буду рад любым замечаниям.
zltigo
Цитата(Androliz @ Dec 8 2008, 12:30) *
Буду рад любым замечаниям.

Тем не менее копировать 16 байт в очередь наименьшее из зол. При желании потом можете сделать отдельный кольцевой буфер кратный 16 байтам, принимать в него и посылать указатели на него. Можно и слегка доработать FreeRTOS добавив вариант с возвращением указателя на место в буфере вместо копирования в буфер....По печати - печать через отдельный буфер для печати разгружаемый из обработчика прерывания UART.
Androliz
спасибо за замечания
Ближе к теме.
1. Может ли Pabt возникать из-за программной ошибки и в каких случаях. Если нет, то как с ним бороться.
2. В erratasheet'e меликом в описании Flash.1 problem упоминается :Do not use even values for CCLKSEL
А ранее они в этом же документе писали: PLL.1: Problem: The maximum output of the CCO within the PLL block is limited to 290 MHz.
Т.е. FCCO 275 - 290 MHz
А при кварце 14,7456 МГц и наличии USB (48МГц) подобрать подходящие M и N с небольшой погрешностью (менее 1000 ppm) неполучается. Так что, теперь квац нужно менять?!
Androliz
Проблема решилась след. образом: убрал из прерывания динамическое выделение памяти и стал копировать сообщения по значению в очередь (очередь пришлось урезать до 4-5 значений).
zltigo
Цитата(Androliz @ Dec 8 2008, 15:57) *
очередь пришлось урезать до 4-5 значений.

В чем необходимость урезания-то? 4 это 64 байта, неужели это были последние байты в Вашей программе smile.gif.....
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.