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

 
 
> Keil RTX-166 Tiny, проблема с переключением стеков...
Legotron
сообщение May 30 2007, 12:34
Сообщение #1


инопланетянин
***

Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832



Добрый день!

Я решил использовать RTOS от Keil RTX-166 Tiny для Infineon, потому что эта ОСь халявная и очень простая(на мой взгляд).
Но в ней есть документированная проблема следующего характера:

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

Дается 2 варианта решения проблемы:

1 - не использовать автоматичесие переменные.
2 - работать с ними в критической секции(заморозка планировщика).

У меня такой вопрос - эта система ПОЛНОЕ говно или я чего-то не понимаю?
Ведь для того, чтобы вызвать любую функцию, в теле задачи мне придется помещать её в крит. секцию или делать все переменные внутри функции статическими. И так для каждой ф-ции с нестатическими переменными. Как мне кажется, одинаково как пичканье программы повсюду крит. секциями, так и ф-ций статическими переменными является дурным тоном(и не только).

Что посоветуете в данном случае?

Текст нотации от Keil:
Цитата
1. Problems with pointers to stack based variables
==================================================
The RTX166 Tiny uses a stack swapping method to reduce the required stack
space of the whole system. However, due to the stack swapping, the addresses
of automatic variables change during program execution. This can cause
problems with the program execution when you use a pointer to an automatic
variable in your program.

There are a couple of ways arround that problem as explained in the follwoing
sample program.

#pragma MOD167
#include <string.h>
#include <reg167.h>
#include <intrins.h>

#define TIM_INT_ENABLE T0IE /* same configuration as in CPUTIMER.INC */

