2011-06-27 03:34 AM
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..2011-06-27 05:28 AM
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???2011-06-27 05:57 AM
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;2011-06-27 09:40 AM
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.2011-06-27 11:25 AM
@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....2011-06-27 05:43 PM
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 = 0x0800F3FFBANK1_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.
2011-06-27 10:30 PM
@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...2011-06-27 10:32 PM
@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.2011-06-27 11:14 PM
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?
2011-06-28 04:13 AM
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?