Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: адреса не выделенной памяти
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
RLC
Использую NIOS II econom. При отладке в дебагере замечаю что сохранения данных регистров(r2,r3,ra...) просходит по адресам в памяти которые не выделял. Язык программирования "С".

То есть происходит вход в функцию и выпоняетя команда сохранения адреса возврата(stw ra,24(sp)). А SP равен 0xee4bf4c8. При этом адресное пространство RAM у меня 0x800020-0x80A000. При этом в одной и той же функции иногда сохранение происходит(адреса в котором сохраняется и не сохраняется состояние регистров разное, 0xee4bf4c8 и 0xee4c4888 ) а иногда не происходит. и при выходе из функции регитр ra(возврата из функции) равен 0, что при выполнении ret вызывает перезагрузку процесора.
Вопроса 3:
что за адреса?(предполагаю что кэш процессора)
Почему не всегда происходит сохранение?
Что с этим делать?=)
RLC
решил проблему. дело было в том что я создавал массив размера в зависимости от входных данных и иногда массив становился непомерно большим и в регистре SP появлялись сумашедшие адреса. После фильтрации размера массива всё стало рабочим.
Странно одно: инога то в эти сумашедшие адреса не относящиеся к моему RAM всё таки запись был успешна!
Alex77
Цитата(RLC @ Jan 15 2015, 15:43) *
решил проблему. дело было в том что я создавал массив размера в зависимости от входных данных и иногда массив становился непомерно большим и в регистре SP появлялись сумашедшие адреса. После фильтрации размера массива всё стало рабочим.
Странно одно: инога то в эти сумашедшие адреса не относящиеся к моему RAM всё таки запись был успешна!

Как говорится "ежу понятно" (с) wink.gif

Происходил "заворот адресов" на реальный диапазон адресов.
WitFed
У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая.
И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения.
А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно.
Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно.
RLC
Цитата(WitFed @ Jan 16 2015, 14:49) *
У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая.
И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения.
А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно.
Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно.

Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати.
У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер.
И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался wacko.gif
Alex77
Цитата(RLC @ Jan 16 2015, 15:44) *
Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати.
У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер.
И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался wacko.gif

Несколько бредово выглядит... "Штудент штоли ???"
1)Кусок С-ишника в студию про "У меня было так: вход в функцию и в ней объяляется этот массив."

2)0x55CE FF34 гдето в 0x80 0020-0x80 A000 и "сохраняется"
Golikov A.
Да чувствуется некое непонимание%)
Цитата
я каждый раз я создаю, но очистки то не происходит!


и сразу решение
Цитата
может мне тогда malloc'ом пользоватья и в конце free делать



Опускаем вопросы создания массивов, того что такое стэк и куча. Сосредоточимся на решении проблемы "каждый раз создаю, но очистки то не происходит", почему это вас ведет не к решению сделать массив 1 раз и использовать его чтобы стэк не тилипать, а к наоборот более сложному изнасилованию кучи через доп функцииsm.gif?
RLC
1)
Код
writeBytes(alt_u8 array[], alt_u32 address,alt_u8 id, alt_u32 data){
    alt_u8
              tempArray[data],//тот самый статически выделенный массив(сейчас создаётся в tempArray). иногда data это размер в последствии пришедших данных а иногда это просто любое число(вот тогда и возникали непонятные адреса)
              
         ...
     switch(id){
        case(...):
        break;
        case(...):
        break;
        case(0x35):
            writeBlockData(array,data)//тут теперь процедура в которой создаётся массив c длинной дата
         break;
      }

}


2)
Код
     ....
      alt_u8 *memory=0;
      memory=address;
     for(index=0;index<(data+2);index++){
         *(memory+index)=IORD_DIRECT(....);
         ...
}


если честно то сейчас уже интересно только куда сохранялись данные по адресам которые я не выделял. В какое физическое место. т.к ситуация решена.

ну а с созданием массива я тупил, согласен. Ссылка на вершину масива теряется поле входа из функции. Где тут вымучивание кучи? Глобальные массивы не люблю. вообще глобальные не люблю. хотя тут наверное оптимально было бы. Но опять же я только минимальный массив создать смогу, а при приходе точного необходимого размера мне придётся вызывать каждый раз malloc. Либо создавать сразу гиганский массив на всю доступную мне память.
Golikov A.
MMU - MPU на вас нету.
сохраняются данные туда же куда и при
int[10] Data;
Data[11] = 10;

