реклама на сайте
подробности

 
 
> STM32F103RET6 уходит в HardFault_Handler
011119xx
сообщение Feb 21 2011, 05:18
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Работаю в 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 не происходит. Вопрос: почему не работает первый вариант кода? Что там не так?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 14)
zhevak
сообщение Feb 21 2011, 06:08
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



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

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

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


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
011119xx
сообщение Feb 21 2011, 06:25
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



SectorBuffer указывает на область ОЗУ по адресу 0x20000320. Иногда бывает другой адрес, но всегда четный.
Go to the top of the page
 
+Quote Post
Dron_Gus
сообщение Feb 21 2011, 08:30
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 202
Регистрация: 9-01-05
Из: Санкт-Петербург
Пользователь №: 1 861



Цитата(011119xx @ Feb 21 2011, 09:25) *
...но всегда четный.

А кратный 4?


--------------------
Если сверху смотреть, то сбоку кажется, что снизу ничего не видно.
Go to the top of the page
 
+Quote Post
011119xx
сообщение Feb 21 2011, 09:15
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Да.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 21 2011, 09:54
Сообщение #6


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



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

Вообще причины могут быть разные, смотря что там внутри readsector.
Вот что что, а выравнивание буфера для чтения сектора никак не должно быть обязательным.
Go to the top of the page
 
+Quote Post
011119xx
сообщение Feb 21 2011, 10:08
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



Цитата(sonycman @ Feb 21 2011, 14:54) *
А куча и стек имеют достаточный размер?


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

Код
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;                                                 
}
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 21 2011, 16:22
Сообщение #8


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(011119xx @ Feb 21 2011, 13:08) *
Вот этого я не знаю.

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

Для задания размеров стека и кучи в кейле можно воспользоваться табом Configuration Wizard под окошком текстового редактора.
Или же просто открыть стартап файл STM32F10x.s и в нём указать необходимые значения в строчках:
Stack_Size EQU ...
Heap_Size EQU ...
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 21 2011, 18:08
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



А stdlib.h включен в исходный файл?

Go to the top of the page
 
+Quote Post
011119xx
сообщение Feb 22 2011, 03:42
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



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

Сообщение отредактировал 011119xx - Feb 22 2011, 06:36
Go to the top of the page
 
+Quote Post
sonycman
сообщение Feb 22 2011, 06:59
Сообщение #11


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(011119xx @ Feb 22 2011, 06:42) *
Да. Дело было в стеке. У меня стоял размер 512 байт. Увеличил до 1024 и проблема исчезла. Спасибо за помощь. Но остался вопрос: какого же размера все-таки делать стек? А куча для чего нужна? У меня под нее сейчас 0 выделено.

Я обычно задаю под стек 4 килобайта.
Это не повредит, особенно, если работаешь с файлами или с форматированным выводом (printf и т.д.).
Потом уже можно уменьшить, если хватает с избытком.

Куча - это память для динамического выделения функциями malloc() и т.п.
Если в твоей программе это есть - будь любезен задать размер кучи.
Я стараюсь избегать, по возможности, работы с кучей и пользуюсь вместо этого статическими блоками памяти.
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 22 2011, 07:27
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(011119xx @ Feb 22 2011, 08:42) *
Да. Дело было в стеке. ... А куча для чего нужна? У меня под нее сейчас 0 выделено.

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

Вот жеж:
Код
    SectorBuffer = (uint32_t*) malloc(512);

    if (SectorBuffer == NULL)
...

для чего это делается?
Или я чего-то не догоняю sad.gif


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
011119xx
сообщение Feb 22 2011, 08:24
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 5-07-05
Из: Уфа
Пользователь №: 6 544



А может память выделяется не из кучи, а из стека?
Go to the top of the page
 
+Quote Post
zhevak
сообщение Feb 22 2011, 08:44
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(011119xx @ Feb 22 2011, 13:24) *
А может память выделяется не из кучи, а из стека?

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


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
ViKo
сообщение Feb 22 2011, 09:02
Сообщение #15


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(zhevak @ Feb 22 2011, 10:44) *
А разве такое возможно для malloc()? Это же нонсэнс!

Скорее всего, для инициализации того, что выделено из кучи, используется стек.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 12:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01517 секунд с 7
ELECTRONIX ©2004-2016