Jump to content

    
Sign in to follow this  
varvar

scmRtos для медных чайников

Recommended Posts

Добрый день всем!

Возникло желание - точнее, необходимось использовать многозадачность в своем проекте - вернее, или надо писать свой диспетчер (в котором я уже успел запутаться), или пользоваться чем-то готовым.

Увидел scmRtos - попытался запустить демку. Пример под IAR на MSP430F2617 - у меня на плате MSP430F2410, IAR версия 5.30

 

Немножко подправил демку под свою плату, чтобы нужный светодиодик моргал, указал иару на MSP430F2410 - и ничего. WDT прерывание случается раза 4 (вроде как это системный таймер?), после чего программа улетает неведомо куда.

 

Кто-нибудь может на путь истинный наставить - что можно трогать, что нельзя. Может ли на работоспособности версия компилятора сказаться? Или, лучше всего, может у кого готовая рыба завалялась для моргания именно на этом кристалле или похожем?

Share this post


Link to post
Share on other sites

Ok, кажется загрузка новой версии (4.0) немного помогла.

Но моргалка здесь сигнал выдает какой-то совсем не похожий на периодический

 

context_switcher_isr:

save_regs

mov.w SP,r12

XOR.B #0x2, &0x21 // blinking led

xcall #os_context_switch_hook

mov.w r12,SP

l_restore_context:

restore_regs

reti

Share this post


Link to post
Share on other sites
Ok, кажется загрузка новой версии (4.0) немного помогла.

Но моргалка здесь сигнал выдает какой-то совсем не похожий на периодический

 

context_switcher_isr:

save_regs

mov.w SP,r12

XOR.B #0x2, &0x21 // blinking led

xcall #os_context_switch_hook

mov.w r12,SP

l_restore_context:

restore_regs

reti

А зачем вы в самые недра ядра-то полезли? Это не место для пользовательского кода. И с чего взяли, что тут должен быть периодический сигнал? Вы документацию-то читали? Используйте для формирования таких сигналов пользовательские процессы и функцию sleep().

Share this post


Link to post
Share on other sites
А зачем вы в самые недра ядра-то полезли? Это не место для пользовательского кода. И с чего взяли, что тут должен быть периодический сигнал? Вы документацию-то читали? Используйте для формирования таких сигналов пользовательские процессы и функцию sleep().

 

так не работало вообще ничего - надо ж как-то определяться было. Я ж предупреждал - чайник медный :) Я понимаю, что коду там не место - но как-то понять, работает или нет надо было.

Насчет документации - грешен, не читал еще. Определить работоспособность пытался по аналогии с FreeRtos - там системный таймер похожим образом сделан. Спасибо за подсказку.

Подход может быть и тупой - но просто хотелось убедиться, что элементарный готовый пример будет на моем железе и с моим компилятором работать - а потом уже разбираться.

 

Share this post


Link to post
Share on other sites

Я с примеров и начинал - с моей версией ИАРа и 3.10 версией scmRtos программа улетала непонятно куда - по крайней мере кода в той области, где я ее останавливал, не было. 4-ая версия работает - по крайней мере, и демки, и мои попытки их модификаций. Самое время начать читать документацию. Кстати, у тексаса не увидел никаких упоминаний о Вашей операционной системе. Они не знают о ней или игнорируют? Или я плохо искал?

Edited by varvar

Share this post


Link to post
Share on other sites
Я с примеров и начинал - с моей версией ИАРа и 3.10 версией scmRtos программа улетала непонятно куда - по крайней мере кода в той области, где я ее останавливал, не было. 4-ая версия работает - по крайней мере, и демки, и мои попытки их модификаций. Самое время начать читать документацию.

3.10 делалась довольно давно и тестировалась на вверсии IAR 4.2х. В IAR 5.xx поменяли поведение компилятора в части размещения обработчиков прерываний, и получалось, что некоторые обработчики прерываний не линковались. В 4-ке этот момент был пофиксен. Использовать 3.10 в новых проектах нет вообще никакого смысла.

 

