cancel
Showing results for 
Search instead for 
Did you mean: 

Hard Fault Error - STM32F100C8

ezyreach
Associate II
Posted on June 27, 2011 at 12:34

I am trying to implement EEPROM emulation in the flash memory. I am able to write and read the data from flash. When trying to write the second data it is going to HARDFAULT Error. I m not sure why this happens.

Below is the code....

void Write_Data(uint32_t Address,uint16_t *Data,uint16_t Len)

{

    uint8_t Temp_RdLen=0;

    uint16_t i=0;

    uint16_t RdLen=0;

       

    FLASH_UnlockBank1();

    Flash Bank1 Program Erase controller */

    NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR)   

                                 /FLASH_PAGE_SIZE;  

    FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR |

                                          FLASH_FLAG_WRPRTERR);

        for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus ==

                                                      FLASH_COMPLETE); EraseCounter++)

        {

          FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR +

                                                               (FLASH_PAGE_SIZE * EraseCounter));

        } 

       

    while(Address < BANK1_WRITE_END_ADDR&& MemoryProgramStatus !=

                                                                                                         FAILED)

    {

        RdLen = (*(__IO uint32_t*)Address);

        Temp_RdLen=(uint8_t)(RdLen>>8);

        break;

    }

   

    if(Temp_RdLen == 0xFF)

    {

        while((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus ==

                                                               FLASH_COMPLETE))

        {

            FLASHStatus = FLASH_ProgramHalfWord(Address, Len);

            Address+=2;

            break;

        }

       

        while((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus ==

                            FLASH_COMPLETE)&& i<Len)           

        {

            FLASHStatus = FLASH_ProgramHalfWord(Address, *Data);

            Address+=2;

            Data+=1;

            if(Len-i>=2)

                i+=2;

            else if(Len-i==1)

                i+=1;

            else if(Len-i==0)

                break;                       

        }

    }

    else

    {

    }

    FLASH_LockBank1();

}

1. Before writing the data i m checking whether the data in the address 0x0800F000 is 0xFF. If so then i proceed to next step.

2. At this address - 0x0800F000 the string length is written and from 0x0800F002 the original data is written.

3. I m able to read back the data from this address also.

4. Next i m checking that whether  the data in the address 0x0800F025  is 0xFF.

5. If yes, then i m trying to write the next string length.

6. But at this point, the control goes to HARDFAULT_ERROR.

I m not sure where is the original trouble is..

11 REPLIES 11
rosarium
Associate II
Posted on June 27, 2011 at 14:28

Can you try once making the data type of Temp_RdLen as uint16_t.

And can you check the data type for NbrOfPage. Is there any overflow???

ezyreach
Associate II
Posted on June 27, 2011 at 14:57

The original data is read and kept in RdLen which is declared as uint16_t....

Temp_RdLen is used for just manipulation.

NbrOfPage is declared as uint32_t...

No overflow is there due to the below deeclarations....

BANK1_WRITE_END_ADDR = 0x0800F3FFF

BANK1_WRITE_START_ADDR = 0x0800F000

FLASH_PAGE_SIZE = 0x400

NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;

Posted on June 27, 2011 at 18:40

The STM32F100C8 only has 64KB of FLASH so

BANK1_WRITE_END_ADDR = 0x0800F3FFF

Is going to cause problems, isn't it?

Perhaps you want

BANK1_WRITE_END_ADDR = 0x08010000

Otherwise your page count will be wrong. With 0x0800FFFF you'd be missing the erase of the last block. With 0x0800F3FFF you're way beyond the capacity of the part.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ezyreach
Associate II
Posted on June 27, 2011 at 20:25

@clive1

Its my typing error....

The bank1 end address is defined as,

#define BANK1_WRITE_END_ADDR    ((uint32_t)0x0800F3FF)

With this macro defined and the code posted earlier, i got the hard fault error....

Posted on June 28, 2011 at 02:43

So what instruction is faulting? It will fault if you touch memory beyond your control. Implement a Hard Fault handler like Joseph Yiu's. It's been discussed a couple of times in the last week.

BANK1_WRITE_END_ADDR = 0x0800F3FF

 

BANK1_WRITE_START_ADDR = 0x0800F000

 

FLASH_PAGE_SIZE = 0x400

 

 

NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;

 

 

NbrOfPage = ZERO, will that cause a problem?

Add some diagnostic output to your code, so you can pin down the failure.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ezyreach
Associate II
Posted on June 28, 2011 at 07:30

@Clive1

For the first time after the MCU is erased and programmed, doesnt require again to erase the flash of a particular bank to start writing of the datas.

If i disable the flash erase in the earlier stated code, i dnt think the NbrOfPage=0 will cause a problem.

If writing a data on the location where already some data is written, then a flash erase followed by new write is required, for which i do agree.

In my case, i m not testing that scenario right now and hence trying to write the data at different locations at different instances and not writing total 1KB of data at one instance...

ezyreach
Associate II
Posted on June 28, 2011 at 07:32

@clive1

Moreover, in my application i use 3 USARTS for various purposes.

In that case, using of Printf is not quite clear to which USART the output will be pushed too..

And when 3 USARTS are being used for different purpose where 1 USART being used to connected to PC for debugging, upon using printf the MCU doesnt not work after that statement...

Please help me to clarify if i m wrong here.

Posted on June 28, 2011 at 08:14

In Keil you can re-target printf() to any serial port by replacing the low-level character IO routines.

4. Next i m checking that whether  the data in the address 0x0800F025  is 0xFF.

 

 

5. If yes, then i m trying to write the next string length.

 

 

6. But at this point, the control goes to HARDFAULT_ERROR.

 

You're not trying to write 16-bit values to ODD addresses (0x0800F025) are you?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ezyreach
Associate II
Posted on June 28, 2011 at 13:13

I m using IAR....hence not sure how to retarget the printf for the corresponding USART....

Yes the second string, i m starting to write from the address 0x0800F025.

 

 

Is the writing of data starting from odd address is not possible?

 

 

If so why?