011119xx 0 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба Работаю в Keil 4. Пытаюсь инициализировать FAT следующей функцией: void MountDrive(void) { uint32_t TotSectors; uint32_t DataSectors; uint32_t FirstSector; struct partrecord *pr; struct bpb710 *bpb; int i; SectorBuffer = (uint32_t*) malloc(512); if (SectorBuffer == NULL) { return; } readsector(0, (uint8_t *)SectorBuffer); то что ниже не привожу, так как проблема возникает выше } SectorBuffer объявлено выше как: uint32_t *SectorBuffer; При этом при попытке прочитать сектор программа уходит в HardFault_Handler в файле stm32f10x_it.c и там зависает. Если поменять код на такой: void MountDrive(void) { uint32_t TotSectors; uint32_t DataSectors; uint32_t FirstSector; struct partrecord *pr; struct bpb710 *bpb; int i; uint8_t buffer[512]; SectorBuffer = (uint32_t *)buffer; if (SectorBuffer == NULL) { return; } readsector(0, (uint8_t *)SectorBuffer); } то сектор читается и перехода в HardFault_Handler не происходит. Вопрос: почему не работает первый вариант кода? Что там не так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба Могу ошибиться. Рассматривайте это как вариант поиска бага. После получения значения, но перед использованием, Вы посмотреть значение SectorBuffer можете? Куда он указывает? Единственное, что приходит в голову, что malloc возвращает не выровненный на границу слова указатель. А когда происходит обращение к памяти по этому указателю, возникает исключительная ситуация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
011119xx 0 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба SectorBuffer указывает на область ОЗУ по адресу 0x20000320. Иногда бывает другой адрес, но всегда четный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба ...но всегда четный. А кратный 4? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
011119xx 0 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба Да. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба А куча и стек имеют достаточный размер? Вообще причины могут быть разные, смотря что там внутри readsector. Вот что что, а выравнивание буфера для чтения сектора никак не должно быть обязательным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
011119xx 0 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба А куча и стек имеют достаточный размер? Вот этого я не знаю. static uint8_t readsector(uint32_t lba, uint8_t *buffer) { if(lba == sector_in_buffer) return 0; sector_in_buffer = lba; return sd_readsector(lba, buffer); } int8_t sd_readsector(uint32_t lba, uint8_t *buffer) { uint16_t i; GPIO_ResetBits(SD_CS_PORT, PIN_CS_SD); if(sdhc_card) sd_command(SD_READ_SINGLE_BLOCK, lba); else sd_command(SD_READ_SINGLE_BLOCK, lba << 9); if(sd_get_response() != 0) { sd_send_dummys(); GPIO_SetBits(SD_CS_PORT, PIN_CS_SD); return SD_ERROR; } if(sd_get_datatoken() != SD_STARTBLOCK_READ) { sd_send_dummys(); GPIO_SetBits(SD_CS_PORT, PIN_CS_SD); return SD_ERROR; } for(i = 0; i < 512; i++) *buffer++ = SPI_byte(0xff); SPI_byte(0xff); SPI_byte(0xff); sd_send_dummys(); GPIO_SetBits(SD_CS_PORT, PIN_CS_SD); return SD_OK; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба Вот этого я не знаю. Ну как же, ты пользуешься выделением памяти из кучи (malloc), и не знаешь, как она инициализирована? Для задания размеров стека и кучи в кейле можно воспользоваться табом Configuration Wizard под окошком текстового редактора. Или же просто открыть стартап файл STM32F10x.s и в нём указать необходимые значения в строчках: Stack_Size EQU ... Heap_Size EQU ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 21 февраля, 2011 Опубликовано 21 февраля, 2011 · Жалоба А stdlib.h включен в исходный файл? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
011119xx 0 22 февраля, 2011 Опубликовано 22 февраля, 2011 (изменено) · Жалоба Да. Дело было в стеке. У меня стоял размер 512 байт. Увеличил до 1024 и проблема исчезла. Спасибо за помощь. Но остался вопрос: какого же размера все-таки делать стек? А куча для чего нужна? У меня под нее сейчас 0 выделено. Изменено 22 февраля, 2011 пользователем 011119xx Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 1 22 февраля, 2011 Опубликовано 22 февраля, 2011 · Жалоба Да. Дело было в стеке. У меня стоял размер 512 байт. Увеличил до 1024 и проблема исчезла. Спасибо за помощь. Но остался вопрос: какого же размера все-таки делать стек? А куча для чего нужна? У меня под нее сейчас 0 выделено. Я обычно задаю под стек 4 килобайта. Это не повредит, особенно, если работаешь с файлами или с форматированным выводом (printf и т.д.). Потом уже можно уменьшить, если хватает с избытком. Куча - это память для динамического выделения функциями malloc() и т.п. Если в твоей программе это есть - будь любезен задать размер кучи. Я стараюсь избегать, по возможности, работы с кучей и пользуюсь вместо этого статическими блоками памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 22 февраля, 2011 Опубликовано 22 февраля, 2011 · Жалоба Да. Дело было в стеке. ... А куча для чего нужна? У меня под нее сейчас 0 выделено. А сейчас у меня вопрос. Если в куче не осталось свободного пространства или она изначально равна нулю, то почему malloc() возвращает валидный указатеь, т.е. не NULL? Вот жеж: SectorBuffer = (uint32_t*) malloc(512); if (SectorBuffer == NULL) ... для чего это делается? Или я чего-то не догоняю :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
011119xx 0 22 февраля, 2011 Опубликовано 22 февраля, 2011 · Жалоба А может память выделяется не из кучи, а из стека? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zhevak 0 22 февраля, 2011 Опубликовано 22 февраля, 2011 · Жалоба А может память выделяется не из кучи, а из стека? А разве такое возможно для malloc()? Это же нонсэнс! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 22 февраля, 2011 Опубликовано 22 февраля, 2011 · Жалоба А разве такое возможно для malloc()? Это же нонсэнс! Скорее всего, для инициализации того, что выделено из кучи, используется стек. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться