Перейти к содержанию
    

STM32F103RET6 уходит в HardFault_Handler

Работаю в 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 не происходит. Вопрос: почему не работает первый вариант кода? Что там не так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Могу ошибиться. Рассматривайте это как вариант поиска бага.

 

После получения значения, но перед использованием, Вы посмотреть значение SectorBuffer можете? Куда он указывает?

 

Единственное, что приходит в голову, что malloc возвращает не выровненный на границу слова указатель. А когда происходит обращение к памяти по этому указателю, возникает исключительная ситуация.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SectorBuffer указывает на область ОЗУ по адресу 0x20000320. Иногда бывает другой адрес, но всегда четный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А куча и стек имеют достаточный размер?

 

Вообще причины могут быть разные, смотря что там внутри readsector.

Вот что что, а выравнивание буфера для чтения сектора никак не должно быть обязательным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А куча и стек имеют достаточный размер?

 

Вот этого я не знаю.

 

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;                                                 
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот этого я не знаю.

Ну как же, ты пользуешься выделением памяти из кучи (malloc), и не знаешь, как она инициализирована?

 

Для задания размеров стека и кучи в кейле можно воспользоваться табом Configuration Wizard под окошком текстового редактора.

Или же просто открыть стартап файл STM32F10x.s и в нём указать необходимые значения в строчках:

Stack_Size EQU ...

Heap_Size EQU ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да. Дело было в стеке. У меня стоял размер 512 байт. Увеличил до 1024 и проблема исчезла. Спасибо за помощь. Но остался вопрос: какого же размера все-таки делать стек? А куча для чего нужна? У меня под нее сейчас 0 выделено.

Изменено пользователем 011119xx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да. Дело было в стеке. У меня стоял размер 512 байт. Увеличил до 1024 и проблема исчезла. Спасибо за помощь. Но остался вопрос: какого же размера все-таки делать стек? А куча для чего нужна? У меня под нее сейчас 0 выделено.

Я обычно задаю под стек 4 килобайта.

Это не повредит, особенно, если работаешь с файлами или с форматированным выводом (printf и т.д.).

Потом уже можно уменьшить, если хватает с избытком.

 

Куча - это память для динамического выделения функциями malloc() и т.п.

Если в твоей программе это есть - будь любезен задать размер кучи.

Я стараюсь избегать, по возможности, работы с кучей и пользуюсь вместо этого статическими блоками памяти.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да. Дело было в стеке. ... А куча для чего нужна? У меня под нее сейчас 0 выделено.

А сейчас у меня вопрос. Если в куче не осталось свободного пространства или она изначально равна нулю, то почему malloc() возвращает валидный указатеь, т.е. не NULL?

 

Вот жеж:

    SectorBuffer = (uint32_t*) malloc(512);

    if (SectorBuffer == NULL)
...

для чего это делается?

Или я чего-то не догоняю :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А может память выделяется не из кучи, а из стека?

А разве такое возможно для malloc()? Это же нонсэнс!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве такое возможно для malloc()? Это же нонсэнс!

Скорее всего, для инициализации того, что выделено из кучи, используется стек.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...