Label pointers into flash (AVR-GCC)

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi All! I have a code:

ISR(TWI_vect)
{
	static void	*label_list[] = {&&label1,&&label2,&&label3,...,&&label31};
	goto *label_list[TWSR>>3];
label1:
	// Do something
	return;
label2:
	// Do something
	return;
...
label31:
	// Do something
	return;
}

How can I store label_list into flash? When I declare it at the beginning:

static const void		*label_list[] PROGMEM = {&&label1,&&label2,&&label3,...,&&label31};

I have an error label 'labelxx' referenced outside of any function
If I write it inside the block I have an error variable 'twi_table' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
If I write:

static const int	label_list[] PROGMEM = {&&label1,&&label2,&&label3,...,&&label31};

I have warnings: initialization makes integer from pointer without a cast [enabled by default]
How do it right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Veter0k wrote:
How do it right?
Use a switch statement to get the same effect.
ISR(TWI_vect)
{
  switch (TWSR>>3)
  {
  case 0:
    // Do something
    break;
  case 1:
    // Do something
    break;
...
  case 31:
   // Do something
   break;
  }
}

Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think that switch-case will be proceed more long time. But maybe I'm wrong.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are (most likely) wrong. For a large number of consecutive case values the compiler will likely use a look-up table.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you! I'll compare these two methods.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This for switch-case:

00000071  IN R24,0x01		In from I/O location 
00000072  CPI R24,0x28		Compare with immediate 
00000073  BRNE PC+0x02		Branch if not equal 
00000074  RJMP PC+0x0045		Relative jump 
00000075  BRCC PC+0x10		Branch if carry cleared 
00000076  CPI R24,0x10		Compare with immediate 
00000077  BREQ PC+0x26		Branch if equal 
00000078  BRCC PC+0x07		Branch if carry cleared 
00000079  TST R24		Test for Zero or Minus 
0000007A  BREQ PC+0x20		Branch if equal 
0000007B  CPI R24,0x08		Compare with immediate 
0000007C  BREQ PC+0x02		Branch if equal 
0000007D  RJMP PC+0x0090		Relative jump 
0000007E  RJMP PC+0x001F		Relative jump 
0000007F  CPI R24,0x18		Compare with immediate 
00000080  BREQ PC+0x39		Branch if equal 
00000081  CPI R24,0x20		Compare with immediate 
00000082  BREQ PC+0x02		Branch if equal 
00000083  RJMP PC+0x008A		Relative jump 
00000084  RJMP PC+0x0054		Relative jump 
00000085  CPI R24,0x40		Compare with immediate 
00000086  BRNE PC+0x02		Branch if not equal 
00000087  RJMP PC+0x005A		Relative jump 
00000088  BRCC PC+0x08		Branch if carry cleared 
00000089  CPI R24,0x30		Compare with immediate 
0000008A  BRNE PC+0x02		Branch if not equal 
0000008B  RJMP PC+0x0050		Relative jump 
0000008C  CPI R24,0x38		Compare with immediate 
0000008D  BREQ PC+0x02		Branch if equal 
0000008E  RJMP PC+0x007F		Relative jump 
0000008F  RJMP PC+0x004F		Relative jump 
00000090  CPI R24,0x50		Compare with immediate 
00000091  BRNE PC+0x02		Branch if not equal 
00000092  RJMP PC+0x005C		Relative jump 
00000093  CPI R24,0x58		Compare with immediate 
00000094  BRNE PC+0x02		Branch if not equal 
00000095  RJMP PC+0x0070		Relative jump 
00000096  CPI R24,0x48		Compare with immediate 
00000097  BREQ PC+0x02		Branch if equal 
00000098  RJMP PC+0x0075		Relative jump 
00000099  RJMP PC+0x0052		Relative jump 

This for jump table:

0000008C  IN R30,0x01		In from I/O location 
0000008D  LSR R30		Logical shift right 
0000008E  LSR R30		Logical shift right 
0000008F  LSR R30		Logical shift right 
00000090  LDI R31,0x00		Load immediate 
00000091  LSL R30		Logical Shift Left 
00000092  ROL R31		Rotate Left Through Carry 
00000093  SUBI R30,0xAC		Subtract immediate 
00000094  SBCI R31,0xFF		Subtract immediate with carry 
00000095  LPM R24,Z+		Load program memory and postincrement 
00000096  LPM R25,Z		Load program memory 
00000097  PUSH R24		Push register on stack 
00000098  PUSH R25		Push register on stack 
00000099  RET 		Subroutine return 

But in fact switch-case works a little more quickly. And I don't know why?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try to write it inside function with 2 "const":

ISR(TWI_vect)
{
	static const void * const PROGMEM label_list[] = {&&label1,&&label2,&&label3,...,&&label31};
	goto *label_list[TWSR>>3];
label1:
	// Do something
	return;
label2:
	// Do something
	return;
...
label31:
	// Do something
	return;
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, but I already found a solution, the same as yours)