RLC 0 15 января, 2015 Опубликовано 15 января, 2015 (изменено) · Жалоба Использую NIOS II econom. При отладке в дебагере замечаю что сохранения данных регистров(r2,r3,ra...) просходит по адресам в памяти которые не выделял. Язык программирования "С". То есть происходит вход в функцию и выпоняетя команда сохранения адреса возврата(stw ra,24(sp)). А SP равен 0xee4bf4c8. При этом адресное пространство RAM у меня 0x800020-0x80A000. При этом в одной и той же функции иногда сохранение происходит(адреса в котором сохраняется и не сохраняется состояние регистров разное, 0xee4bf4c8 и 0xee4c4888 ) а иногда не происходит. и при выходе из функции регитр ra(возврата из функции) равен 0, что при выполнении ret вызывает перезагрузку процесора. Вопроса 3: что за адреса?(предполагаю что кэш процессора) Почему не всегда происходит сохранение? Что с этим делать?=) Изменено 15 января, 2015 пользователем RLC Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RLC 0 15 января, 2015 Опубликовано 15 января, 2015 · Жалоба решил проблему. дело было в том что я создавал массив размера в зависимости от входных данных и иногда массив становился непомерно большим и в регистре SP появлялись сумашедшие адреса. После фильтрации размера массива всё стало рабочим. Странно одно: инога то в эти сумашедшие адреса не относящиеся к моему RAM всё таки запись был успешна! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex77 4 15 января, 2015 Опубликовано 15 января, 2015 · Жалоба решил проблему. дело было в том что я создавал массив размера в зависимости от входных данных и иногда массив становился непомерно большим и в регистре SP появлялись сумашедшие адреса. После фильтрации размера массива всё стало рабочим. Странно одно: инога то в эти сумашедшие адреса не относящиеся к моему RAM всё таки запись был успешна! Как говорится "ежу понятно" (с) ;) Происходил "заворот адресов" на реальный диапазон адресов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
WitFed 1 16 января, 2015 Опубликовано 16 января, 2015 · Жалоба У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая. И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения. А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно. Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RLC 0 16 января, 2015 Опубликовано 16 января, 2015 · Жалоба У Альтеры запись в "мусорные" недопустимые адреса обычно проходит, ничего не вешая. И чтение из них возвращает -1. Хотя лучше бы всё падало при самом первом глюке, без их наслоения. А в С нет понятия "массив переменной длины", автоматические переменные массивов в стеке нужно объявлять на максимально возможную константную длину данных, ну или из кучи выделять динамически, если это значение неизвестно. Очень похоже, что был "заступ" по записи за массив, а в стеке выше локальных переменных и входных параметров вообще много чего интересного сохраняется, в том числе и адреса возвратов из функций, сами значения SP после возврата -- лучше их не трогать, ибо при выходе из функции и восстановлении системных регистров может случиться, что угодно. Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати. У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер. И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex77 4 16 января, 2015 Опубликовано 16 января, 2015 · Жалоба Ну вот я в отладчике в оочию наблюдал что сохранение в ячейке с адресом 0x55CE FF34 проходит успешно(через Memory Map смотрел), а вот адреное пространств всего лишь от 0x80 0020-0x80 A000. И из этого сумашедшего адреса данные востанавливались успешно! Вот это мне и интересно. а собственно куда сохраняется? Ну а через несколько проходов с такими адресами "вдруг" переставало сохранятся туда. тоесть вроде как команда выполнена, а реально содержимое ячейки как было 0, так и осталось. И с неё содержимое читается как 0 кстати. У меня было так: вход в функцию и в ней объяляется этот массив. Функция универсальная и разумный объём массива будет только в одном из нескольких случаев(собственно он в этом случае и нужен был). В остальных случаях размерность массива больше может получиться чем объём физически доступной памяти(собственно от 0 до 2^32). Сейчас я в нужном случае вызываю ещё одну функцию в котором и создаётся используемый массив объёмом равным аргумента функции. Тоесть массив выделяется статически, но тогда когда известен размер. И вот сейчас я задумался что по факту я каждый раз я создаю, но очистки то не происходит! может мне тогда malloc'ом пользоватья и в конце free делать. Тут же сборки мусора не происходит. Или можно free использовать просто от ссылки на массив который статически выделен. Или функция завершается, ссылку на массив теряется (тк он локальный) и можно забыть про очистку... что то я совсем задумался Несколько бредово выглядит... "Штудент штоли ???" 1)Кусок С-ишника в студию про "У меня было так: вход в функцию и в ней объяляется этот массив." 2)0x55CE FF34 гдето в 0x80 0020-0x80 A000 и "сохраняется" Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 января, 2015 Опубликовано 16 января, 2015 · Жалоба Да чувствуется некое непонимание%) я каждый раз я создаю, но очистки то не происходит! и сразу решение может мне тогда malloc'ом пользоватья и в конце free делать Опускаем вопросы создания массивов, того что такое стэк и куча. Сосредоточимся на решении проблемы "каждый раз создаю, но очистки то не происходит", почему это вас ведет не к решению сделать массив 1 раз и использовать его чтобы стэк не тилипать, а к наоборот более сложному изнасилованию кучи через доп функции:)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RLC 0 20 января, 2015 Опубликовано 20 января, 2015 · Жалоба 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 0 20 января, 2015 Опубликовано 20 января, 2015 · Жалоба MMU - MPU на вас нету. сохраняются данные туда же куда и при int[10] Data; Data[11] = 10; то есть в память с адресом &Data[0] + 11*4, а что там лежит одному вам известно. Так можно спокойно загадить данные, другие переменные, даже если очень постараться можно код программы завалить. Дальше больше если выбрать ячейку вне пределов вашей памяти, она свернеться и попадет куда-то в адрес который у вас есть. Вообще это базовые понятия программирования, винды тут нет которая напишет приложение выполнила недопустимую ошибку и будет закрыто, или как она там писала? Локальные массивы выделяются на стеке, стек кончиться начнут гадить оперативку. Глобальные массивы выделены сразу в оперативке, менять их размеры на лету не выйдет. Массивы динамические создаются на куче, со всеми делами по организации, дефрагментации и прочей байде с кучей. Потому вместо одноразового массива выделяемого на стеке придумать одноразовый массив в куче - это мучение кучи, созданием и удалением массивов, ее фрагментации и так далее... хорошим тоном в вашем случае является проверка data на допустимые значения а вторым хорошим тоном является создавать массив всегда одной величины с запасиком, и проверкой влезет ли дата в него или нет. А то так далеко можно уйти, в непредсказуемые дали... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RLC 0 22 января, 2015 Опубликовано 22 января, 2015 · Жалоба Golikov A., спасибо за объяснение. Когда я пишу по конкретным адресам, то конкретные адреса в ходят в разряд памяти не являющейся RAM для NIOS. Тоесть это память в которую я пишу и заю что она незаорется программой. от такая особенность. ну вот странно у меня адресов таких больших нет в Qsys проекте. вот максимальные как раз 0x80 a000. Вся переферия меньшие адреса имеет. Всем спасибо за внимание :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 22 января, 2015 Опубликовано 22 января, 2015 · Жалоба ПИПЕЦ!!!!! просото пипец!!! вы что нибудь про шины адреса знаете? если у вас шина 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 4 22 января, 2015 Опубликовано 22 января, 2015 · Жалоба ПИПЕЦ!!!!! просото пипец!!! вы что нибудь про шины адреса знаете? если у вас шина 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 0 23 января, 2015 Опубликовано 23 января, 2015 · Жалоба То что Линкером я оградил память это ежу понятно. Это память недоступна для создания кучи, стёка, в нём не лежит исполняемый код в том числе =) То что я вам говорил что память у меня до 0x80 a000 на самом деле её больше, её 64K, но остальные выделены в другую область в bsp в неё я и пишу. Писать необходимо именно по заранее известным адресам. Это исхоное требование. То есть вот с 0x80 a000 до 0x80 ffff можно а в другие нельзя. Вы меня не поняли или я выразился коряво. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться