реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> I2C LPC2xxx
GetSmart
сообщение Sep 25 2009, 16:51
Сообщение #1


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Есть исходник, работающий через I2C с термометром. Тестирую его без FreeRTOS - работает стабильно и долго. Запускаю Ось - глючит сильно, и иногда работает. I2C работает через прерывание. Компилятор CW. Под Осью оно описано так:
Код
void vI2C_ISR_Wrapper( void )
{
    /* Save the context of the interrupted task. */
    portSAVE_CONTEXT();

    /* Call the handler.  This must be a separate function from the wrapper
    to ensure the correct stack frame is set up. */
    vI2C_ISR_Handler();

    /* Restore the context of whichever task is going to run next. */
    portRESTORE_CONTEXT();
}

без оси так:
Код
void vI2C_ISR_Handler( void )
{
    asm("STMDB    SP!,{R0-R12,LR}");        // пролог для IRQ
...
    VICVectAddr = 0;        /* Acknowledge Interrupt */
    asm(    "LDMIA    SP!,{R0-R12,LR}    \n"    // эпиолог для IRQ
        "SUBS    PC,LR,#4    ");
}

Прерывания в обоих случаях внутри обработчиков запрещены. Начинка прерывания была взята из примеров с сайта NXP, хотя немного переделана. Параллельно с работой I2C прерывания работает FIQ с частотой 8 КГц. FIQ работает стабильно под осью и без оси, и на глюки в обоих вариантах (с осью/без) не влияет.

Вопрос: куда копать? Может кто описать особенности "написания программы" под FreeRTOS ? В том смысле, что вот этого например делать нельзя, или на вот это нужно обратить особое внимание, или ещё что-нить. Проект большой, так что выложить бОльшие куски кода пока не могу.

Сообщение отредактировал GetSmart - Sep 25 2009, 17:02


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
HARMHARM
сообщение Sep 25 2009, 19:50
Сообщение #2


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Посмотрите как сделано в примерах, идущих с FreeRTOS под ваш контроллер. Есть разница в оформлении прерываний?
Я так понимаю, что это ARM. Это ARM7? Нужно ли вообще сохранять контекст внутри прерывания?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 25 2009, 20:01
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Sep 25 2009, 18:51) *
глючит сильно

Исчерпывающе sad.gif.
Цитата
Может кто описать особенности "написания программы" под FreeRTOS ?

Да нет никаких особенных особенностей.



Цитата(HARMHARM @ Sep 25 2009, 21:50) *
Нужно ли вообще сохранять контекст внутри прерывания?

Подозреваю, что для столь медленного девайса, как I2C термометр это (обеспечение вызова переключения контекста из обработчика) по любому излишество.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 21:28
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Sep 26 2009, 02:01) *
Исчерпывающе sad.gif.

smile.gif
Правильнее было бы написать, что принимаются неправильные данные по i2c. Вероятнее всего криво написанный обработчик, точнее сама его начинка, а не прологи/эпилоги. Я с того времени накатал простенький обработчик i2c. Вот, если кто обнаружит ошибки - буду признателен. Проц LPC2368
CODE
void vI2C_ISR_Handler( void )
{
asm("STMDB SP!,{R0-R12,LR}"); // пролог для IRQ

switch ( I20STAT )
{
case 0x08: // передан первый START, далее передать SLA
case 0x10: // передан повторный START без STOP-a
// I20CONCLR = STA; //???
I20CONSET = AA;
I2CMasterState = I2C_STARTED;
if (WrIndex < I2CWriteLength) // если есть данные для передачи
I20DAT = I2CMasterAddr;
else I20DAT = I2CMasterAddr | 0x01; // иначе будет чтение данных
break;

case 0x18: // принят ACK после SLA+W
case 0x28: // принят ACK после Byte Send
I2CMasterState = DATA_ACK;
if (WrIndex < I2CWriteLength)
{ I20DAT = I2CBuffer[WrIndex++];
I20CONSET = AA;
}
else if (I2CReadLength != 0) // если требуется что-то прочитать
{ I20CONSET = STA | AA; // повторить START для чтения данных
}
else
{ I20CONSET = STO | AA; // завершить обмен по I2C
I2CMasterState = DATA_NACK; // реально - удачное завершение обмена
}
break;

case 0x50: // передан ACK после Byte Receive
case 0x58: // передан NACK после Byte Receive (проверить реально ли NACK ?)
if (RdIndex < I2CReadLength)
I2CBuffer[RdIndex++] = I20DAT;
case 0x40: // принят ACK после SLA+R
// I2CMasterState = DATA_ACK;
if ((RdIndex+1) < I2CReadLength) I20CONSET = AA; // будет ACK // если есть место куда ложить байты
else if ((RdIndex+1) == I2CReadLength) I20CONCLR = AA; // будет NACK // если есть место куда ложить байты
else
{ I20CONSET = STO | AA; // завершить обмен по I2C
I2CMasterState = DATA_NACK; // реально - удачное завершение обмена
}
break;

case 0x20: // после SLA+W принят NACK
case 0x30: // после Byte Send принят NACK
case 0x48: // после SLA+R принят NACK
I20CONSET = STO | AA;
// case 0x38: // потеря арбитража
default:
I2CMasterState = DATA_ERROR; // завершение обмена
break;
}

I20CONCLR = SI;

VICVectAddr = 0; /* Acknowledge Interrupt */
asm( "LDMIA SP!,{R0-R12,LR} \n" // эпиолог для IRQ
"SUBS PC,LR,#4 ");
}


