Pointers and structures

Hello everyone.

Maybe you can help, I really do not see why this is happening.

I am working with fonts on small Arduino (AT32U4).

Storing the fonts into flash and using them is imperative, but I have issues using the data structures provided with fonts.

The fonts are build-up the following way, in the .h file:

 typedef struct {
     const uint8_t *dataX;
     uint16_t width;
     uint16_t height;
     uint8_t dataSize;
     } tImage;
 typedef struct {
     long int code;
     const tImage *image;
     } tChar;
 typedef struct {
     int length;
     const tChar *chars;
     } tFont;

extern const tFont Font;

The .c file contains the fonts:


//font bitmap

static const uint8_t image_data_Font_0x2d[264] PROGMEM = {
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
    0xff, 0xff, 0xff, 0xe0, 
.
.
.
.

};


//font data + font metrics as size, width etc.

static const tImage Font_0x2e[] PROGMEM = { image_data_Font_0x2e,
    22, 66, 8};


//array of font data + font metrics

const tChar Font_array[] = {

#if (0x0 == 0x0)
  // character: '+'
  {0x2b, &Font_0x2b},
#else
  // character: '+' == ''
  {0x2b, &Font_0x},
#endif

//finally the font is constructed
PROGMEM const tFont Font = { 13, Font_array };


The issue occurs when I try to access members in Font.

void write_index(uint16_t code, uint16_t index){

  byte temp = (byte)code;

  Serial.print("\r\nANSI: ");
  Serial.write(temp);

  Serial.print(", CODE: 0x");
  Serial.print(code, HEX);

  Serial.print("\r\nLENGTH: ");
  Serial.print(Font.length);

  Serial.print("\r\nDecoded CODE: 0x");
  Serial.print(Font.chars[index].code, HEX);
  Serial.print("\r\nWidth: ");
  Serial.print(Font.chars[index].image->width);
  Serial.print("\r\nheight: ");
  Serial.print(Font.chars[index].image->height);
  Serial.print("\r\nDATA: 0x");
  Serial.print(Font.chars[index].image->dataX[0], HEX);
  Serial.print(Font.chars[index].image->dataX[1], HEX);
  Serial.print(Font.chars[index].image->dataX[2], HEX);
  
}
ANSI: -, CODE: 0x2D (control)
LENGTH: 13 (correct)
Decoded CODE: 0x2D (correct)
Width: 4883 (WRONG!)
height: 4883 (WRONG!)
DATA: 0x131313 (WRONG!)

It looks like, that when I access parameters from "image" structure, the data is wrong. Why is that?

You have to use special instructions to read from PROGMEM.

Thanks for that!

Looking at the examples I really am not sure how this will be done in my case, since I read entire structures with different data types.

The only reason this is correct is that the answer is a constant that the compiler knows. The (incorrect) fetch from RAM is optimized away. You should explicitly fetch the length from PROGMEM or some day you will make a change somewhere and the compiler will decide not to optimize the fetch away.

You did not in the code you posted, all accesses are to basic types.

There is no need to read full structures anyway,
all of them, and their members, can be addresses directly.

I will read the documentation, if I do not figure this out I will come back.

Thanks everyone.

Hello again.

I can't figure this one out.

I am checking address and value for fonts and it does not add-up.

This is the function used to display address and values at those address:

void write_index(uint16_t code, uint16_t index){
  byte temp = (byte)code;
  //String s = temp.toString();
  Serial.print("\r\nANSI: ");
  Serial.write(temp);
  Serial.print(", CODE: 0x");
  Serial.print(code, HEX);

  uint16_t var_addr = &Font.length;
  Serial.print("\r\nLENGTH ADDR: 0x");
  Serial.print(var_addr, HEX);

  var_addr = &Font.chars[index].code;
  Serial.print("\r\nGLYPH CODE ADDR: 0x");
  Serial.print(var_addr, HEX);

  var_addr = &Font.chars[index].image->width;
  Serial.print("\r\nGLYPH WIDTH ADDR: 0x");
  Serial.print(var_addr, HEX);

  var_addr = &Font.chars[index].image->height;
  Serial.print("\r\nGLYPH HEIGHT ADDR: 0x");
  Serial.print(var_addr, HEX);

  var_addr = pgm_read_word_near(&Font.length);
  Serial.print("\r\nFONT LENGTH VAL PGM: ");
  Serial.print(var_addr);

  var_addr = pgm_read_word_near(&(Font.chars[index].image->width));
  Serial.print("\r\nWidth VAL PGM: ");
  Serial.print(var_addr);

  var_addr = pgm_read_word_near(&(Font.chars[index].image->height));
  Serial.print("\r\nHeight VAL PGM: ");
  Serial.print(var_addr);

  Serial.print("\r\nGLYPH DATA ADDR: 0x");
  var_addr = &(Font.chars[index].image->dataX[0]);
  Serial.print(var_addr, HEX);
  
  Serial.print("\r\nDATA VAL PGM: 0x");
  var_addr = (uint16_t)pgm_read_byte_near(&(Font.chars[index].image->dataX[0]));
  Serial.print(var_addr, HEX);
  var_addr = pgm_read_byte_near(&(Font.chars[index].image->dataX[1]));
  Serial.print(var_addr, HEX);
  var_addr = pgm_read_byte_near(&(Font.chars[index].image->dataX[2]));
  Serial.print(var_addr, HEX);

  
}

Here is the address of objects, got it with obj-dump out of the .elf file.

SYMBOL TABLE:
00800100 l    d  .data  00000000 .data
00000000 l    d  .text  00000000 .text
0080036c l    d  .bss   00000000 .bss
00000000 l    d  .comment       00000000 .comment
00000000 l    d  .note.gnu.avr.deviceinfo       00000000 .note.gnu.avr.deviceinfo
00000000 l    d  .debug_aranges 00000000 .debug_aranges
00000000 l    d  .debug_info    00000000 .debug_info
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev
00000000 l    d  .debug_line    00000000 .debug_line
00000000 l    d  .debug_frame   00000000 .debug_frame
00000000 l    d  .debug_str     00000000 .debug_str
00000000 l    d  .debug_loc     00000000 .debug_loc
00000000 l    d  .debug_ranges  00000000 .debug_ranges
00000000 l    df *ABS*  00000000
0000003e l       *ABS*  00000000 __SP_H__
0000003d l       *ABS*  00000000 __SP_L__
0000003f l       *ABS*  00000000 __SREG__
00000000 l       *ABS*  00000000 __tmp_reg__
00000001 l       *ABS*  00000000 __zero_reg__
00001a38 l     F .text  00000054 _Z8USB_RecvhPvi.constprop.9
00800400 l     O .bss   00000001 _usbConfiguration
008003ff l     O .bss   00000001 RxLEDPulse
00001a8c l     F .text  00000022 _Z13USB_SendSpaceh.constprop.7
00001aae l     F .text  00000028 _Z12PluggableUSBv
008003f7 l     O .bss   00000008 _ZGVZ12PluggableUSBvE3obj
008003f3 l     O .bss   00000004 _ZZ12PluggableUSBvE3obj
00001ad6 l     F .text  0000005c _ZL11SendControlh
008003e9 l     O .bss   00000002 _ZL6_cmark
008003e7 l     O .bss   00000002 _ZL5_cend
00004f9c l     F .text  00000066 _ZL24USB_SendStringDescriptorPKhhh
00001b32 l     F .text  0000004c _Z15USB_SendControlhPKvi
00001b7e l     F .text  00000062 _ZL14SendInterfacesv
0000191d l     O .text  00000042 _cdcInterface
00001be0 l     F .text  0000001a _ZL4RecvPVhh
00001bfa l     F .text  0000005a _ZN5Print5writeEPKhj
00001c54 l     F .text  0000002c _ZN7Serial_5writeEh
00001c80 l     F .text  00000016 _ZN7Serial_5flushEv
00001c96 l     F .text  00000008 _ZN7Serial_17availableForWriteEv
00001c9e l     F .text  0000003c _ZN7Serial_4readEv
00001cda l     F .text  00000048 _ZN7Serial_4peekEv
00001d22 l     F .text  00000034 _ZN7Serial_9availableEv
00001d56 l     F .text  00000098 turnOffPWM
00001dee l     F .text  00000052 digitalRead
000018ff l     O .text  0000001e digital_pin_to_timer_PGM
000019c2 l     O .text  0000001f digital_pin_to_bit_mask_PGM
000019a3 l     O .text  0000001f digital_pin_to_port_PGM
00001995 l     O .text  0000000e port_to_input_PGM
00001e40 l     F .text  0000005c digitalWrite
000018f1 l     O .text  0000000e port_to_output_PGM
00001e9c l     F .text  00000062 pinMode
000018e3 l     O .text  0000000e port_to_mode_PGM
00001efe l     F .text  0000004a micros
008003e3 l     O .bss   00000004 timer0_overflow_count
00001f48 l     F .text  00000066 delay
00001fae l     F .text  0000010a _ZN7Serial_5writeEPKhj
00800104 l     O .data  00000008 _ZL12_usbLineInfo
008003ed l     O .bss   00000001 _usbSuspendState
008003ec l     O .bss   00000001 TxLEDPulse
000020b8 l     F .text  0000004e twi_transmit
00800394 l     O .bss   00000001 twi_txBufferLength
008003b8 l     O .bss   00000001 twi_state
00800374 l     O .bss   00000020 twi_txBuffer
00002106 l     F .text  00000002 _ZN12Adafruit_GFX10startWriteEv
00002106 l     F .text  00000002 _ZN12Adafruit_GFX8endWriteEv
00002106 l     F .text  00000002 _ZN7TwoWire5flushEv
00002108 l     F .text  00000006 _ZN7TwoWire4peekEv
0000210e l     F .text  00000006 _ZN7TwoWire4readEv
00002114 l     F .text  0000000e _ZN7TwoWire9availableEv
0080036d l     O .bss   00000001 _ZN7TwoWire13rxBufferIndexE
00002122 l     F .text  00000016 _ZN7TwoWire5writeEPKhj
00002138 l     F .text  00000022 _ZN7TwoWire5writeEh
0000215a l     F .text  00000002 _ZN12Adafruit_GFX13invertDisplayEb
0000215c l     F .text  0000002a _ZN12Adafruit_GFX11setRotationEh
00002186 l     F .text  0000044a _ZN12Adafruit_GFX8drawCharEiihjjhh
000013e3 l     O .text  00000500 _ZL4font
000025d0 l     F .text  000001a4 _ZN12Adafruit_GFX5writeEh
00002774 l     F .text  000000be _ZN12Adafruit_GFX8drawRectEiiiij
00002832 l     F .text  000000f0 _ZN12Adafruit_GFX8drawLineEiiiij
00002922 l     F .text  0000003a _ZN12Adafruit_GFX10fillScreenEj
0000295c l     F .text  0000008a _ZN12Adafruit_GFX8fillRectEiiiij
000029e6 l     F .text  00000072 _ZN12Adafruit_GFX13drawFastHLineEiiij
00002a58 l     F .text  00000072 _ZN12Adafruit_GFX13drawFastVLineEiiij
00002aca l     F .text  00000020 _ZN12Adafruit_GFX13writeFillRectEiiiij
00002aea l     F .text  00000018 _ZN12Adafruit_GFX14writeFastHLineEiiij
00002b02 l     F .text  00000018 _ZN12Adafruit_GFX14writeFastVLineEiiij
00002b1a l     F .text  0000000e _ZN12Adafruit_GFX10writePixelEiij
00002b28 l     F .text  0000015a _ZN12Adafruit_GFX9writeLineEiiiij
00002c82 l     F .text  0000000c _ZN8GxIO_SPI12setBackLightEb
00002c8e l     F .text  00000012 _ZN8GxIO_SPI14selectRegisterEb
00002ca0 l     F .text  000000e6 _ZN8GxIO_SPI4initEv
0080036c l     O .bss   00000001 _ZN8SPIClass11initializedE
00002d86 l     F .text  0000004c _ZN8GxIO_SPI5resetEv
00002dd2 l     F .text  00000002 _ZN4GxIO15setClockDividerEm
00002dd4 l     F .text  00000002 _ZN8SPIClass14endTransactionEv
00002dd6 l     F .text  00000010 _ZN8GxIO_SPI14endTransactionEv
00002de6 l     F .text  0000003a _ZN8SPIClass10transfer16Ej
00002e20 l     F .text  0000003c _ZN8GxIO_SPI11writeData16Ejm
00002e5c l     F .text  00000008 _ZN8GxIO_SPI10readData16Ev
00002e64 l     F .text  0000000e _ZN8SPIClass8transferEh
00002e72 l     F .text  00000012 _ZN8GxIO_SPI17writeAddrMSBfirstEj
00002e84 l     F .text  0000003c _ZN8GxIO_SPI9writeDataEPhm
00002ec0 l     F .text  00000006 _ZN8GxIO_SPI9writeDataEh
00002ec6 l     F .text  00000036 _ZN8GxIO_SPI12writeCommandEh
00002efc l     F .text  00000006 _ZN8GxIO_SPI8readDataEv
00002f02 l     F .text  00000006 _ZN8SPIClass16beginTransactionE11SPISettings
00002f08 l     F .text  00000024 _ZN8GxIO_SPI16startTransactionEv
00002f2c l     F .text  0000006e _ZN8GxIO_SPI22writeData16TransactionEjm
00002f9a l     F .text  0000003e _ZN8GxIO_SPI20writeDataTransactionEh
00002fd8 l     F .text  00000056 _ZN8GxIO_SPI23writeCommandTransactionEh
0000302e l     F .text  00000040 _ZN8GxIO_SPI21readData16TransactionEv
0000306e l     F .text  0000003a _ZN8GxIO_SPI19readDataTransactionEv
000030a8 l     F .text  00000040 _ZN8GxIO_SPI21transfer16TransactionEj
000030e8 l     F .text  0000003c _ZN8GxIO_SPI19transferTransactionEh
00003124 l     F .text  00000008 _ZN4GxIO13readRawData32Eh
0000312c l     F .text  00000018 _ZN13GxGDEH0154D6710_writeDataEh
00003144 l     F .text  000002a4 _ZN13GxGDEH0154D6710drawBitmapEPKhjjjjji
000033e8 l     F .text  0000001c _ZN13GxGDEH0154D6710fillScreenEj
00003404 l     F .text  000000bc _ZN13GxGDEH0154D674initEm
00800401 l     O .bss   00000050 Serial
000034c0 l     F .text  0000011a _ZN13GxGDEH0154D679drawPixelEiij
000035da l     F .text  00000002 _ZN5GxEPD14updateToWindowEjjjjjjb
000035dc l     F .text  00000002 _ZN5GxEPD12updateWindowEjjjjb
000035de l     F .text  00000002 _ZN5GxEPD12eraseDisplayEb
000035e0 l     F .text  00000018 _ZN5GxEPD17drawExampleBitmapEPKhmi
000035f8 l     F .text  00000002 _ZN5GxEPD11drawPictureEPKhS1_mmi
000035fa l     F .text  00000002 _ZN5GxEPD18drawExamplePictureEPKhS1_mm
000035fc l     F .text  0000001c _ZN5GxEPD11drawPictureEPKhm
00003618 l     F .text  00000030 _ZN5GxEPD17drawExampleBitmapEPKhjjjjji
00003648 l     F .text  00000002 _ZN5Print5flushEv
0000364a l     F .text  00000006 _ZN5Print17availableForWriteEv
00003650 l     F .text  0000001a _ZN5Print5writeEPKc.part.2.constprop.77
0000366a l     F .text  00000088 _ZN5Print11printNumberEmh.constprop.75
000036f2 l     F .text  0000000c _ZN5Print5printEji.constprop.72
000036fe l     F .text  0000000e _ZN5Print5printEPKc.constprop.71
0000370c l     F .text  00000004 __cxa_pure_virtual
00003710 l     F .text  00000010 _ZN6StringD2Ev
00003710 l     F .text  00000010 _ZN6StringD1Ev
00003720 l     F .text  00000050 _ZN6String7reserveEj
00003770 l     F .text  00000056 _ZN6String4copyEPKcj
000037c6 l     F .text  000000ea twi_stop
00800370 l     O .bss   00000004 twi_timeout_us
0080036f l     O .bss   00000001 twi_do_reset_on_timeout
0080036e l     O .bss   00000001 twi_timed_out_flag
008003ba l     O .bss   00000001 twi_sendStop
008003b9 l     O .bss   00000001 twi_inRepStart
000038b0 l     F .text  0000003e _ZN8GxIO_SPI12setFrequencyEm
000038ee l     F .text  00000116 _ZN13GxGDEH0154D6714_waitWhileBusyEPKcj
00003a04 l     F .text  0000019e _ZN13GxGDEH0154D6713_writeCommandEh
00003ba2 l     F .text  0000002e _ZN13GxGDEH0154D6712_Update_PartEv
00003bd0 l     F .text  0000002e _ZN13GxGDEH0154D6712_Update_FullEv
00003bfe l     F .text  0000002e _ZN13GxGDEH0154D679_PowerOffEv
00003c2c l     F .text  0000000c _ZN13GxGDEH0154D679powerDownEv
00003c38 l     F .text  00000042 _ZN13GxGDEH0154D6714_SetRamPointerEhhh
00003c7a l     F .text  00000066 _ZN13GxGDEH0154D6711_SetRamAreaEhhhhhh
00003ce0 l     F .text  000001ac _ZN13GxGDEH0154D6714_writeToWindowEjjjjjj.part.5
00003e8c l     F .text  0000012a _ZN13GxGDEH0154D6710_Init_FullEh
00003e8c l     F .text  0000012a _ZN13GxGDEH0154D6710_Init_PartEh
00003fb6 l     F .text  000001b8 _ZN13GxGDEH0154D6714updateToWindowEjjjjjjb
0000416e l     F .text  000002d2 _ZN13GxGDEH0154D6712updateWindowEjjjjb
00004440 l     F .text  000000da _ZN13GxGDEH0154D6712eraseDisplayEb
0000451a l     F .text  000001cc _ZN13GxGDEH0154D6710drawBitmapEPKhmi
000046e6 l     F .text  000000aa _ZN13GxGDEH0154D676updateEv
00005002 l     F .text  0000018e _GLOBAL__I_65535_0_FontArialOptimized.c.o.12941
0080019f l     O .data  00000012 _ZTV7Serial_
00800884 l     O .bss   0000000e oneWire
0080086d l     O .bss   00000017 sensors
0080085f l     O .bss   0000000e io
008001f7 l     O .data  00000032 _ZTV8GxIO_SPI
0080085e l     O .bss   00000001 SPI
00800451 l     O .bss   0000040d display
008001b1 l     O .data  00000046 _ZTV13GxGDEH0154D67
008003ee l     O .bss   00000001 _usbCurrentStatus
0080014a l     O .data  0000004e Font_array
00001991 l     O .text  00000004 Font
008003ef l     O .bss   00000004 temperature
0000197e l     O .text  00000013 STRING_PRODUCT
00001975 l     O .text  00000009 STRING_MANUFACTURER
0000195f l     O .text  00000004 STRING_LANGUAGE
00800198 l     O .data  00000007 _initEndpoints
00800100 l     O .data  00000004 _ZL10breakValue
008003eb l     O .bss   00000001 _ZL11wdtcsr_save
00001963 l     O .text  00000012 USB_DeviceDescriptorIAD
008003df l     O .bss   00000004 timer0_millis
008003de l     O .bss   00000001 timer0_fract
008003b7 l     O .bss   00000001 twi_error
008003b6 l     O .bss   00000001 twi_rxBufferIndex
00800396 l     O .bss   00000020 twi_rxBuffer
00800395 l     O .bss   00000001 twi_txBufferIndex
008003dd l     O .bss   00000001 twi_slarw
008003dc l     O .bss   00000001 twi_masterBufferIndex
008003db l     O .bss   00000001 twi_masterBufferLength
008003bb l     O .bss   00000020 twi_masterBuffer
000000ac l     O .text  0000018c image_data_Font_0x39
00000238 l     O .text  0000018c image_data_Font_0x38
000003c4 l     O .text  0000018c image_data_Font_0x37
00000550 l     O .text  0000018c image_data_Font_0x36
000006dc l     O .text  0000018c image_data_Font_0x35
00000868 l     O .text  0000018c image_data_Font_0x34
000009f4 l     O .text  0000018c image_data_Font_0x33
00000b80 l     O .text  0000018c image_data_Font_0x32
00000d0c l     O .text  0000018c image_data_Font_0x31
00000e98 l     O .text  0000018c image_data_Font_0x30
00001024 l     O .text  000000c6 image_data_Font_0x2e
000010ea l     O .text  00000108 image_data_Font_0x2d
000011f2 l     O .text  000001ce image_data_Font_0x2b
00800112 l     O .data  00000007 Font_0x39
00800119 l     O .data  00000007 Font_0x38
00800120 l     O .data  00000007 Font_0x37
00800127 l     O .data  00000007 Font_0x36
0080012e l     O .data  00000007 Font_0x35
00800135 l     O .data  00000007 Font_0x34
0080013c l     O .data  00000007 Font_0x33
000013c0 l     O .text  00000007 Font_0x32
000013c7 l     O .text  00000007 Font_0x31
000013ce l     O .text  00000007 Font_0x30
000013d5 l     O .text  00000007 Font_0x2e
000013dc l     O .text  00000007 Font_0x2d
00800143 l     O .data  00000007 Font_0x2b
00000000 l    df *ABS*  00000000 malloc.c
0000003e l       *ABS*  00000000 __SP_H__
0000003d l       *ABS*  00000000 __SP_L__
0000003f l       *ABS*  00000000 __SREG__
00000000 l       *ABS*  00000000 __tmp_reg__
00000001 l       *ABS*  00000000 __zero_reg__
00000000 l    df *ABS*  00000000 _clear_bss.o
000019fa l       .text  00000000 .do_clear_bss_start
000019f8 l       .text  00000000 .do_clear_bss_loop
00000000 l    df *ABS*  00000000 _divmodhi4.o
000057a0 l       .text  00000000 __divmodhi4_neg1
000057a8 l       .text  00000000 __divmodhi4_neg2
000057ae l       .text  00000000 __divmodhi4_exit
00000000 l    df *ABS*  00000000 _udivmodsi4.o
000057d6 l       .text  00000000 __udivmodsi4_ep
000057bc l       .text  00000000 __udivmodsi4_loop
00000000 l    df *ABS*  00000000 _udivmodhi4.o
00005816 l       .text  00000000 __udivmodhi4_ep
00005808 l       .text  00000000 __udivmodhi4_loop
00000000 l    df *ABS*  00000000 realloc.c
0000003e l       *ABS*  00000000 __SP_H__
0000003d l       *ABS*  00000000 __SP_L__
0000003f l       *ABS*  00000000 __SREG__
00000000 l       *ABS*  00000000 __tmp_reg__
00000001 l       *ABS*  00000000 __zero_reg__
00000000 l    df *ABS*  00000000 _exit.o
00005c18 l       .text  00000000 __stop_program
00001a34  w      .text  00000000 __vector_38
00001a34  w      .text  00000000 __vector_22
00005c08 g     F .text  0000000e strcpy
00001a34  w      .text  00000000 __vector_28
00001a34  w      .text  00000000 __vector_1
00001a34  w      .text  00000000 __vector_32
0000ffa0 g       *ABS*  00000000 __DATA_REGION_LENGTH__
00005678 g       .text  00000036 .hidden __epilogue_restores__
000055cc g     F .text  00000022 __fp_round
00001a34  w      .text  00000000 __vector_34
000055ee g     F .text  00000044 __fp_split3
00005800 g       .text  00000028 .hidden __udivmodhi4
000000ac g       .text  00000000 __trampolines_start
00005556 g     F .text  00000048 __fp_cmp
00005c1a g       .text  00000000 _etext
000056ae g     F .text  0000000e __subsf3
00001a34  w      .text  00000000 __vector_24
00001a34  w      .text  00000000 __vector_12
00001a34 g       .text  00000000 __bad_interrupt
00005bf6 g     F .text  00000012 memcpy
00005e86 g       *ABS*  00000000 __data_load_end
000054f8 g     F .text  00000034 __utoa_ncheck
00001a34  w      .text  00000000 __vector_6
00005828 g     F .text  00000138 malloc
00001a34  w      .text  00000000 __vector_31
0000554c g       .text  00000000 __lesf2
00001a34  w      .text  00000000 __vector_35
0000552c g     F .text  00000020 strrev
0080010e g     O .data  00000002 __malloc_heap_start
000000ac g       .text  00000000 __trampolines_end
00001a34  w      .text  00000000 __vector_39
00001a34  w      .text  00000000 __vector_3
00005632 g     F .text  0000000e __fp_zero
0000554c g       .text  00000000 __nesf2
00004cd2 g     F .text  00000094 __vector_23
00005c1a g       *ABS*  00000000 __data_load_start
000019e4 g       .text  00000000 __dtors_end
00800896 g       .bss   00000000 __bss_end
00001a34  w      .text  00000000 __vector_30
00000400 g       *ABS*  00000000 __LOCK_REGION_LENGTH__
00005bec g     F .text  0000000a abort
00001a34  w      .text  00000000 __vector_25
00800892 g     O .bss   00000002 __brkval
0000486e g     F .text  00000464 __vector_11
000019e4  w      .text  00000000 __init
00000000  w      *UND*  00000000 _Z14serialEventRunv
00001a34  w      .text  00000000 __vector_13
00001a34  w      .text  00000000 __vector_17
000055aa g     F .text  00000006 __fp_nan
00001a34  w      .text  00000000 __vector_19
00001a34  w      .text  00000000 __vector_7
0000559e g     F .text  0000000c __fp_inf
000019f0 g       .text  00000010 .hidden __do_clear_bss
00001a34  w      .text  00000000 __vector_41
00810000 g       .comment       00000000 __eeprom_end
0080010c g     O .data  00000002 __malloc_heap_end
00000000 g       .text  00000000 __vectors
00001a34  w      .text  00000000 __vector_27
0080036c g       .data  00000000 __data_end
0000554c g       .text  00000000 __eqsf2
00000000  w      .text  00000000 __vector_default
00005788 g       .text  00000028 .hidden __divmodhi4
00005a72 g     F .text  0000017a realloc
00001a34  w      .text  00000000 __vector_5
00001a34  w      .text  00000000 __vector_33
00000400 g       *ABS*  00000000 __SIGNATURE_REGION_LENGTH__
000057f4 g       .text  0000000c .hidden __tablejump2__
000019e2 g       .text  00000000 __ctors_start
00001a34  w      .text  00000000 __vector_37
00001a00 g       .text  00000016 .hidden __do_copy_data
0000554c g     F .text  0000000a __cmpsf2
000055be g     F .text  0000000e __fp_pscB
000055fe g       .text  00000000 __fp_splitA
0080036c g       .bss   00000000 __bss_start
00005190 g     F .text  00000368 main
0000554c g       .text  00000000 __ltsf2
00001a34  w      .text  00000000 __vector_4
00800060 g       *ABS*  00000000 __DATA_REGION_ORIGIN__
00000000  w      *ABS*  00000000 __heap_end
00001a34  w      .text  00000000 __vector_9
00001a34  w      .text  00000000 __vector_2
000056de g     F .text  000000cc __addsf3x
00000400 g       *ABS*  00000000 __USER_SIGNATURE_REGION_LENGTH__
00001a34  w      .text  00000000 __vector_21
00001a34  w      .text  00000000 __vector_15
00004d66 g     F .text  00000236 __vector_36
000055b0 g     F .text  0000000e __fp_pscA
00001a34  w      .text  00000000 __vector_29
00800896 g       .comment       00000000 __heap_start
000019e4 g       .text  00000000 __dtors_start
000019e4 g       .text  00000000 __ctors_end
00000aff  w      *ABS*  00000000 __stack
00001a34  w      .text  00000000 __vector_40
0080036c g       .data  00000000 _edata
00800896 g       .comment       00000000 _end
00001a34  w      .text  00000000 __vector_8
00001a34  w      .text  00000000 __vector_26
00005c16  w      .text  00000000 .hidden exit
00005788 g       .text  00000000 .hidden _div
00800894 g     O .bss   00000002 __flp
000057b0 g       .text  00000044 .hidden __udivmodsi4
00010000 g       *ABS*  00000000 __EEPROM_REGION_LENGTH__
00005c16 g       .text  00000000 .hidden _exit
00001a34  w      .text  00000000 __vector_14
00004790 g     F .text  000000de __vector_10
00001a34  w      .text  00000000 __vector_16
00800100 g       .data  00000000 __data_start
00001a34  w      .text  00000000 __vector_18
00000003 g       *ABS*  00000000 __FUSE_REGION_LENGTH__
00020000 g       *ABS*  00000000 __TEXT_REGION_LENGTH__
00800110 g     O .data  00000002 __malloc_margin
00001a34  w      .text  00000000 __vector_20
000056b0 g       .text  00000000 __addsf3
00001a34  w      .text  00000000 __vector_42
000054fa g       .text  00000000 __utoa_common
00005640 g       .text  00000038 .hidden __prologue_saves__
00005960 g     F .text  00000112 free
00005634 g       .text  00000000 __fp_szero
00001a16 g       .text  00000016 .hidden __do_global_ctors

Here is the output from the function for 2 Glyphs, + and -:

ANSI: -, CODE: 0x2D
LENGTH ADDR: 0x1991
GLYPH CODE ADDR: 0x150
GLYPH WIDTH ADDR: 0x13DE
GLYPH HEIGHT ADDR: 0x13E0
FONT LENGTH VAL PGM: 13
Width VAL PGM: 27
Height VAL PGM: 66
GLYPH DATA ADDR: 0x1313
DATA VAL PGM: 0xFE3FF
BOOTED!
ANSI: +, CODE: 0x2B
LENGTH ADDR: 0x1991
GLYPH CODE ADDR: 0x14A
GLYPH WIDTH ADDR: 0x145
GLYPH HEIGHT ADDR: 0x147
FONT LENGTH VAL PGM: 13
Width VAL PGM: 63743
Height VAL PGM: 61442
GLYPH DATA ADDR: 0x11F2
DATA VAL PGM: 0xFFFFFF
BOOTED!

What am I doing wrong?

You only post snippets.

Without a complete sketch, there is nothing to comment on,
I will not switch between posts to guess what you are doing.

But I have a guess, you use an embedded pointer that also points to PROGMEM.

Read that pointer first, then all the data relative to it.
Will probably even lead to more readable code.

I can see how this can be annoying, yes.

epaper_AT32U4_minimum.zip (6.8 KB)

A minimum version of code reproducing the issue.

Uploading a zip, is not what posting code means.

But maybe I should screenshot my answers and post them as zip to show you how it feels.

Nevermind then, thanks. :grin:

In case you're not familiar...

That's not a minimum. Limit FontArialOptimized.c to one character (e.g. image_data_Font_0x34 and static const tImage Font_0x34); also remove the comment that shows the character. Next post the three files, each one in it's own code block.

Nearly forgot, modify the sketch to only use that one character.

Here is the address of objects, got it with obj-dump out of the .elf file.

SYMBOL TABLE:
   :
0080014a l     O .data  0000004e Font_array
00001991 l     O .text  00000004 Font

   :
000010ea l     O .text  00000108 image_data_Font_0x2d
000011f2 l     O .text  000001ce image_data_Font_0x2b
   :
000013d5 l     O .text  00000007 Font_0x2e
000013dc l     O .text  00000007 Font_0x2d
00800143 l     O .data  00000007 Font_0x2b
00000000 l    df *ABS*  00000000 malloc.c

You need to be consistent. According to the symbol table, you have Font_0x2d in PROGMEM, and Font_0x2b in RAM. and Font is in PROGMEM (even though it's only 4 bytes), and Font_array is in RAM (even though it's "big")

You MUST use some version of pgm_read_xxx to access any structure that is in PROGMEM, and MUST NOT use it to access the data in RAM. The compiler can trick you because it doesn't actually understand the difference (two separate address spaces!), and will optimize PROGMEM accesses to constant addresses.
This means that:

   const char flashdata[] = {0, 1, 2, 3, 4, 5, 6};
   //   :
   a = flashdata[4];                     // appears to work - a will contain 4, because of optimization
   index = (digitalRead(12) ^ digitalRead(12)) + 4;  // almost certainly 4, but must be computed
   a = flashdata[index];                 // fails.
   a = pgm_read_byte(&flashdata[index]); // works

Hint: add -C to your objdump/nm command, and it will unscramble C++ names for you.


static const tImage Font_0x2e[]
const tChar Font_array[] 
PROGMEM const tFont Font

Suggestion: Be more explicit about the difference between a Glyph (info about a single character) and a Font (a collection of a bunch of Glyphs); it'll make the code more readable.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.