|
|
  |
Работа с переменными в прерывании и основном теле, жутко неудобно выходит |
|
|
|
Oct 5 2015, 13:36
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Alexashka @ Oct 5 2015, 00:53)  Поясните пожалуйста, что значит readonly если я как читаю указатель, так и пишу его (инкрементирую)  И что делает эта строчка Код while(res != *dsc) res = *dsc; К сожалению не читал обсуждение темы, о которой Вы говорите, если есть ссылочка прошу направить в нужном направлении  не помню ссылочек уже. Мы читаем указатель, но не запрещаем прерывания. Указатель считается валидным, если за два чтения подряд он не был изменен процессом более высокого приоритета. Это и есть неатомарное чтение. Быстро ли, медленно ли? Наверное, если это имеет значение - пора утяжелять прерывание.
Сообщение отредактировал _Pasha - Oct 5 2015, 13:38
|
|
|
|
|
Oct 6 2015, 07:29
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(jcxz @ Oct 5 2015, 15:58)  Там где они модифицируются, можно делать только так, как я написал. А не напрямую глобальные. Если Вы этого не поняли, значит не поняли ничего в моих функциях. Да вроде понятно всЁ. Ну я например работаю непосредственно с глобальными и вроде все работает (блокирую прерывание непосредственно перед сравнением двух глобальных переменных). С копированием получается наглядней в том смысле что имеем только 2 места где нужно ставить блокировку прерывания, и к локальной переменной можно обращаться сколько угодно раз. Я правильно понимаю идею? Цитата(Сергей Борщ @ Oct 5 2015, 15:53)  Все три известные мне компилятора для x51 (Кейл, Иар и SDCC) позволяли объявлять указатель на конкретный тип памяти. Такие указатели и меньше места занимают и работают без этого ветвления. Посмотрите документацию на свой компилятор, наверняка они там есть. Проверил- и действительно: добавил спецификатор памяти в объявление указателя и всё лишнее в коде исчезло. Вот оно как оказывается, Михалыч (с)  Спасибо за информацию, Сергей! Цитата(_Pasha @ Oct 5 2015, 16:36)  Мы читаем указатель, но не запрещаем прерывания. Указатель считается валидным, если за два чтения подряд он не был изменен процессом более высокого приоритета. Это и есть неатомарное чтение. Быстро ли, медленно ли? Наверное, если это имеет значение - пора утяжелять прерывание. Понял идею, но это ведь можно провернуть не только с указателем, но и с любой переменной? Добавлено: попробовал Вашу функцию, вроде работает, только выдает предупреждение Цитата Pointer truncation A spaced pointer has been assigned some constant value which exceeds the range covered by the pointers memory space. For example: char idata *p1 = 0x1234; /* result is 0x34 */
|
|
|
|
|
Oct 6 2015, 08:41
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(jcxz @ Oct 6 2015, 11:10)  просто тупо подменить в моих функциях все использования локальных на соответствующие им глобальные - работать не будет. Загадка  ... В предположении, что read() не вызывается и rpos не модифицируется в прерывании: Код int read() { __disable_interrupt(); if (rpos == wpos) return -1; __enable_interrupt(); if (--rpos < 0) rpos = sizeof(buf) - 1; return buf[rpos]; } Не будет работать??
|
|
|
|
|
Oct 6 2015, 16:36
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(_Pasha @ Oct 6 2015, 14:51)  Ну я как бы тоже "из головы" писал, не с реального примера. У меня не случались неатомарные чтения по указателю. Мог и что-то упустить. Да нет все ок, разобрался  Заменил Код char *p = nonatomic_ptr(&r_pos); на Код char *p; p = nonatomic_ptr(&r_pos); и ашИпка ушла
|
|
|
|
|
Oct 8 2015, 07:58
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(Valentine Loginov @ Oct 8 2015, 11:35)  Идея в том, что атомарный флаг делается тоже через критические секции, другое дело, что к нему обращается программа куда реже, чем к индексам буфера, за счет чего снижается количество критических секций. Не знаю может это тоже самое, но у меня была была идея такая: в основной программе работаем не с самими индексами буфера, а с их копиями, причем перед обращением к переменным-копиями устанавливаем спец.флаг занятости, потом сбрасываем его. В прерывании текущее значение индекса копируется в переменную-копию в том случае, если флаг занятости не установлен, если же он установлен -копирование не производится (оно произойдет при последующих заходах в прерывание). Есть однако вероятность (хоть и небольшая, но есть) что при каждом заходе в прерывание флаг занятости будет установлен и мы так и не сможем обновить наши копии индексов. Однако в этом случае проблема с атомарностью не возникает, т.е. критические секции вообще не нужны и нет задержки входа в прерывание.
|
|
|
|
|
Oct 8 2015, 09:13
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Valentine Loginov @ Oct 8 2015, 10:35)  Идея в том, что атомарный флаг делается тоже через критические секции, другое дело, что к нему обращается программа куда реже... Не бывает так, что какой-то флаг, который что-то вне прерывания прикрывает, используется реже, чем то, что он прикрывает. Посему лишняя сущность в таких простых задачах. Если речь идет о множественных действиях каким-то перемеными, тогда да - экономнее один раз взвести-уронить, чем заниматься оформлением в критичекие секции каждой из переменных. Хотя и в таком случае нужно думать о простом расширении критической секции. Ну а вообше не забываем о том, что кроме огульного запрещения всех прерываний запрещать в критической секции можно ТОЛЬКО конкретные источники прерываний с которыми может быть конфликт.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|