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 mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list