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

 
 
> Процесс, ограниченный по времени, помогите советом
_Pasha
сообщение May 24 2008, 05:17
Сообщение #1


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Доброго времени!
Требуется соорудить такую конструкцию:
предположим, у нас выполняется некий процесс. Считаем что-то, короче.
По наступлению прерывания от таймера необходимо из этого процесса выйти, да так, чтобы запомнить его состояние и впоследствии вернуться и продолжить его выполнение.
На ассемблере это делается элементарно.
Проблема в реализации этой конструкции на C - мешает нереентерабельность функций, огромные сохраняемые контексты.
Пока что представляю, как это сделать в рамках main() - с помощью setjump() и такой-то матери.smile.gif
Как это сделать в любой другой функции - как эти функции заточить по правильному - не имею понятия.
В идеале хочу выйти на что-то типа
Код
TIME_LIMITED_BLOCK(T_100us)
{/*code*/
}


взяв за основу for() как ATOMIC_BLOCK в WINAVR.

В общем,если есть какие-то советы, милости просим.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Pasha
сообщение Feb 14 2009, 13:06
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Опять приперло пересмотреть концепцию. Эх, ОС-пользователи, не близки вам страдания негритянского народа ! smile.gif
В общем, сделал красивше во сто раз, о чем и хвастаюсь:
Это препарированный timer.h
CODE

#ifndef TIMER_H_INCLUDED
#define TIMER_H_INCLUDED 1

typedef uint16_t timer_t;
//typedef uint32_t timer_t;

extern volatile timer_t ticks;
timer_t get_time(timer_t from);

#define ENABLE_LIFETIME_SW

#ifdef ENABLE_LIFETIME_SW
#include <setjmp.h>
typedef struct
{
timer_t time;
jmp_buf context;
} lifetime_t;

typedef void( * limited_proc_t)(void);
extern volatile lifetime_t *lifetime;
unsigned char time_limited(timer_t time, limited_proc_t process);

#endif

#endif // TIMER_H_INCLUDED


Это реализация time_limited

CODE


ISR(TIMER0_COMPA_vect)

{

ticks++;

#ifdef ENABLE_LIFETIME_SW
if((lifetime) && (lifetime->time >= ticks))
{
lifetime_t *tmp = lifetime;
lifetime = 0; // purge
longjmp(tmp->context,1);
}
#endif

}

/*...........*/

#ifdef ENABLE_LIFETIME_SW
unsigned char time_limited(timer_t time, limited_proc_t process)
{
lifetime_t list;
list.time = time + get_time(0);
if(setjmp(list.context)) return 1; // aborted
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) lifetime = &list;
process();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) lifetime = 0;// UPD
return 0;
}
#endif


Тестовая программа
CODE


#include <avr/io.h>
#include "timer.h"
void MyProcess(void);
int main(void)
{
time_limited(100,MyProcess);
return 0;
}

void MyProcess(void)
{
volatile int a,b,c;
a = b + c;
return;
}


И попутно вопрос. Приятно удивила реентерабельность void MyProcess(void)
CODE
void MyProcess(void)
{
6c: df 93 push r29
6e: cf 93 push r28
70: 00 d0 rcall .+0 ; 0x72
72: 00 d0 rcall .+0 ; 0x74
74: 00 d0 rcall .+0 ; 0x76
76: cd b7 in r28, 0x3d ; 61
78: de b7 in r29, 0x3e ; 62
volatile int a,b,c;
a = b + c;
7a: 2b 81 ldd r18, Y+3 ; 0x03
7c: 3c 81 ldd r19, Y+4 ; 0x04
7e: 8d 81 ldd r24, Y+5 ; 0x05
80: 9e 81 ldd r25, Y+6 ; 0x06
82: 82 0f add r24, r18
84: 93 1f adc r25, r19
86: 9a 83 std Y+2, r25 ; 0x02
88: 89 83 std Y+1, r24 ; 0x01
return;
8a: 26 96 adiw r28, 0x06 ; 6
8c: 0f b6 in r0, 0x3f ; 63
8e: f8 94 cli
90: de bf out 0x3e, r29 ; 62
92: 0f be out 0x3f, r0 ; 63
94: cd bf out 0x3d, r28 ; 61
96: cf 91 pop r28
98: df 91 pop r29
9a: 08 95 ret


Это всегда так должно быть? Или этим можно управлять как-то ?
UPD исправлено - вставил пропущенную строчку.
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 23:47
Рейтинг@Mail.ru


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