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

 
 
> volatile всё-таки нужен или нет?, всё работает, но страшно
sigmaN
сообщение Mar 9 2013, 02:18
Сообщение #1


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Имеется программный ШИМ:
Код
typedef struct
{
    uint8_t    counter;
    uint8_t    top;
    uint8_t    compare_val;
    uint8_t    pin;
    uint8_t    enabled;
    volatile uint8_t    *port;        
} pwm_channel;

static pwm_channel    channels[PWM_MAXCHANNELS];


ISR(TIMER1_COMPA_vect)
{
    uint8_t    i;
    
    for ( i = 0; i < chnls_cnt; i++ )
    {        
        if ( ! channels[i].enabled )
            continue;
        
        channels[i].counter++;
        if ( channels[i].counter == channels[i].compare_val )
        {
            *channels[i].port |= 1 << channels[i].pin;        
        }
        else
        {    
            if ( channels[i].counter >= channels[i].top )
            {
                channels[i].counter = 0;
                *channels[i].port &= ~(1 << channels[i].pin);                                
            }    
        }                        
    }    
}

При этом channels[i].enabled, channels[i].top и channels[i].compare_val меняются посредством вызова функции spwm_configchannel(), нужно ли делать их volatile и почему всё работает и без этого?
Верно ли утверждение, что все глобальные переменные, доступ к которым осуществляется как в прерывании, так и в основном цикле нужно обязательно объявлять с volatile?
Я в принципе так всегда и делал, но вот тут вдруг всё работает даже с -O3 blink.gif

P.S. скурил Nine ways to break your systems code using volatile.. страшно. Щас ещё баръеры памяти расставлять побегу )


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
xemul
сообщение Mar 9 2013, 08:20
Сообщение #2



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(sigmaN @ Mar 9 2013, 06:18) *
При этом channels[i].enabled, channels[i].top и channels[i].compare_val меняются посредством вызова функции spwm_configchannel(), нужно ли делать их volatile и почему всё работает и без этого?
Верно ли утверждение, что все глобальные переменные, доступ к которым осуществляется как в прерывании, так и в основном цикле нужно обязательно объявлять с volatile?

volatile должны быть объявлены глобальные переменные, которые и _изменяются_ в прерывании, и используются вне прерывания.
channels[i].enabled, channels[i].top и channels[i].compare_val в прерывании не изменяются, и им volatile'ность не требуется.
Используется ли вне прерывания channels[i].counter++, не понятно.
Тем не менее, прерывание TIMER1_COMPA при исполнении spwm_configchannel() может привести к сбою формирования ШИМ, если не подстелить соломки.
(н-р, из приведённого кода не очевидно, что в spwm_configchannel() после "channels[i].enabled = 0" выполняется что-то, устанавливающее пин в определённое состояние, вроде "*channels[i].port &= ~(1 << channels[i].pin);", или что не приключится пропуск такта ШИМ при изменении channels[i].compare_val, или что ...; но, возможно, оно Вам и не актуально)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Mar 11 2013, 10:58
Сообщение #3


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата(xemul @ Mar 9 2013, 11:20) *
volatile должны быть объявлены глобальные переменные, которые и _изменяются_ в прерывании, и используются вне прерывания.
channels[i].enabled, channels[i].top и channels[i].compare_val в прерывании не изменяются, и им volatile'ность не требуется.
Используется ли вне прерывания channels[i].counter++, не понятно.
Хотелось-бы пруфлинк, если можно. Сколько копал на тему volatile - нигде не видел подобного разделения на то где требуется, а где не требуется volatile.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sigmaN   volatile всё-таки нужен или нет?   Mar 9 2013, 02:18
|- - xemul   Цитата(sigmaN @ Mar 11 2013, 14:58) Хотел...   Mar 11 2013, 11:26
- - Сергей Борщ   QUOTE (sigmaN @ Mar 9 2013, 04:18) Верно ...   Mar 9 2013, 09:01
|- - xemul   Цитата(Сергей Борщ @ Mar 9 2013, 13:01) А...   Mar 9 2013, 10:20
||- - XVR   Цитата(xemul @ Mar 9 2013, 14:20) Тогда н...   Mar 11 2013, 08:36
||- - xemul   Цитата(XVR @ Mar 11 2013, 12:36) Нет... В...   Mar 11 2013, 10:42
|- - Herz   Цитата(Сергей Борщ @ Mar 9 2013, 11:01) Е...   Mar 9 2013, 11:12
- - sigmaN   ЦитатаИспользуется ли вне прерывания channels[i].c...   Mar 9 2013, 10:56
- - _Pasha   Немного о другом. Зачем в теле цикла инкрементиров...   Mar 9 2013, 11:24
- - sigmaN   ЦитатаЭто чтобы при прерывании между обращениями к...   Mar 9 2013, 12:01
|- - Herz   Цитата(sigmaN @ Mar 9 2013, 14:01) но вед...   Mar 9 2013, 13:01
- - sigmaN   В приведенном примере после инкремента счётчика я ...   Mar 9 2013, 15:26
- - Herz   Понятно, спасибо. Хотя я отнёс бы такой случай к и...   Mar 9 2013, 21:04
- - sigmaN   Ну 30 или 100 это я так, для контраста придумал ) ...   Mar 10 2013, 00:46
- - sigmaN   ой не знаю не знаю... An implementation might def...   Mar 11 2013, 18:46
- - xemul   Цитата(sigmaN @ Mar 11 2013, 22:46) а мэй...   Mar 12 2013, 11:35
- - Andron77   Нашел понятное обьяснение про volatile переменные ...   May 1 2013, 08:24


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

 


RSS Текстовая версия Сейчас: 19th June 2025 - 10:50
Рейтинг@Mail.ru


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