Как я могу изменить память по последовательным адресам?

Я пытаюсь проверить оперативную память устройства, над которым я работаю, просматривая диапазон адресов, скажем, от 0x0 до 0xfef.

Я пробовал множество вещей, но ничего не сработало. Вот пример того, что я хочу сделать:

unsigned char temp;
unsigned char* addr = 0x0; // create ptr to point to address in mem

while(addr != 0xfef) // while not at end of mem
{
    temp = *addr; // save value at current addr
    *addr = 0xAA; // set value at addr to 0xAA
    if(*addr != 0xAA) // if value did not write properly, do not run software
        while(1);
    *addr = temp; // restore value at addr to original value
    ++addr; // move on to next addr
}

Единственная операция, которая работает в этом коде, — установка значения по адресу addr в 0xAA. Операторы while и if выдают ошибку: «Для сравнения требуются совместимые скалярные операнды с ошибкой [1128]».

Я также пытался создать указатели со значением адресов, которые я хочу, но попытка установить указатель на другой указатель приводит к ошибке «Несоответствие типа ошибки [1131] в назначении».

Заранее спасибо.

РЕДАКТИРОВАТЬ 2018-04-06:

Еще немного информации: я использую PIC18F66K80. Мы можем выполнить эту функциональность, используя SFR:

FSR0 = 0x00; 
while(FSR0 != 0xfef)
{
    temp = INDF0; 
    INDF0 = 0xAA; 
    if(INDF0 != 0xAA)
        while(1);
    POSTINC0 = temp;
};

Код C теперь запускается и изменяет память, оказывается, я искал не то место в памяти...

Однако, похоже, он не работает по адресу addr = 0xDAA. Замечу, что адрес указателя addr 0xD08, а адрес temp 0xD07.


person SamsquanchIsReal    schedule 05.04.2018    source источник
comment
while(addr != 0xfef) -- это никогда не будет оцениваться как true, если только sizeof(int) = 1. Вместо этого попробуйте объявить addr указателем на unsigned char. И измените if(addr != 0xAA) на if(*addr != 0xAA)   -  person r3mainer    schedule 06.04.2018
comment
Я предполагаю, что вы имели в виду while (*addr != 0xAA)...   -  person Lee Daniel Crocker    schedule 06.04.2018
comment
Я имел в виду это, и на самом деле у меня изначально был addr в качестве указателя на символ, но я изменил его, пытаясь заставить код работать. Спасибо за пятна.   -  person SamsquanchIsReal    schedule 06.04.2018
comment
Просто вопрос, не каждая ячейка ОЗУ доступна, в обычных условиях. Вы проверяли свой техпаспорт? Вы пытаетесь получить доступ к местоположению OK? Кроме того, какое у вас устройство? Возможно, эта информация поможет людям помочь вам лучше.   -  person    schedule 06.04.2018


Ответы (2)


Скорее всего, вы получаете конфликт типов, когда тип вашей константы — int, а тип указателя или разыменованного указателя — это что-то другого размера или знака. Приведение обоих к одному и тому же должно работать:

while(addr != (unsigned char*)0xfef) 
{
    temp = *addr; 
    *addr = 0xAA; 
    if(*addr != (unsigned char)0xAA) 
        while(1);
    *addr = temp; 
    ++addr; 
}
person mnistic    schedule 05.04.2018
comment
Спасибо за предложение. if(*addr != (unsigned char)0xAA) фактически вызывает предупреждение от знака к беззнаковому, возможно, потому, что включено продвижение целых чисел. - person SamsquanchIsReal; 06.04.2018
comment
@SamsquanchIsReal Да, это потому, что тип константы по умолчанию — целое число со знаком. Если вы также хотите избавиться от предупреждения, вы, вероятно, могли бы сделать это, используя переменную для сравнения вместо константы: unsigned char my_val = (unsigned char)0xAA;, а затем: if(*addr != my_val) - person mnistic; 06.04.2018

Спасибо вам за помощь. Оказалось, что я смотрел не в ту память, и поэтому не видел никаких изменений.

Еще одна проблема, с которой я столкнулся после того, как обнаружил, что код работает, была проблема, которая не существовала при использовании регистров специальных функций. Указатель и переменная перезаписывались, что приводило к сбою теста (или входу в цикл while).

Я исправил это, используя два указателя и два временных значения и проверив определенные условия, которые нарушили бы нормальную работу кода:

unsigned char temp, temp2;
unsigned char * addr, * addr2;

addr = (unsigned char*) 0x0; // set addr to start of ram

//continue until at end of usable memory
while(addr != (unsigned char*) 0xfef)
{
  //if not testing address of 'addr' pointer, continue testing byte by byte
  if((int) addr != (int) &addr)
  {
    //if 'addr' is pointing to location in ram where 'temp' is being stored,
    //use 'temp2' to hold the old value instead, since it has a dif address
    if(&temp != addr)
      temp = *addr; //copy value out of address
    else
      temp2 = *addr; //copy value out of address

    *addr = 0xAA; //set RAM value at 'addr' to 0xAA

    //if value at 'addr' equals 0xAA then continue test
    if(*addr != 0xAA)
      //if value is not equal to 0xAA, then hang forever
      while(1);

    //if 'addr' is pointing to location in ram where 'temp' is being stored,
    //pull old value from 'temp2' since that is where it is stored
    if(&temp != addr)
      *addr = temp; //copy old value back to address
    else
      *addr = temp2; //copy old value back to address

    ++addr; //move on to the next byte in memory
  }
  //if testing the address of the 'addr' pointer, then perform same test
  //differently by setting both bytes of the pointer to 0xAA, and then
  //validating that both bytes are what they should be, before returning the
  //'addr' pointer back to its original value.
  else
  {
    addr2 = addr; //save the position of the ram test

    //set RAM value at addr to 0xAAAA to test both bytes of ptr
    addr = (char*) 0xAAAA;

    //check to ensure bytes in memory changed like they should have
    if(addr != (char*) 0xAAAA )
      //if both bytes are not equal to 0xAAAA, then hang forever
      while(1);
    addr = addr2 + 2; //return to correct position in memory to continue test
                      //move two bytes forward since two bytes were tested
  }
}
person SamsquanchIsReal    schedule 06.04.2018