Кстати, у тексаса не увидел никаких упоминаний о Вашей операционной системе. Они не знают о ней или игнорируют? Или я плохо искал?

К TI это вообще не имеет никакого отношения. И этих осей как собак бездомных, чего такому монстру, как TI, обращать на это внимание. Он микрухи делает и поддержку для некоторых из них (TMS) в виде тулчейна и своей собственной операционки.

Share this post


Link to post
Share on other sites

Попытаюсь воспользоваться еще раз добротой и отзывчивостью авторов, уже чуть более конкретно.

Одна из моих задач отправляет радиопакет по таймеру (прерывание номер раз). Для управления используется аппаратный SPI - прерывание номер два. Когда данные отправлены - передатчик генерирует прерывание три. После чего он переключается на прием в и течении определенного времени ждет прерывания от приемника. Дождался - считывает данные. Нет - выключается приемник и все начинается с начала.

Какими средствами scmRTOS кошерно воспользоваться здесь? Сделать одну задачу с семафорами или две - одна обслуживает SPI, а вторая трансмиттер?

 

И второй вопрос - пусть это будет UART только на передачу по прерываниям и у него есть буфер. Как поступить при заполнении буфера, чтобы приостановить программу? Можно ли как-то семафоры разместить не в задаче, а в вызываемых подпрограммах? или вообще все как-то иначе лучше сделать?

Заготовка кода на чистом С выглядит примерно так (без всяческого контроля, только опустошение буфера):

 

uint8 TxBuffer[16];
uint8 TxBufIndexIn;
uint8 TxBufIndexOut;

void Init_UART(void)
{ 
  P3SEL |= 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  UCA0BR0 = 138;                            // 16MHz 115200
  UCA0BR1 = 0;                              // 16MHz 115200
  UCA0MCTL = UCBRS2 + UCBRS1 + UCBRS0;      // Modulation UCBRSx = 7
  UCA0CTL1 &= ~UCSWRST;                     // Initialize USCI state machine
  IFG2 |= UCA0TXIFG;                        // ready to start int 
  TxBufIndexIn=0;
  TxBufIndexOut=0;
} 

int putchar( int data )
{
  TxBuffer[TxBufIndexIn++] = data;
  TxBufIndexIn &= 0x0F;
  IE2 |= UCA0TXIE;     
  return data;
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
  UCA0TXBUF = TxBuffer[TxBufIndexOut++];
  TxBufIndexOut &= 0x0F;
  if (TxBufIndexOut == TxBufIndexIn) IE2 &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt 
}

Контроль переполнения можно как-то сделать в putchar остановив задачу или все-таки где-то в самой задаче это делать?

 

Если вопросы слишком наивные - как медный чайник, обещаю обзавестись свистком :)

 

А вообще - Ваша документация описывает все, но вот из нее бы выжимку для чайников сделать, без полного описания что и как работает.

Типа - делай так - и вот тебе пример. Тем более, у большинства начинающих пользоваться и вопросы возникают практически одинаковые.

А пока читаешь полную документацию, дойдя до середины, уже забудешь, что было в начале.

Такая подробная нужна уже тогда, когда элементарные вещи делаешь без проблем и нужны уже тонкости.

А для начала бы список функций с кратким пояснением на пару страниц - или в качестве приложения к документации.

 

P.S.

 

по второму вопросу - видимо, нужны channel и я плохо смотрел приметы?

Edited by varvar

Share this post


Link to post
Share on other sites

Почитай статьи по потокам. Это фактически тоже самое.

 

Также статьи по использованию scmRTOS существуют. И там и рассказано, что и как инициализировать/использовать.

Share this post


Link to post
Share on other sites

