RTOS теперь для MSP430

Как-то я тут публиковал про самодельую litenkjerne — RTOS для STM8(003S).
Теперь пришло время пересесть на MSP430 (16 бит + очень низкое потребление). Ну и, собственно, почему бы не перенести на MSP430 свою RTOS? Неделя вечеров — и всё готово. Что же она умеет?


  1. Статические нити
  2. простой CFQ диспетчер
  3. события таймера
  4. сон/пробуждение любой нити (в т.ч. из обработчика прерываний)
  5. блокировка/разблокировка любой нити (в т.ч. из обработчика прерываний)
  6. выделенная нить для управления режимами сна и ожидания


Вот все функции ядра:
  • создание нити:
    krn_thread_create(krn_thread *thr, void *func, void* param, uint8_t tslice, void *stack, uint8_t stack_size);
  • передача управления диспетчеру:
    extern inline void krn_dispatch();
  • инициализация таймера ядра:
    extern void krn_timer_init();
  • запуск ядра:
    extern void krn_run();
  • засыпание нити на ticks тиков:
    extern void krn_sleep(int16_t ticks);
  • пробуждение:
    extern void krn_thread_wake(krn_thread *thr);
  • инициализация мутекса:
    extern void krn_mutex_init(krn_mutex *mutex);
  • захват мутекса:
    extern void krn_mutex_lock(krn_mutex *mutex);
  • освобождение мутекса:
    extern void krn_mutex_unlock(krn_mutex *mutex);

А теперь традиционно посмотрим, что нам это даёт. Как всегда, мигаем светодиодами и делаем буферизованный ввод-вывод на UART в трёх нитях. Кстати, я учёл замечания участников и отказался от кольцевых буферов, профита от них и правда мало.

Инициализация:

	// create threads
	krn_thread_init();
	krn_thread_create(&thr_main, (void*)main_thread_func, (void*)1, 1, main_thread_stack, MAIN_THREAD_STACK);
	krn_thread_create(&thr_btn, (void*)btn_thread_func, (void*)2, 6, btn_thread_stack, MAIN_THREAD_STACK);
	krn_thread_create(&thr_io, (void*)io_thread_func, (void*)3, 1, io_thread_stack, MAIN_THREAD_STACK);
	krn_timer_init(); // start base timer
	uart_init(16000000 / 115200); // init UART
	krn_run(); // run threads


Два стула Три сосны нити:

static NO_REG_SAVE void main_thread_func (void)
{
	while(1){
		krn_sleep(50);
		P1OUT ^= BIT0;
		uart_write("Hello world!\n", 14);
	}
}

static NO_REG_SAVE void btn_thread_func (void)
{
	char str[16];
	while(1){
		uart_write("Hallo vaarlden!\n", 16);
		krn_sleep(100);
		P1OUT ^= BIT6;
	    kout_uart("sec=");
		kout_uart(kout_u32d(str + 12, krn_timer_cnt / KRN_FREQ));
		kout_uart("\n");
	}
}

//EOL filter
int rx_eol(char c) {
	return c < ' ' ? 0 : 1;
}

static NO_REG_SAVE void io_thread_func (void)
{
	char bfr[16];
	char str[16];
	int l;
	uart_rx_callback = rx_eol;
	while(1) {
		l = uart_read(bfr, 16);
		kout_uart("\t\tbfr=");
		uart_write(bfr, l);
		kout_uart("\n");
	    kout_uart("len=");
		kout_uart(kout_u32d(str, l));
		kout_uart("\n");
	}
}


int rx_eol(char c) — это калбэк который говорит, продолжать приём в буфер, или хорош.

Ну и на примере приёма с UART посмотрим, как RTOS упрощает жизнь:

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
	char c;
	if(IFG2 & UCA0RXIFG) {
		c = *uart_rx_bfr++ = UCA0RXBUF;
		uart_rx_len--;
		if(!(uart_rx_len && (uart_rx_callback ? uart_rx_callback(C) : 1))) {
			IE2 &= ~UCA0RXIE;
			if(uart_sleep_thread_rx) {
				krn_thread_wake(uart_sleep_thread_rx);
				krn_thread_move(uart_sleep_thread_rx, krn_thread_current);
				uart_sleep_thread_rx = 0;
				//krn_dispatch(); //uncomment for extra hardness
			}
		}
	}
}

int uart_read(char *bfr, int len)
{
	CRITICAL_STORE;
	if(!len) return 0;
	krn_mutex_lock(&uart_mutex_rx);
	CRITICAL_START();
	uart_rx_bfr = bfr;
	uart_rx_len = len;
	IE2 |= UCA0RXIE;
	uart_sleep_thread_rx = krn_thread_current;
	krn_sleep(uart_rx_wait_timeout);
        uart_sleep_thread_rx = 0;
	len = len - uart_rx_len;
	CRITICAL_END();
	krn_mutex_unlock(&uart_mutex_rx);
	return len;
}


