|
Два потока на си |
|
|
|
 |
Ответов
(1 - 11)
|
Sep 10 2008, 13:49
|
Участник

Группа: Свой
Сообщений: 56
Регистрация: 11-03-05
Из: Подмосковье
Пользователь №: 3 260

|
Принцип реализации многозадачности примерно один что на си что на асме. Описан например в книжке Кристиан Тавернье PIC-микроконтроллеры практика применения страница 172. Например одна задача выполняется в основном цикле а другая в прерывании. Далее организуем ветвление по необходимым признакам для выполнения дополнительных задач или организуем временной цикл и разносим задачи по времени.
|
|
|
|
|
Sep 13 2008, 19:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(sergeeff @ Sep 10 2008, 19:02)  Практически такие вещи на "чистом" С не напишешь Можно написать. Встречалась (сейчас не могу найти, может у кого-то из участников ссылка сохранилась) реализация корпоративной многозадачности на основе switch() case замаскированного хитрыми макросами препроцессора. Реализовано довольно красиво, но видя, насколько неэффективна реализация switch() case на некоторых (avr) контроллерах, наверное использование ОС (в которой что надо реализовано на ассемблере) будет более предпочтительным. Цитата(MacGregor @ Sep 13 2008, 21:18)  выделено мной красным цветом И что "именно"? Снова доктора сюда занесло?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 14 2008, 10:28
|
Группа: Участник
Сообщений: 13
Регистрация: 23-10-04
Пользователь №: 968

|
Цитата(Сергей Борщ @ Sep 13 2008, 22:08)  Можно написать. Встречалась (сейчас не могу найти, может у кого-то из участников ссылка сохранилась) Protothreads - Lightweight, Stackless Threads in C http://www.sics.se/~adam/pt/expansion.html
|
|
|
|
|
Sep 14 2008, 13:51
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Практически такие вещи на "чистом" С не напишешь Как раз для камней типа AVR пишется на раз. Необходимые средства в штатной сишной библиотеке есть. Код #include <setjmp.h>
jmp_buf main_task; jmp_buf rs_task; char rs_rstack[8]; char rs_cstack[64];
__interrupt void CNTX_SWT(void) { if (!setjmp(main_task)) //Запомнили контекст осн. задачи { longjmp(rs_task,1); //Перешли в контекст RS_TRX } }
#pragma vector=USART0_RXC_vect __interrupt __raw void rs_rx(void) { ((void(*)(void))CNTX_SWT)(); }
#pragma vector=USART0_UDRE_vect __interrupt __raw void rs_tx(void) { ((void(*)(void))CNTX_SWT)(); }
#pragma vector=USART0_TXC_vect __interrupt __raw void rs_txc(void) { ((void(*)(void))CNTX_SWT)(); }
#pragma vector=TIMER1_OVF_vect __interrupt __raw void rs_timeout(void) { ((void(*)(void))CNTX_SWT)(); }
void wait_int() { if (!setjmp(rs_task)) //Запомнили контекст RS_TASK { longjmp(main_task,1); //Перешли в контекст осн. задачи } }
__task __noreturn RS_TRX(void) { //Ну, например, вечное эхо for(;;) { char c; UCSR0B_RXCIE0=1; //Разрешили прерывания от приемника wait_int(); c=UDR; UDR=c; UCSR0B_TXCIE0=1; //Разрешаем прерывания от передатчика wait_int(); //Ждемс } }
void InitRS(void) { __disable_interrupt(); ((unsigned int *)rs_task)[10]=((unsigned int)rs_rstack)+7; //SP ((unsigned int *)rs_task)[8]=((unsigned int)rs_cstack)+64; //Y ((unsigned int *)rs_task)[9]=(unsigned int)RS_TRX; //Адрес перехода if (!setjmp(main_task)) longjmp(rs_task,1); //Переходим в RS_TRX __enable_interrupt(); } Тут будет выполнен запуск фоновой задачи RS_TRX, которая будет ждать символа из уарта и отправлять его обратно, ждать готовности передатчика и по кругу.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
Guest_Цыкетчик_*
|
Sep 24 2008, 13:25
|
Guests

|
Цитата(Rst7 @ Sep 14 2008, 17:51)  Как раз для камней типа AVR пишется на раз. Необходимые средства в штатной сишной библиотеке есть. ИМХО, это не от "камня" зависит а от разработчиков компилятора
|
|
|
|
|
Sep 24 2008, 16:31
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата ИМХО, это не от "камня" зависит Если смущает модификатор __raw (а это единственная вещь в приведенном коде, характерная для IAR'а, хотя, имеющая аналог, например, в GCC) - так он только для того, чтобы уменьшить время нахождения в состоянии с запрещенными прерываниями. Без него тоже все стреляет. А основную работу тут делают библиотечные функции setjmp/longjmp. Объясняю, почему "камень класса AVR" - потому что нет режима супервизора. На ARM, например, метод тоже имеет право на существование, но либо в виде принудительного переключения на другой поток (типа yield()), либо с отдельным костылем (возможно на асме, возможно intrinsic-функцией компилятора, если таковая существует) для сохранения и восстановления User Mode SP в процедуре IRQ. Аналогичный код с принудительным переключением прекрасно работает на x86 (однако, например MSVC слишком умный, он по longjmp уничтожает все объекты, созданные в стеке, посему работу с setjmp/longjmp надо выносить в отдельный файл, который собирать в режиме C, а не C++). PS Доктор, Вы теперь в каждой теме считаете нужным отписаться, а вдруг флуд поднимется?
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Sep 24 2008, 18:16
|
Гуру
     
Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823

|
Цитата(sergey sva @ Sep 10 2008, 15:53)  Как на си реализовать два потока, без использования ОС ? к примеру таймер 0 вызывает программу обработки прерываний, в который происходит переключение между потоками. Может что прочитать посоветуете или ссылку дадите. Вам точно шашечки потоки нужны? Для практических целей можно легко ограничить последовательность команд при обслуживании чего-нибудь, выйти и отдать управление другому сервису.
--------------------
Уходя, оставьте свет...
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|