Hi,
I am using memcpy and it is not running and landing in HardFault_Handler.
I am trying to create a big font to display in TFT LCD. Below is my scenario. Can somebody what I am missing here?
1. I have font data declared as below
static const unsigned char SevenSegNumFont[10][200]={ . . };
2. Use below function to copy font data from flash to memory
void Get7SegmentXLCode(unsigned char* pBuffer,unsigned char ASCII) { memcpy(pBuffer,SevenSegNumXLFont[ASCII] ,800); }
3. Function in #2 above is called from below function
void Put7SegmentXL( uint16_t Xpos, uint16_t Ypos, uint8_t ASCI, uint16_t charColor, uint16_t bkColor ) { uint16_t i=0, j=0,k=0,l=0; unsigned char buffer[800], tmp_char; Get7SegmentXLCode(buffer,ASCI); for (l=0;l<100;l++) { for( i=0; i<8; i++ ) { tmp_char = buffer[k]; for( j=0; j<8; j++ ) { if( (tmp_char >> 7 - j) & 0x01 == 0x01 ) { LCD_SetPoint( Xpos + (i*8+j), Ypos + l, charColor ); } else { LCD_SetPoint( Xpos + (i*8+j), Ypos + l, bkColor ); } } k++; } } }
4. When I run these code, it does not run and while debugging I found the memcpy is landing in error in the marked line <-------
0x00006722 EA400301 ORR r3,r0,r1 0x00006726 079B LSLS r3,r3,#30 0x00006728 D003 BEQ 0x00006732 0x0000672A E009 B 0x00006740 0x0000672C C908 LDM r1!,{r3} 0x0000672E 1F12 SUBS r2,r2,#4 <------------ 0x00006730 C008 STM r0!,{r3} 0x00006732 2A04 CMP r2,#0x04 0x00006734 D2FA BCS 0x0000672C 0x00006736 E003 B 0x00006740 0x00006738 F8113B01 LDRB r3,[r1],#0x01 0x0000673C F8003B01 STRB r3,[r0],#0x01 0x00006740 1E52 SUBS r2,r2,#1 0x00006742 D2F9 BCS 0x00006738 0x00006744 4770 BX lr
Processor is NXP LPC1768 I am using MDK-ARM 4.23
Regards, M Mohan
Because your code doesn't make much sense, there's insufficient context, and your quite likely violating the bounds of the array, and that SevenSegNumXLFont[ASCII] probably doesn't provide the array address you're looking for.
What's the range of ASCII? 0..9? Are you trying to display a string? How's the function called? What's the expected behaviour?
If ASCII is a character between '0' and '9', then you need to take (ASCII-'0') as index into the array.
But why do you play around with all hard-coded sizes? Don't you believe in using
#define CHAR_HEIGHT 100 #define CHAR_XBYTES 8 #define CHAR_SIZE (CHAR_HEIGHT*CHAR_XBYTES)
or
enum { CharHeight = 100, CharXBytes = 8, CharSize = CharHeight*CharXBytes, };
It really isn't good to make use of magic values - and how will you ever be able to find all places where you use a magic value, in case you need to change from 800 to something else?
And is there a reason why you avoid sizeof(xxx)?
And why play with so nice variable names l, i, j, k? Wouldn't x and y or row, col be better names?
And why do you copy 800 bytes for every character you are going to write - isn't it enough to get a pointer to the bitmap instead of the extra 800 byte large buffer[]?
void Put7SegmentXL( uint16_t Xpos, uint16_t Ypos, uint8_t ASCI, uint16_t charColor, uint16_t bkColor ) { uint16_t dx=0, dy=0, xbytes=0; unsigned char tmp_char; unsigned *charmap = Get7SegmentXLCode(ASCII); for (dy=0; dy<CHAR_HEGIHT; ++dy) { for (xbytes=dx=0; xbytes<CHAR_XBYTES; xbytes++) { tmp_char = *charmap++; for (bit=0; bit<8; ++bit) { LCD_SetPoint( Xpos + dx++, Ypos + dy, (tmp_char & (0x1<<bit)) ? charColor : bkColor); } } } }