Тут мы погружаем нить в спячку на некоторый заданный таймаут, читаем байты в буфер. Заодно, наш калбэк говорит, надо ли продолжать читать, или как. Полезная фича, скажем, для отслеживания EOL на терминале или заголовка и конца пакета. Потом нить разблокируется либо по таймауту, либо по заполнению буфера, либо по окончанию приёма и функция возвращает число прочитанных байт. Так довольно сложное поведение достигается весьма простым путём.

P.S. В ядре, на таймере TIMER0_A реализовано три таймера с разными частотами.
На выделенном векторе TIMER0_A0 оставил заглушку

#pragma vector = TIMER0_A0_VECTOR
__interrupt void TA0_highspeed() {
	TACCR0 += TA0_DELTA0;
}

На ней можно реализовать опрос 1W по прерываниям, например.

Как всегда налетаем, тестим, отписываемся.
  • +4
  • 13 октября 2013, 22:55
  • scaldov

Комментарии (45)

RSS свернуть / развернуть
Это наверное очень круто (я фактически не пробовал ртос кроме одного примера), но хотелось бы ос найти а не мух :) «с блэкджэком и ....» — uart, i2c, spi c DMA ессесвенно со встроенным WEB сервером и прочими ништяками (может даже с lua, spawn) -а то мож есть на stm32, а я не знаю :)
зы пардон, что вопрос не совсем по теме
0
на STM32 это Chibios.
Там есть то что вам надо: уровень HAL c шахматами и поэтессами.
0
чето как то дороговато оно для небольшого коммерческого использования.
0
для коммерческого — $4000 на всё про всё — вполне нормально. Это месячная зарплата годного программера в ДС или 2х-3х в замкадье.

А если совсем уж небольшого, под десяток штук, то можно и втихаря захомячить. Я думаю, никто не узнает обидится :)
0
мда… 4к вечнозеленых — это нормально?
не все живут в Масквабаде и даже не в Замкадье… в моей Буратиновке больше чем пол года нужно для этой суммы…
+1
так я ж и говорю — никто не обидится же. с другой стороны, ты можешь своё железо выложить под GPL.
0
насчет втихаря — не совсем реально, а на 100штук (и даже на 200) — это нехилая прибавка к себестоимости недорогого устройства >40USD (которая при продаже выльется в 100USD и больше)
зы был бы вариант 1-5usd c устройства — в моем случае было бы интересно
0
UART — пример я дал в статье — с операционкой пишется за час с нуля.
SPI — не сложнее.
I2C — да, посложнее, чем SPI, но не намного.
USB — потратите неделю максимум.
т.е., если всё делать по-честному, то нужно лишь желание.
-1
DMA, кстати, тоже очень просто. ISR перевешиваете с устройства на нужный канал DMA. При необходимости настраиваете half transfer.
Могу свою старую демку выложить для платы embest
0
это все понятно и в принципе видимо к этому и пойдет скорее всего, просто думалось мне что где-то есть рыба моей мечты :)
зы с другой стороны поле непаханное
0
USB — потратите неделю максимум.
Это с нуля, не используя ничего из библиотек и ничего не зная про usb?
0
да.
туда же входит освоение libusb2 за день.
0
освоение libusb2
То есть не с нуля, иначе зачем libusb2? Что это такое, кстати?
0
для небольшого коммерческого использования
Chibios разве не free? Или денег тоже хочут?
0
для коммерческого применения — нет.
но можно же применять под GPL
-1
для коммерческого применения — нет.
Ничего себе… Интересно им кто-то платит? Я бы не стал…
-1
uart, i2c, spi c DMA
Это не нужно — задача rtos разделить код на задачи(с системой приоритетов) и дать задачам средства взаимодействия друг с другом и прерываниями. HAL можно и нужно писать самому, иначе получится очередная SPL/ASF/другая библиотека написанная индусами, за миску риса в день.

ессесвенно со встроенным WEB сервером и прочими ништяками (может даже с lua, spawn) -а то мож есть на stm32, а я не знаю :)
зы пардон, что вопрос не совсем по теме
И к тому же freeware и opensource?
0
собственно потому, что не знаком с ос и спрашиваю.
А просто шедулер и хал мне не совсем интересен, т.к. надо много дописывыть.
ps К тому же контроллеры щас нынче жирные весьма и почему бы не иметь все в одном флаконе?
0
см про энергопотребление а так же объём памяти на этом классе контроллеров.
0
Круть! Будет время — попробую, хотя раньше с RTOSами дела не имел, но всё хотелось пошшупать.
0
Не смог найти в коде __low_power_mode_n или __bis_SR_register. Может, не IAR, но проект-то под него. Как проц засыпает не понял.
0
в .asm есть нить krn_uthread_idle. Её надо будет перенести в Си (чтоб попроще прогать) и в ней собственно и будет управление. Пока там тупо пустой цикл.
0
сегодня вечерком сделаю пример со сменой частоты ядра и режимов.
0
Так понимаю при переключении между задачами контекст не сохраняется?
0
  • avatar
  • mihey
  • 14 октября 2013, 16:34