/*****************************/
/* RTX166 Tiny Task Function */
/*****************************/
void job (void) _task_ 0 {
char a[16]; /* stack based variable */
static char b[16]; /* static variable */

strcpy (a, "Hello World"); /* this can fail since the address of the
variable 'a' can change due to stack
swapping during a task switch */

/* as a work-around you can disable the RTX166 Tiny Timer Interrupt */
TIM_INT_ENABLE = 0; /* disable RTX166 Tiny Timer */
_nop_ (); /* two NOP's to make sure that 166/167 */
_nop_ (); /* hardware has disabled the interrupt */
strcpy (a, "Hello World"); /* now it works, since there can be not
RTX166 Tiny task switch */
TIM_INT_ENABLE = 1; /* enable RTX166 Tiny Timer */

/* another solution is to use static variables instead of stack based
variables as in the following example */
strcpy (b, "Hello World"); /* this will always work. The variable 'b'
is a static variable which has a fixed
memory location */
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
DimaM
сообщение May 30 2007, 13:06
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 103
Регистрация: 17-12-06
Из: село
Пользователь №: 23 615



я кстати тоже собираюсь эту операционку использовать, однако еще не попробовал.

по поводу " Problems with pointers to stack based variables "
то мне кажется речь идет только об указателях внутри функций
это ограничение, но не смертельно.
другое дело - я не до конца понял что они называю автоматическими переменными ?
образуются они только тогда когда с указателями работаешь или еще в каких то случаях?

кстати, если у кого есть исходники для этой RTX для ARM пришлите пожалуйста на мейл
dmilioukov на yahoo.com
Go to the top of the page
 
+Quote Post
Legotron
сообщение May 30 2007, 13:34
Сообщение #3


инопланетянин
***

Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832



Цитата(DimaM @ May 30 2007, 17:06) *
я кстати тоже собираюсь эту операционку использовать, однако еще не попробовал.

Я её чуть-чуть попробовал smile.gif
Вот и думаю стоит ли использовать дальше или сразу остановится.
Цитата(DimaM @ May 30 2007, 17:06) *
по поводу " Problems with pointers to stack based variables "
то мне кажется речь идет только об указателях внутри функций
это ограничение, но не смертельно.
другое дело - я не до конца понял что они называю автоматическими переменными ?

Тема такая:
Автоматическая переменная - это обычная переменная, которая размещается в стеке (вообщем все мы на заре начинали работать с auto переменными не задумываясь об этом smile.gif ). Тип она может иметь абсолютно любой, в том числе и указатель и объект класса и.т.д.
Цитата(DimaM @ May 30 2007, 17:06) *
образуются они только тогда когда с указателями работаешь или еще в каких то случаях?

Это не зависит от способа работы.

А по поводу "не смертельно":
Я стараюсь при написании программ сводить на минимум количество глобальных и статических переменных, и использовать их только в крайней необходимости. Глобальные лучше вообще не использовать(по крайней мере в ООП).
А с этой ОСью придется почти все переменные делать СТАТИЧЕСКИМ или ГЛОБАЛЬНЫМИ(что еще хуже)

Другой подход - критические секции(отключении планировщика) тоже перспектива так себе.
Существуют рекомендации также по минимизации количества/времени критических секций, потому что они отрубают систему. Если ими весь код натыркан то возникает вопрос: ЗАЧЕМ ВООБЩЕ СИСТЕМА, если она большинство времени заморожена?

Вообщем у меня пока пессимистический настрой к этой системе. mad.gif
Go to the top of the page
 
+Quote Post
DimaM
сообщение May 30 2007, 20:51
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 103
Регистрация: 17-12-06
Из: село
Пользователь №: 23 615



сначала просто подумал про указателеи что только они должны быть статическими.
согласен что делать все переменные статическими глупо.
но если локальные переменные могут быть изменены вызовами функция то это какая то фигня мне что то не верится 07.gif
Go to the top of the page
 
+Quote Post
Legotron
сообщение May 30 2007, 23:34
Сообщение #5


инопланетянин
***

Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832



Цитата(DimaM @ May 31 2007, 00:51) *
но если локальные переменные могут быть изменены вызовами функция то это какая то фигня мне что то не верится 07.gif

На сайте Keil.com есть аппноут по поводу проблем, которые могут возникать с функцией printf как раз из-за локальных переменных. Разумеется эта ф-ция не единственная жертва, просто как мне кажется, у людей чаще возникает вопрос: Почему с RTX166 Tiny глючит printf? потому, что ф-ция printf связана с портом RS(ждет завершения putchar) и тут-то планировщик делает свое черное дело smile.gif когда поджимает другая задача. Там предлагается отключение системного таймера на время выполнения функции. Бред!

Думаю есть еще такие выходы из проблемы:

1 - использовать кооперативную планировку(с добровольной передачей управления другой задаче)
Тогда все приемущества циклической планировки x на 0. Плохо, но можно. Зато не надо парится со статикой и системным таймером!
2 - Выбрать период таймаута задачи заведомо большим чем самая длинная ф-ция. Более бредовый подход, т.к. мало кто знает скока будет в данный момент работать ф-ция (из разряда "Знал бы прикуп, жил бы в Сочи")
3 - Забросить к черту эту систему и перейти на UCOS (сложно, зато универсально и возможностей на порядок больше)
4 - Ждать предложений по решению проблемы
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 7 2007, 11:41
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(Legotron @ May 30 2007, 16:34) *
У меня такой вопрос - эта система ПОЛНОЕ говно или я чего-то не понимаю?

Вы чего-то не понимаете.

Я с успехом использовал RTX-166 Tiny. Конечно, нельзя брать адрес от автоматической переменной, но меня это не смутило. Честно говоря, даже не могу вспомнить, когда мне приходилось в последний раз брать адрес локальной переменной.
Кстати, вполне ясно, что мы получаем в обмен на это ограничение: не нужно выделять стек отдельно под каждую задачу, так как суммарный расход стека равен сумме расходов для каждой задачи. В общем, изрядная экономия.

Цитата(Legotron @ May 31 2007, 03:34) *
Там предлагается отключение системного таймера на время выполнения функции. Бред!


Совсем не бред. Вполне нормальное решение. Оберните printf макросом, который будет отключать и включать прерывание таймера, и используйте этот макрос.

Цитата(Legotron @ May 31 2007, 03:34) *
2 - Выбрать период таймаута задачи заведомо большим чем самая длинная ф-ция. Более бредовый подход, т.к. мало кто знает скока будет в данный момент работать ф-ция (из разряда "Знал бы прикуп, жил бы в Сочи")


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

Честно говоря, меня несколько задел такой "наезд" на RTX-166 Tiny. Не подходит - не используйте. Нужен совет - пожалуйста. А огульно обзывать вполне приличный софт полным г. - это перебор.
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Jun 7 2007, 12:37
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата
Совсем не бред. Вполне нормальное решение. Оберните printf макросом, который будет отключать и включать прерывание таймера, и используйте этот макрос.

А лучше вовсе не использовать printf. Есть sprintf - печатайте в разных задачах в свои буфера, потом выводите их своей функцией куда угодно (и синхронизируйте как нравится).
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 25th July 2025 - 01:06
Рейтинг@Mail.ru


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