Реклама на сайте DatasheetsDatasheets

KAZUS.RUN - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Книги и журналы
FAQ по электронике

  Datasheets
Поиск SMD
Онлайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Схемы и проекты
Принципиальные схемы
  Программы
Каталог сайтов
Калькуляторы
  Форумы по электронике
Помощь проекту

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы

Своя RTOS

Непрочитано 03.03.2015, 19:34  
Fangir
Временная регистрация
 
Регистрация: 31.10.2014
Сообщений: 59
Сказал спасибо: 24
Сказали Спасибо 7 раз(а) в 7 сообщении(ях)
Fangir на пути к лучшему
По умолчанию Своя RTOS

Наверно, я тут уже достал всех с этой темой

Но после недели упорного изучения "всего этого", родил такое чудо
Которое не работает (ктоб сомневался )

Собственно в этом и вопрос, я в ступоре, что не так?
Светодиоды хоть и не с точностью, но мигать должны, но все зависает на нулевом процессе

Код:
// Макросы
//==================================================  ==================================================  ==
#define HIGH_P(port, num) ( port |= (1 ‹‹ num) ) // 1. Высокий уровень
#define LOW_P(port, num) ( port &= ~(1 ‹‹ num) ) // 0. Низкий уровень
#define OUT_P(port, num) ( port |= (1 ‹‹ num) ) // Выход
#define IN_P(port, num) ( port &= ~(1 ‹‹ num) ) // Вход
#define SCAN_P(port, num) ( port & (1 ‹‹ num) ) // Поступает ли сигнал на порт
#define F_CPU 16000000UL

// Сохраняем контекст
#define SAVE_CONTEXT()	\
	asm volatile ( \
		"push	r0		\n\t"	\
		"in	r0, __SREG__	\n\t"	\
		"cli			\n\t"	\
		"push	r0		\n\t"	\
		"push	r1		\n\t"	\
		"push	r2		\n\t"	\
		"push	r3		\n\t"	\
		"push	r4		\n\t"	\
		"push	r5		\n\t"	\
		"push	r6		\n\t"	\
		"push	r7		\n\t"	\
		"push	r8		\n\t"	\
		"push	r9		\n\t"	\
		"push	r10		\n\t"	\
		"push	r11		\n\t"	\
		"push	r12		\n\t"	\
		"push	r13		\n\t"	\
		"push	r14		\n\t"	\
		"push	r15		\n\t"	\
		"push	r16		\n\t"	\
		"push	r17		\n\t"	\
		"push	r18		\n\t"	\
		"push	r19		\n\t"	\
		"push	r20		\n\t"	\
		"push	r21		\n\t"	\
		"push	r22		\n\t"	\
		"push	r23		\n\t"	\
		"push	r24		\n\t"	\
		"push	r25		\n\t"	\
		"push	r26		\n\t"	\
		"push	r27		\n\t"	\
		"push	r28		\n\t"	\
		"push	r29		\n\t"	\
		"push	r30		\n\t"	\
		"push	r31		\n\t"	\
		"lds	r26, this_sp	\n\t"	\
		"lds	r27, this_sp + 1	\n\t"	\
		"in 	r0, 0x3d	\n\t"	\
		"st		x+, r0		\n\t"	\
		"in 	r0, 0x3e	\n\t"	\
		"st		x+, r0		\n\t"	\
	)

// Перемещаем указатель стека
#define LOAD_PTR_TO_SP() \
	asm volatile ( \
		"lds    r26, this_sp     \n\t"   \
		"lds    r27, this_sp + 1 \n\t"   \
		"ld     r28, x+         \n\t"   \
		"out    __SP_L__, r28   \n\t"   \
		"ld     r29, x+         \n\t"   \
		"out    __SP_H__, r29   \n\t"   \
	)

// Востанавливаем контекст
#define RESTORE_CONTEXT()\
	asm volatile ( \
		"lds 	r26, this_sp			\n\t"	\
		"lds	r27, this_sp + 1		\n\t"	\
		"ld		r28, x+				\n\t"	\
		"out	__SP_L__, r28		\n\t"	\
		"ld		r29, x+				\n\t"	\
		"out	__SP_H__, r29		\n\t"	\
		"pop	r31		\n\t"	\
		"pop	r30		\n\t"	\
		"pop	r29		\n\t"	\
		"pop	r28		\n\t"	\
		"pop	r27		\n\t"	\
		"pop	r26		\n\t"	\
		"pop	r25		\n\t"	\
		"pop	r24		\n\t"	\
		"pop	r23		\n\t"	\
		"pop	r22		\n\t"	\
		"pop	r21		\n\t"	\
		"pop	r20		\n\t"	\
		"pop	r19		\n\t"	\
		"pop	r18		\n\t"	\
		"pop	r17		\n\t"	\
		"pop	r16		\n\t"	\
		"pop	r15		\n\t"	\
		"pop	r14		\n\t"	\
		"pop	r13		\n\t"	\
		"pop	r12		\n\t"	\
		"pop	r11		\n\t"	\
		"pop	r10		\n\t"	\
		"pop	r9		\n\t"	\
		"pop	r8		\n\t"	\
		"pop	r7		\n\t"	\
		"pop	r6		\n\t"	\
		"pop	r5		\n\t"	\
		"pop	r4		\n\t"	\
		"pop	r3		\n\t"	\
		"pop	r2		\n\t"	\
		"pop	r1		\n\t"	\
		"pop	r0		\n\t"	\
		"out 	__SREG__, r0	\n\t"	\
		"pop	r0		\n\t"	\
	)