Да вы что?? Не пугайте так людей.
Конечно, сохраняется. На стеке текущей задачи.
0
Пардон, увидел в листинге.
0
Заплакал… launchpad за 12 вечно зеленых… п*** цена!
0
извиняюсь за оффтоп но: Your text to link...
0
из вашего списка на любой встанет.

да в Ti-Store закажите MSP430 launchpad, на него встанет. Доедет дней за 4-5 федексом.
0
не знаю как сейчас… раньше еще и бесплатно доставляли их!
0
Спасибо, всем!
Да, там дешевле, вопрос цены доставки, на АЛИ фришипинг… Ну и есть наборы с обвязкой для всяких примеров… Хорошо, подумаю, главное Вы сказал!
0
с TI store везут бесплатно. т.е., какая цена написана, такую и платите.
0
Спасибо! Заказал вот эту:
estore.ti.com/msp-exp430f5529lp.aspx
MSP-EXP430F5529LP
Вопрос к Вам и ко всем кто имеет опыт — чем прошиваем эти микросхемы у кого какой опыт? Нужен хард и софт из Вашего опыта!
Заранее признателен всем ответившим!
0
хард — на плате USB- программатор и отладчик. Из софта я пользовался GCC-msp430 + mspdebug под линуксом и IAR под виндой.
0
Спасибо! Но… Меня интересует чем и как прошить не эту плату а стороннии… Ну скажем так — освоил по этой платке что-то, и потом сделал свою — какие для программирования возможности? Чем, какой разъём, какие выводы на контроллере задействовать, какой интерфейс, я так понял их два основных там...? Можно ли ЭТОЙ платой воспользоваться для этого и что там нужно вывести? И ещё — примеры есть у TI, или только с Миру по нитке, ну скажем так из вот этого небольшого списка:
UART — пример я дал в статье — с операционкой пишется за час с нуля.
SPI — не сложнее.
I2C — да, посложнее, чем SPI, но не намного.
USB — потратите неделю максимум.
В силу возраста и программирования только на Ассемблере, хотелось бы немного облегчить себе задачу, извините за пассаж.
0
с этой платы провода можно вывести и прошивать свою.
можно взять клон их програматора

На вашем контроллере 8К ОЗУ и 128К флеша, советую сразу поставить freeRTOS и подключить usblib от TI (у него примеры есть).
0
Спасибо!
Да я собственно для freeRTOS и взял, попробовать, если есть библиотеки — посмотрю. Помимо клона там есть варианты подешевле… Можно их использовать?
www.aliexpress.com/item/MSP430-BSL-Programmer-Download-Adapter-USB-Port/663754342.html
www.aliexpress.com/item/MSP430-JTAG-Parallel-Programmer-Debugger-Emulator-for-430-FET-MSP430-FLASH/659321368.html
И есть ли опыт по выведению с этой платы разъёма программатора?
0
лаунчпад можно использовать как отладчик не только для МК на лаунчпаде, отладочный интерфейс sbw и uart(BSL) подключаются к МК на плате через джамперы, если их снять то 2.54мм штырьки превращаются в разъём, к которому можно подключить любой другой МК на другой плате.
0
Спасибо!
Личный опыт превыше всего.
Всегда есть что сказать на последок — как говорил, Мюнхаузен…
0
Смотря по нуждам. FET с ланчпада покрывает большинство нужд, позволяя программировать MSP430 с интерфейсом Spy-Bi-Wire (SBW). JTAG позволяет программировать MSP430 без интерфейса SBW, но большинству такой МК попадается только один — в составе FET'а на ланчпаде, к тому же он элементарно делается на коленке.
Полноценный USB-FET позволяет программировать и по JTAG, и по SBW, покрывая весь ассортимент MSP430 (насколько я знаю) и это единственный программатор, позволяющий прожечь фьюз (этот фьюз отключает отладочный интерфейс МК, навечно). В принципе, его вполне можно собрать из обрезка на ланчпаде, добавив некоторое количество деталек и перепрошив.
А BSL — просто USB-UART адаптер для прошивки через встроенный бутлоадер.
0
Спасибо за советы!
Прислали Федексом Ланчпад — просто сказка на борту 2553 и ещё одна в комплекте 2552! По деньгам если эту пару микросхем брать отдельно, то будет ДОРОЖЕ (до прихода пакета заказал для попробовать поделки — 11$, а комплект 9,8$) что-то в Техасе происходит фантастическое (STM продает но неопределенно с ценой доставки — и может стать золотой)… Буду пробовать пришедшее, по переделке прошивателя на обрезке, обращусь к ВАм для консультации, пока попробую операционку и пару проектов меня заинтересовавших.
0
Извините! 2452 вторая микросхема.
0
Так у них свое производство всего что в ней есть… Цена самого лаунчпада копеечная для них. Прислав Вам лаунчпад они в убыток не уйдут, а обьем поделок, которые могут в результате вылится в неплохую промышленную серию возрастает!
+ Обьемы продаж и использование Fedex-a монструозны (только им и доставляют)! Так что ничего удивительного=))
0
По видимому, содержимое ti.eStore у них проходит по статье «расходы на рекламу». Потому и цены на многое ниже, чем стоит доставка.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.