И ещё я не понял, как мастер узнаёт когда передавать 9 клоков после передачи SLA+R и получении ACK ? Проц взводит флаг SI, I20STAT становится = 0x40, входит в прерывание. С какого момента начинают передаваться клоки - сразу после доступа к I20CONSET/I20CONCLR или по сбросу SI или ещё когда? И после приёма байта когда мастер начинает вырабатывать 9 клоков - аналогично предыдущему случаю или сразу после чтения I20DAT ? Или может проц вырабатывает 8 клоков, и только после записи AA вырабатывает 9-ый. Осцилла нет да сроки поджимают очень, а так бы проверил.

Цитата(zltigo @ Sep 26 2009, 02:01) *
Подозреваю, что для столь медленного девайса, как I2C термометр это (обеспечение вызова переключения контекста из обработчика) по любому излишество.

То есть, во FreeRTOS можно (рекомендуется?) делать IRQ без обёрток portSAVE_CONTEXT() ? То есть самым обыкновенным способом, как я сделал в примере без оси?

Сообщение отредактировал GetSmart - Sep 25 2009, 21:18


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 25 2009, 21:44
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Sep 26 2009, 01:28) *
То есть, во FreeRTOS можно (рекомендуется?) делать IRQ без обёрток portSAVE_CONTEXT() ? То есть самым обыкновенным способом, как я сделал в примере без оси?

Можно. Если переключение контекста в обработчике не нужно, то эта обертка - пустая трата времени и памяти.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 25 2009, 21:55
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Sep 25 2009, 23:28) *
То есть, во FreeRTOS можно (рекомендуется?) делать IRQ без обёрток portSAVE_CONTEXT() ? То есть самым обыкновенным способом, как я сделал в примере без оси?

Ни нафиг не сдались, если не преключать контекст из обработчика прерывания. Для только перепланировки есть отдельная группа функций "from isr". Ваш обработчик не читал. Образчик своего когда-то на на форуме выкладывал. Пользуюсь постоянно в основном для EEPROМ в том числе и на высоких скоростях.
P.S.
Увлечение asm вставками зачем?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 22:33
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(zltigo @ Sep 26 2009, 03:55) *
Увлечение asm вставками зачем?

Я тут уже отчитывался по кривому коду, генерируемому CW 1.7.9 http://electronix.ru/forum/index.php?showt...st&p=651216
Вот такой прототип обратботчика

void NameIntr() __attribute__((interrupt("IRQ")));

правильно работает только на 0 уровне оптимизации, то есть с самым тормознутым кодом. На уровнях 1 и выше приходится делать ручные вставки.

Цитата(zltigo @ Sep 26 2009, 03:55) *
Образчик своего когда-то на на форуме выкладывал.

Вот этот?
http://electronix.ru/forum/index.php?showt...ost&p=90212
А он для 2368 подойдёт? Там ничего не поменяли?

Я злой sad.gif
На Manual 2368. Где там указано, что при статусе 0x08/0x10 нужно сбрасывать STA (I20CONCLR = STA) ?
В разделе (((10.6 Master states->10.6.1 State : 0x08))) нету такого. И ещё непонятно зачем почти для всех статусов нужно записывать AA в I2CONSET.
Зря я NXP-шников защищал когда-то.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 25 2009, 23:02
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(GetSmart @ Sep 26 2009, 00:33) *
На Manual 2368...

Не читал smile.gif контроллер I2C не менялся со времен филипсовских 51. В первых мануалах на LPC2114 даже вообще не описывали никак.
Цитата
Вот этот?

Да, лабораторная работа, так сказать. Реальный отличается, но не принципиально.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 23:14
Сообщение #9


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Грёбаный компилятор CW. Я щас с ума сойду от таких ошибок. Оптимизация = level1

Упс. Там мой косяк. Написал ненароком if (WrIndex >= I2CWriteLength) tmp | 0x01;
А компилер даже не заругался.

Сообщение отредактировал GetSmart - Sep 25 2009, 23:23
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 25 2009, 23:23
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Sep 26 2009, 03:14) *
Грёбаный компилятор CW. Я щас с ума сойду от таких ошибок.

Может, сменить/починить инструмент, коли все так запущено?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 23:35
Сообщение #11


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Sep 26 2009, 05:23) *
Может, сменить/починить инструмент, коли все так запущено?

А на что его сменить? Студия-то неплохая, компилятор (внешний, GNU) - ховно.

Цитата(zltigo @ Sep 26 2009, 05:02) *
Да, лабораторная работа, так сказать. Реальный отличается, но не принципиально.

У Вас там не всё гладко. Не формируется NACK на последнем принимаемом байте, из-за этого статуса 0x58 никогда не будет. А если (гипотетически) туда залетит прога, то зачем-то снова START формируется.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 25 2009, 23:40
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(GetSmart @ Sep 26 2009, 03:35) *
А на что его сменить?

На что-нибудь коммерческое. Или нельзя?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 23:44
Сообщение #13


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Sep 26 2009, 05:40) *
На что-нибудь коммерческое. Или нельзя?

А есть коммерческий под CW ? Саму студию пока низзя менять.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 25 2009, 23:54
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Хм. А в CW есть что-то уникальное?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Sep 25 2009, 23:59
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(aaarrr @ Sep 26 2009, 05:54) *
Хм. А в CW есть что-то уникальное?

Скажем так: мой работодатель в него влюблён biggrin.gif
Ну и синтаксис у CW и IARа отличается прилично. А проект большой. Переделывать затруднительно. И ещё есть несколько причин против.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th June 2025 - 19:18
Рейтинг@Mail.ru


Страница сгенерированна за 0.02175 секунд с 7
ELECTRONIX ©2004-2016