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

 
 
> typeinfo + IAR v.5.11B, Как пользоваться?
alux
сообщение Jun 18 2008, 08:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Редактирование переменных типа double реализовал при помощи виртуальных функций. Какую именно переменную редактировать указывается при помощи указателя pValue, в которую передается адрес переменной :
Код
volatile double* pValue;            // Указатель на редактируемый параметр
volatile double __eeprom* pValueEE; // Указатель на редактируемый параметр в EEPROM
volatile double* param[] = {&area, &Kt, &Y0};
volatile double __eeprom* paramEE[] = {&ee_area, &ee_Kt, &ee_Y0};
..................
class TEditValue
{
public:
  void Up()       // k_right
  {

       if(pValue-- == *param) pValue = *(param+2);
       if(pValueEE-- == *paramEE) pValueEE = *(paramEE+2);
       ......................................... // какие-то действия при нажатии кнопки UP
       ftoa(*pValue, lcd_buf, 3, 0);
  }
  
  void Down()     // k_left
  {
      .................
  }
  
  void Right()    // k_enter
  {
     *pValue = round_to_pow(atof(lcd_buf), -3);  // округлить до 3 знака после запятой
     *pValueEE = *pValue;       // сохранить отредактированную переменную в EEPROM
  }
  
  void Numeric()  // 0...9
  {
          ..............
   }
};

// Функция, вызываемая при входе в пункт меню
void Level1Item1Sub1sub1_Func(void)
{
  TCritSect cs;
  
  pValue = *param;        // &area;
  pValueEE = *paramEE;    // &ee_area;
.............
}
Это все работает. Но теперь возникла необходимость реализовать почти те же действия для переменных типа unsigned char. Первое, что пришло на ум, использовать указатель void* pValue. Когда необходимо редактировать переменную типа unsigned char (при входе в соответствующий пункт меню), то указатель приводится к типу (unsigned char*).
Но возникает вопрос, как привести к конкретному типу указатель pValue в реализации виртуальной функции? Т.е. определение типа происходит в runtime. В C++ есть механизм динамического определения типа во время выполнения программы при помощи операции typeid и класса type_info. В IAR v.5.11B есть даже соответствующий заголовочный файл <typeinfo>. Но при использовании ее компилятор выдает ошибки

Error[Pe878]: Embedded C++ does not support run-time type information C:\Program Files\IAR Systems\Embedded Workbench 5.0\avr\INC\DLIB\typeinfo 62
Error[Pe020]: identifier "typeid" is undefined D:\Sasha\MyWork\IAR projects\device\include\tasks.h 351

Для чего нужен этот файл, если нельзя им пользоваться? И как мне решить проблему с редактированием разных типов переменных посредством одного указателя?

PS. Создание второго класса для редактирования переменных unsigned char типа не предлагать.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
alux
сообщение Jun 19 2008, 13:38
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Прошу помощь зала smile.gif

С редактированием и сохранением переменных типа double проблем нет. А вот с переменными типа unsigned char какая-то ерунда получается... Напомню, что есть две переменных unsigned char rate, nmax и две переменные unsigned char ee_rate, ee_nmax. Их адреса содержатся в глобальных массивах:
Код
unsigned char* option[] = {&rate, &nmax};
unsigned char __eeprom* optionEE[] = {&ee_rate, &ee_nmax};