1. В процессе ждать флаг события от таймера, когда флаг просигнален, отправить в SPI. Тут если скорость SPI высокая, а МК не очень быстрый, то, возможно, имеет смысл не заморачиваться с прерываниями, а просто поллить флаг окончания передачи - с переходами в другие процессы может получиться тормознее и накладнее. Если скорость SPI медленная по сравнению с темпом выполнения инструкций процессора, то просто после инициирования отправки в этом же процессе ждать другого флага событий, который просигналит уже обработчик прерывания передатчика SPI. Дождались, пошли дальше - теперь ждём, как я понял, данных от приёмника, но ждём не вечно, а в течении какого-то времени и ждём не просто события, а данных. Поэтому тут логично было бы использовать OS::message<> - создать объект-сообщение для ожидаемого типа и ждать его с таймаутом. Пришли данные до истечения таймаута - одни действия, таймаут истёк - другие. Весь код получается простой и линейный в одном процессе.

 

2. Да, OS::channel<> вполне нормально подходит. Но, возможно, пойдёт и просто кольцевой буфер - зависит от приложения, от того, какие источники и как они обращаются к буферу передатчика. Возможно, проще будет использовать кольцевой буфер с критическими секциями. Но и канал тоже нормально подходит, единственное, надо следить, чтобы в ISR передатчика канал не пытался встать на ожидание, т.е. надо следить за тем, что обработчике прерываний перед извлечением из канала очередного элемента канал не пуст. Иначе он будет вставать в ожидание с попыткой отдать управление ядру, а это чревато негативными последствиями.

Share this post


Link to post
Share on other sites

Здравствуйте. Чтобы не плодить лишних тем решил отписаться здесь.

 

Пытаюсь запустить scmRTOS 4.00 на LPC1766.

 

CodeSourcery + Eclipse. За основу взял GCC пример для STM EventFlag.

Проблема в том, что работает только процесс Proc1.

Управление процессам Proc2 и Proc3 не передается.

Соответственно светодиод led2 не

работает.

Флаг TimerEvent в system_timer_user_hook взводится и обрабатывается

процессом Proc1. Светодиод led1 моргает как и положено.

Код запускаю из RAM. Возможно в этом и грабли. Но хотелось бы понять в чем дело.

 

Недавно запускал такой пример для LPC1766 и IAR для scmRTOS 3 версии. Проблем не было.

 

Буду благодарен за любые замечания. Проект прикрепил.

lpc17xx.zip

Edited by tamam

Share this post


Link to post
Share on other sites

У меня всё уже работает (1-EventFlag и 4-Debug и начинаю писать рабочий проект), именно на LPC1766+GCC

Но из флеша, в RAM меня пока не тянет.

Сейчас нет сил, вечером как-то причешу и оформлю. Я бы уже и в репозиторий положил, но мне не нравится то, что я написал по аналогии с pin.h из примеров для Cortex-M3, а решить, как переделать — нет времени.

 

Если забуду — постучите завтра в личку, мне на почту уведомление придёт.

Share this post


Link to post
Share on other sites
Ага. И первым делом вписал свой копирайт в мой мейкфайл:)

Вообще-то так не делается.

 

Виноват, Обидеть не хотел. :blush:

 

Я его сначала начал сам писать и конкретно запарился, а потом взял за основу Ваш.

 

Но пока разбирался, было не до копирайта.

 

Только переползаю на GCC.

 

Исправил.

Edited by tamam

Share this post


Link to post
Share on other sites
Если забуду — постучите завтра в личку, мне на почту уведомление придёт.
Сам вспомнил :-)

Но все равно откладывается. Там хоть и примеры, но много завязано на конкретную мою плату и уже почикано под пробу конкретных моих заморочек.

 

На работе есть плата SK_MLPC1768, я на ней подниму примеры, вычищу лишнее, тогда можно будет показать.

Для начала 1-EventFlag, он по сравнению с STM32-шным уже изменён. Приведён в соответствие с avr-gcc-шным.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this