то есть в память с адресом &Data[0] + 11*4, а что там лежит одному вам известно. Так можно спокойно загадить данные, другие переменные, даже если очень постараться можно код программы завалить.

Дальше больше если выбрать ячейку вне пределов вашей памяти, она свернеться и попадет куда-то в адрес который у вас есть.

Вообще это базовые понятия программирования, винды тут нет которая напишет приложение выполнила недопустимую ошибку и будет закрыто, или как она там писала?


Локальные массивы выделяются на стеке, стек кончиться начнут гадить оперативку. Глобальные массивы выделены сразу в оперативке, менять их размеры на лету не выйдет. Массивы динамические создаются на куче, со всеми делами по организации, дефрагментации и прочей байде с кучей. Потому вместо одноразового массива выделяемого на стеке придумать одноразовый массив в куче - это мучение кучи, созданием и удалением массивов, ее фрагментации и так далее...





хорошим тоном в вашем случае является проверка data на допустимые значения

а вторым хорошим тоном является создавать массив всегда одной величины с запасиком, и проверкой влезет ли дата в него или нет. А то так далеко можно уйти, в непредсказуемые дали...
RLC
Golikov A., спасибо за объяснение. Когда я пишу по конкретным адресам, то конкретные адреса в ходят в разряд памяти не являющейся RAM для NIOS. Тоесть это память в которую я пишу и заю что она незаорется программой. от такая особенность.
ну вот странно у меня адресов таких больших нет в Qsys проекте. вот максимальные как раз 0x80 a000. Вся переферия меньшие адреса имеет.
Всем спасибо за внимание sm.gif
Golikov A.
ПИПЕЦ!!!!!
просото пипец!!!

вы что нибудь про шины адреса знаете?
если у вас шина 2 бита и программа занимает адреса 0, 1, 2, 3

то запись в адрес 4, 5, 6, 7 - это запись в 3 битную шину
4 = 100
5 = 101
6 = 110
7 = 111
, а теперь представьте что это 3 бита выставлдяются на 2 битной шине, что будет, откинеться старший бит и что убдет?
100 = 00
101 = 01
110 = 10
111 = 11
понято что стало?
0 1 2 3

когда у вас что-то за пределами РАМ для ниос, это что-то ограничено разрядностью шины адреса, и запись туда, это запись в младшие адреса.


Нельзя так делать, нельзя писать туда, куда надеетесь программа не дотянется! Для этого есть линкеры, можно выделить область памяти, регион, запретить линкеру туда лезть, и использовать для своих нужд, зная что там точно не будет программы, но только так! никак иначе...

Можно взять большой массив выделить 1000 элементов, и по указателю обращаться в него как в память, и знать что это не загадиться, а так как вы решили эту проблемму - это ПИПЕЦ!!!!


Alex77
Цитата(Golikov A. @ Jan 22 2015, 17:42) *
ПИПЕЦ!!!!!
просото пипец!!!

вы что нибудь про шины адреса знаете?
если у вас шина 2 бита и программа занимает адреса 0, 1, 2, 3

то запись в адрес 4, 5, 6, 7 - это запись в 3 битную шину
4 = 100
5 = 101
6 = 110
7 = 111
, а теперь представьте что это 3 бита выставлдяются на 2 битной шине, что будет, откинеться старший бит и что убдет?
100 = 00
101 = 01
110 = 10
111 = 11
понято что стало?
0 1 2 3

когда у вас что-то за пределами РАМ для ниос, это что-то ограничено разрядностью шины адреса, и запись туда, это запись в младшие адреса.


Нельзя так делать, нельзя писать туда, куда надеетесь программа не дотянется! Для этого есть линкеры, можно выделить область памяти, регион, запретить линкеру туда лезть, и использовать для своих нужд, зная что там точно не будет программы, но только так! никак иначе...

Можно взять большой массив выделить 1000 элементов, и по указателю обращаться в него как в память, и знать что это не загадиться, а так как вы решили эту проблемму - это ПИПЕЦ!!!!

Спасибо за красочное описание... меня не хватило на это в 6 сообщении...
RLC
То что Линкером я оградил память это ежу понятно. Это память недоступна для создания кучи, стёка, в нём не лежит исполняемый код в том числе =)
То что я вам говорил что память у меня до 0x80 a000 на самом деле её больше, её 64K, но остальные выделены в другую область в bsp в неё я и пишу. Писать необходимо именно по заранее известным адресам. Это исхоное требование. То есть вот с 0x80 a000 до 0x80 ffff можно а в другие нельзя. Вы меня не поняли или я выразился коряво.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.