[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] Accessing function and strings in flash in the ATMega 644
From: |
Robert von Knobloch |
Subject: |
[avr-gcc-list] Accessing function and strings in flash in the ATMega 644 |
Date: |
Mon, 02 Feb 2009 16:48:45 +0100 |
User-agent: |
Thunderbird 1.5.0.14 (X11/20060911) |
Firstly, sorry that this post is a bit long, but I need to explain what
is happening.
I am trying to access the flash memory in an ATMega 644 chip that I am
using as the basis for a piece of test equipment.
This tester will be used to program and test small devices with a
ATTiny13 and so contains an array of 10 flash images for the target
devices (Each one 0x900 bytes) and an array of 10 test routines
(functions) also 0x900 bytes each. These elements are located in the
ATMega644's flash by means of SECTION directives. The purpose here is
that flash images and/or test routines can be written and tested here
and sent to the production location as an intel-hex file which the
tester can download using minicom or teraterm via an inbuilt ihex
downloader. This won't happen very often so flash life is not an issue.
Reading of the flash images is achieved by defining:
FLASHIMAGE_SECTION uint8_t flashimage[] = {}; // Base of flash images
- and indexing flashimage[i]. GCC will not let me dimension this, but,
fortunately does not check bounds, so I abuse the system and let i point
to whatever.
All works fine, EXCEPT that my attempts to access the test routines
generate unexpected code:
//******************************************************************************
if (pgm_read_byte((PGM_P)(TESTIMAGE + (IMAGE_SIZE * projnum) +
SIGNATURE) != 0))
49c: 80 91 38 03 lds r24, 0x0338
4a0: 90 e0 ldi r25, 0x00 ; 0
4a2: 8c 9f mul r24, r28
4a4: 90 01 movw r18, r0
4a6: 8d 9f mul r24, r29
4a8: 30 0d add r19, r0
4aa: 9c 9f mul r25, r28
4ac: 30 0d add r19, r0
4ae: 11 24 eor r1, r1
4b0: e0 e0 ldi r30, 0x00 ; 0
4b2: f0 e0 ldi r31, 0x00 ; 0
4b4: 81 ed ldi r24, 0xD1 ; 209
4b6: 2c 37 cpi r18, 0x7C ; 124
4b8: 38 07 cpc r19, r24
4ba: 11 f0 breq .+4 ; 0x4c0 <main+0x14a>
4bc: e1 e0 ldi r30, 0x01 ; 1
4be: f0 e0 ldi r31, 0x00 ; 0
4c0: 84 91 lpm r24, Z
4c2: 88 23 and r24, r24
4c4: 29 f0 breq .+10 ; 0x4d0 <main+0x15a>
//******************************************************************************
Which, as far as I can see loads the Z-Pointer with either 0x0000 or
0x0001 before the lpm.
I rather expected Z to point to (assuming projnum = 0):
TESTIMAGE + NAME = (0x2300 + 0x88c = 0x2b8c) // The string
describing the test routine.
Can anyone tell me a: why this does not work and/or what I am assuming
that is wrong?
Best regards,
Robert von Knobloch
Here are snippets of my code:
//******************************************************************************
// Image definitions in Flash Memory
#define NUM_IMAGES 10
#define IMAGE_SIZE 0x900
// Offsets in the image
// Warning 'FUSES' defined in ../avr/fuses.h, use another name
#define FLASHIMAGE 0
#define FLASHIMAGE_SIZE 0x800 // Size of flash in host
#define EEPROMIMAGE FLASHIMAGE + FLASHIMAGE_SIZE
#define EEPROM_SIZE 0x80 // Size of EE in host
#define TARGETF_LENGTH EEPROMIMAGE + EEPROM_SIZE // Flash used
in target
#define TARGFLEN_SIZE 2 // 16-Bit quantity
#define TARGETEE_LENGTH TARGETF_LENGTH + TARGFLEN_SIZE
#define TARGEE_SIZE 2 // 16-Bit quantity
#define SIGNATURE TARGETEE_LENGTH + TARGEE_SIZE
#define SIG_SIZE 3
#define UUTFUSES SIGNATURE + SIG_SIZE
#define UUTFUSE_SIZE 2
#define NUM_PAGES UUTFUSES + UUTFUSE_SIZE
#define NUMPAGE_SIZE 1 // 8-Bit quantity
#define PAGE_WORDS NUM_PAGES + NUMPAGE_SIZE
#define PAGEWORDS_SIZE 1 // 8-Bit quantity
#define TESTER_SLOT PAGE_WORDS + PAGEWORDS_SIZE
#define TESTSLOT_SIZE 1 // 8-Bit quantity
#define TEST_ROUTINE TESTER_SLOT + TESTSLOT_SIZE
#define TESTROUT_SIZE 1 // 8-Bit quantity
#define NAME TEST_ROUTINE + TESTROUT_SIZE
#define NAME_SIZE LCDLINELENGTH
#define TESTIMAGE 0x2600 // Base address of test images
#define TEST0_SECTION __attribute__((section (".test0")))
#define TEST1_SECTION __attribute__((section (".test1")))
#define TESTPARMS0_SECTION __attribute__((section (".testparms0")))
#define TESTPARMS1_SECTION __attribute__((section (".testparms1")))
// Global variables
uint16_t (*test[])(void) = {test0,test1};
/*
******************************************************************************
* Tester routine 0
******************************************************************************
*/
TEST0_SECTION uint16_t test0(void)
{
int x;
DDRA = 0xff;
for (x = 0; x < 1000; ++x)
{
PORTA = x;
milliSecDelay(10);
}
return NO_ERROR;
}
TESTPARMS0_SECTION uint16_t flash0 = 1024; // Bytes
TESTPARMS0_SECTION uint16_t eep0 = 64; // Bytes
TESTPARMS0_SECTION uint8_t sig0[] = {0x00, 0x00, 0x00}; // Test file
TESTPARMS0_SECTION uint8_t fuse0[] = {0xfb, 0x33}; // Big-Endian
TESTPARMS0_SECTION uint8_t np0 = 32; // Flash
TESTPARMS0_SECTION uint8_t ps0 = 16; // In 16-bit words
TESTPARMS0_SECTION uint8_t ts0 = 0; // Slot in NKP
tester[0-9]
TESTPARMS0_SECTION uint8_t tr0 = 0; // Routine in
tester[0-9]
TESTPARMS0_SECTION char pn0[] = "ES07 Test 0 "; // Pad
to exactly 16 chars
/*
******************************************************************************
* Send program-merory resident string LCD.
******************************************************************************
*/
BOOTLOADER_SECTION void prog_lcd_string1(PGM_P string)
{
char temp;
while ((temp = pgm_read_byte(string++)) != 0)
{
lcd_putchar(temp);
}
}
//
******************************************************************************
in main:
// projnum is a uint8_t with values from 0-9
if (pgm_read_byte((PGM_P)(TESTIMAGE + (IMAGE_SIZE * projnum) +
SIGNATURE) != 0)) //Read 1 byte from Flash
{
lcd_string2("No test loaded!");
goto error;
}
prog_lcd_string1((PGM_P)(TESTIMAGE + (projnum * IMAGE_SIZE) + NAME)); //
Display string from Flash
if ((errorcode = test[projnum]()) != NO_ERROR) // Run test
routine from flash
{
lcd_errorout2(errorcode);
goto error;
}
error: // Do something else
//
******************************************************************************
In the Makefile:
LDFLAGS = -Wl,-Map,$(PRG).map \
-Wl,--section-start=.test0=0x2600 \
-Wl,--section-start=.testparms0=0x2e80 \
-Wl,--section-start=.test1=0x2f00 \
-Wl,--section-start=.testparms1=0x3780 \
-Wl,--section-start=.flashimage=0x8000 \
-Wl,--section-start=.bootloader=0xe000
- [avr-gcc-list] Accessing function and strings in flash in the ATMega 644,
Robert von Knobloch <=