В начале программы
Код
int main()
{
  // Initialise variables from EEPROM
  area = ee_area;        
  Kt = ee_Kt;          
  Y0 = ee_Y0;          
  rate = ee_rate;      
  nmax = ee_nmax;      
...........

При входе в пункт меню
Код
//  Редактирование установок прибора:
//  значения частоты АЦП (rate) и значения усреднения (nmax)
//------------------------------------------------------------------------------
void Level1Item1Sub2sub1_Func(void)
{
  TCritSect cs;
  
  real = false;
  
  pValue = *option;        // &rate;
  pValueEE = *optionEE;    // &ee_rate;

  ks0108GotoXY(94, 21);
  itoa(nmax, lcd_buf);
  ks0108PutStr(lcd_buf);
  
  ks0108GotoXY(94, 11);
  itoa(*(unsigned char*)pValue, lcd_buf);
  ks0108PutStr(lcd_buf);
  
  xx = 94;
  yy = 11;

  plcd_buf = lcd_buf;
  w = ks0108CharWidth(*lcd_buf)-2;  
  CurrentMode = &EditValue;
  
ks0108FillRect(0, 40, 20, 9, WHITE);                    // Эти три строки нужны только для посмотреть
ks0108GotoXY(0, 40);                                         //
ks0108PutChar((char)(*((unsigned char*)pValue+0))+'0'); //  содержимое указателя + 0, +1
}
Обе переменные сохранены в EEPROM (имеют значения 1 и 2 соответственно). Это можна увидеть по прочитанному hex-файлу EEPROM (последние два байта):
Код
:020000020000FC
:100000000000A03F829523405D8F52400102FFFF18
При входе в пункт меню вывожу содержимое указателя на экран
Код
ks0108PutChar((char)(*((unsigned char*)pValue+0))+'0');
выводит '1'.
А вот если вывести
Код
ks0108PutChar((char)(*((unsigned char*)pValue+1))+'0');
, то выводит '0'. Получается, что не правильно смещает указатель
Код
pValue = (unsigned char*)pValue + 1;


Делаю то же самое с переменными double - все в порядке, выводит то, что положено. В чем дело? 05.gif


PS. Какой-то абсурд! На всякий случай проверил в симуляторе этот кусочек:
Код
int main()
{
  // Initialise variables from EEPROM        
  rate = ee_rate;      
  nmax = ee_nmax;  
pValue = *option;        // &rate;
pValueEE = *optionEE;    // &ee_rate;
pValue = (unsigned char*)pValue+1;
pValue, как и положено, указывает на содержимое переменной nmax, инициализированной переменной ЕЕПРОМа ee_nmax = 2.
Затем, если вставить следующий кусок в main и вывести на индикатор значения массива unsigned char* option, который содержит адреса переменных unsigned char rate=1, nmax=2:
Код
int main()
{................
  lcd_Init();
  menu_Init();
pValue = *option;        // &rate;
ks0108FillRect(0, 40, 20, 9, WHITE);
ks0108GotoXY(0, 40);
ks0108PutChar((char)(*((unsigned char*)pValue+0))+'0');  
ks0108GotoXY(10, 40);
ks0108PutChar((char)(*((unsigned char*)pValue+1))+'0');
То выводит '1' и '0' (должно быть '1' и '2')

А если таким же образом выводить на индикатор содержимое массива double* param, который содержит адреса переменных double area=1.25, Kt=2.556, Y0=3.29:
Код
int main()
{................
  lcd_Init();
  menu_Init();
pValue = *param;        // &area;
ks0108FillRect(0, 40, 40, 9, WHITE);
ks0108GotoXY(0, 40);
ks0108PutChar((char)(*((double*)pValue+0))+'0');
ks0108GotoXY(10, 40);
ks0108PutChar((char)(*((double*)pValue+1))+'0');
ks0108GotoXY(20, 40);
ks0108PutChar((char)(*((double*)pValue+2))+'0');
То выводит '1', '2' и '3'? как и положено!!!
Как такое может быть?!! Почему не выводится содержимое unsigned char переменной через указатель со смещением (+1)? Объясните мне, пожалуйста. help.gif

PS2. Я пока вышел из положения так:
Код
  void Up()       // k_right
  {.......................
      if(pValue == *option) pValue = *(option+1);    
      else pValue = *option;                                      //pValue = (unsigned char*)pValue - 1;
  
  void Down()     // k_left
  {........................      
      if(pValue == *(option+1)) pValue = *option;
      else pValue = *(option+1);                                //pValue = (unsigned char*)pValue + 1;
Но это, понятное дело, работает только для массива из двух переменных.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 20 2008, 13:16
Сообщение #3


Гуру
******

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



Цитата(alux @ Jun 19 2008, 16:38) *
Как такое может быть?!! Почему не выводится содержимое unsigned char переменной через указатель со смещением (+1)? Объясните мне, пожалуйста. help.gif
Полагаю, внимательное исследование листинга поможет. И зачем столько приведений типов?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- alux   typeinfo + IAR v.5.11B   Jun 18 2008, 08:33
- - KRS   typeid же только на классы с виртуальными функциям...   Jun 18 2008, 08:48
|- - alux   Цитата(KRS @ Jun 18 2008, 11:48) typeid ж...   Jun 18 2008, 09:00
- - KRS   ЦитатаСледует помнить, что RTTI в собственном смыс...   Jun 18 2008, 09:44
- - alux   Понятно. Значит typeid мне не подходит. Тогда все ...   Jun 18 2008, 12:39
- - KRS   операции с указателями void* запрещены, потому что...   Jun 18 2008, 12:58
|- - alux   Цитата(KRS @ Jun 18 2008, 15:58) можно на...   Jun 18 2008, 13:08
|- - KRS   Цитата(alux @ Jun 18 2008, 17:08) Та же о...   Jun 18 2008, 13:22
- - alux   Получается, врут учебники: ЦитатаДля указателя на ...   Jun 18 2008, 13:48
|- - Сергей Борщ   Цитата(alux @ Jun 18 2008, 16:48) Получае...   Jun 18 2008, 14:19
|- - alux   Цитата(Сергей Борщ @ Jun 18 2008, 17:19) ...   Jun 18 2008, 14:44
|- - Сергей Борщ   Цитата(alux @ Jun 18 2008, 17:44) Если бы...   Jun 18 2008, 21:21
||- - alux   Цитата(Сергей Борщ @ Jun 19 2008, 00:21) ...   Jun 19 2008, 06:39
|- - IgorKossak   Цитата(alux @ Jun 18 2008, 17:44) ...Да и...   Jun 19 2008, 04:58


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

 


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


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