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

 
 
> CodeVision+указатели+прерывание, Искажение указателя при прерывании
troy97
сообщение Sep 25 2009, 06:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 12-01-09
Из: Донецк, Украина
Пользователь №: 43 218



Написал вот такой код:
Код
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
        // Stop timer
        TCCR2=0x00;

        if(get_incoming_pkt()==3){
        
                switch (check_command(myip)) {
                
                case 0:
                        strcpyf(service_msg, "Micro_device#0:not_a_command");
                        service_msg[13]=device_id;
                        send_to_server(service_msg, service_msg_len);                
                break;
                                
                case 1:
                        init_ip_arp_udp(mymac,myip);
                        strcpyf(service_msg, "Micro_device#0:IP_changed");
                        service_msg[13]=device_id;
                        send_to_server(service_msg, service_msg_len);                
                break;
                
                case 2:
                        strcpyf(service_msg, "Micro_device#0:comm_2_done");
                        service_msg[13]=device_id;
                        send_to_server(service_msg, service_msg_len);                
                break;                
      
                default:
                        strcpyf(service_msg, "Micro_device#0:command_Error");
                        service_msg[13]=device_id;
                        send_to_server(service_msg, service_msg_len);
                };                      
        };        
                
        // Start timer
        TCCR2=0x07;
        TCNT2=0x00;
} // end of interrupt


void main(void)

....
unsigned int* pointer;
......

          pointer=get_adc_data();
          for(i=0;i<6;i++){    
                data_msg[16+2*i]=(*(pointer+i))>>8; //MSB
                data_msg[16+2*i+1]=(*(pointer+i)) & 0xff; //LSB
          };

......


Проблема следующая: при возникновении прерывания во время работы с указателем, значения записываемые в data_msg[], искажаются.
При запрете прерываний на этот кусок кода, всё работает нормально.

Сообщение отредактировал troy97 - Sep 25 2009, 07:20
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Sergey Reva
сообщение Sep 26 2009, 06:15
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 22-04-07
Из: Poltava/Kharkov
Пользователь №: 27 243



get_adc_data возвращает указатель на локальную переменную (созданую с стеке), естественно при входе в прерывание по тем адресам (где были значения analog_vals_arr) создаются другие локальные переменные. Нужно объявить analog_vals_arr как static, либо переделать get_adc_data так чтобы она заполняла переданый ей (указателем) массив.

p.s.
ладно, попробую поменять порядок слов smile.gif

Сообщение отредактировал Sergey Reva - Sep 26 2009, 06:36
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Sep 27 2009, 18:40
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Sergey Reva @ Sep 26 2009, 09:15) *
get_adc_data возвращает указатель на локальную переменную (созданую с стеке), естественно при входе в прерывание по тем адресам (где были значения analog_vals_arr) создаются другие локальные переменные. Нужно объявить analog_vals_arr как static, либо переделать get_adc_data так чтобы она заполняла переданый ей (указателем) массив.


+1.

Причём надо отметить, что это не "неточность", а грубая ошибка. С формальной точки зрения, вы передаёте указатель на несуществующие данные. Прогнозировать дальнейшее поведение системы не представляется возможным. Оно будет меняться от компиляции к компиляции. То есть будет зависеть от распределения памяти компилятором. Иными словами изменения в другой части программы, логически совершенно не связанной, может изменить поведение этого куска.

Я бы не применял static, так как выглядит неестественно. Я бы либо сделал массив глобальным, либо объявил его в месте использования и передавал процедуре на неё указатель, как рекомендовал Sergey Reva.
Go to the top of the page
 
+Quote Post



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

 


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


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