// Кол-во процессов
#define TASKS_COUNT 2


// Стандартные библиотеки
#include ‹avr/io.h›
#include ‹avr/interrupt.h›
#include ‹util/delay.h›



// Струнтура контекста
struct __attribute__((__packed__)) tack_data {
	unsigned int stack_pointer;  // Указатель стека
	unsigned int stack_space;    // Выделяемое место в стеке
	void(*tack_fn)(void);        // Ссылка на процесс
};

// Массив всех процессов
struct tack_data tack_block[TASKS_COUNT];

// id текущего прорцесса
unsigned char this_tack_id = 0;

// Ссылка на текущий контекст
struct tack_data *this_tack_data;

// Текущий указатель стека
unsigned int *this_sp;


// ISR_NAKED — запрещает компилятору делать функцию инлайновой
ISR(TIMER0_OVF_vect, ISR_NAKED) {

	// Сохраняем контекст
	SAVE_CONTEXT();

	// Сбросить таймер
	TCNT0 = 0x38;

	// Переключение задачи
	this_tack_id++;
	if(this_tack_id ›= TASKS_COUNT) {
		this_tack_id = 0;
	}
	this_tack_data = &tack_block[this_tack_id];

	// Меняем указатель стека
	this_sp = &tack_block[this_tack_id].stack_pointer;

	// Востанавливаем контекст
	RESTORE_CONTEXT();

	asm volatile("reti");
}


// Создать процесс
void new_tack(void(*t)(), unsigned int stack_space) {
	tack_block[this_tack_id].stack_pointer = 0;
	tack_block[this_tack_id].stack_space = stack_space;
	tack_block[this_tack_id].tack_fn = t;
	this_tack_id++;
}


void init_RTOS() {
	unsigned char i;

	// Текущий указатель стека
	unsigned int sp = SPH ‹‹ 8 | SPL;

	// Сбрасываем, ибо юзали для newTasck
	this_tack_id = 0;

	// Обходим все процессы
	for(i = 0; i ‹ TASKS_COUNT; i++) {

		// Записываем указатель стека
		tack_block[i].stack_pointer = sp;

		// Поднимаем точку указателя стека
		sp -= tack_block[i].stack_space; // 100 байт на регистры и т.п.
	}


	// Инициализация таймера на 0.1мм
	ASSR = 0 ‹‹ AS0;
	TCCR0 = (0 ‹‹ WGM00) | (0 ‹‹ COM01) | (0 ‹‹ COM00) | (0 ‹‹ WGM01) | (0 ‹‹ CS02) | (1 ‹‹ CS01) | (0 ‹‹ CS00);
	TCNT0 = 0x38;
	OCR0 = 0x00;
	TIMSK = (0 ‹‹ OCIE2) | (0 ‹‹ TOIE2) | (0 ‹‹ TICIE1) | (0 ‹‹ OCIE1A) | (0 ‹‹ OCIE1B) | (0 ‹‹ TOIE1) | (0 ‹‹ OCIE0) | (1 ‹‹ TOIE0);
	sei(); // Разрешаем прерывания

	// Записываем ссылку на нулевой процесс в "this_tack_data"
	this_tack_data = &tack_block[0];

	// Записываем ссылку на указатель стека
	this_sp = &tack_block[0].stack_pointer;

	// Перемещаем указатель куда надо
	LOAD_PTR_TO_SP();

	// Запускаем нулевую задачу
	tack_block[0].tack_fn();
}


// Первый процесс
void tack_1(void) {
	while(1) {
		HIGH_P(PORTE, 5);
		_delay_ms(500);
		LOW_P(PORTE, 5);
		_delay_ms(500);
	}
}

// Второй процесс
void tack_2(void) {
	while(1) {
		HIGH_P(PORTE, 4);
		_delay_ms(200);
		LOW_P(PORTE, 4);
		_delay_ms(200);
	}
}

// Главная функция
int main(void) {
	OUT_P(DDRE, 4);
	OUT_P(DDRE, 5);

	new_tack(tack_1, 200);
	new_tack(tack_2, 200);

	init_RTOS();

	while(1);
}
Реклама:
Fangir вне форума  
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Изучение RTOS Fangir AVR 9 02.03.2015 12:43
Вери смалл RTOS для AVR8b посоветуйте whoim AVR 13 01.02.2015 03:55
RTOS ua3rad AVR 1 03.09.2014 23:05
Установка RTOS на STM32F10x dmitriycor Микроконтроллеры, АЦП, память и т.д 11 12.05.2011 17:39
AVR RTOS alberio Микроконтроллеры, АЦП, память и т.д 6 15.10.2009 23:40


Часовой пояс GMT +4, время: 11:40.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.