Not able to read bits from const __flash variable using SBIT macro

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

I trying to read two bits at a time from variables in flash memory.

 

Using Atmega328p

Example :-

#include <avr/io.h>  

#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)

struct bits {
	uint8_t b0:2;
	uint8_t b1:2;
	uint8_t b2:2;
	uint8_t b3:2;
} __attribute__((__packed__,__may_alias__));

uint8_t var1 = 0xff;
const __flash uint8_t var2 = 0xff;

uint8_t var3 = 0;
uint8_t var4 = 0;

int main(void)
{
	var3 = SBIT(var1,3);	// Works
	var4 = SBIT(var2,3);	// Does not work

    while (1)
    {
		__asm__ __volatile__ ("nop");
    }
}

 

 

 

This topic has a solution.
Last Edited: Sat. Mar 14, 2020 - 12:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You're casting away __flash in the SBIT define...

:: Morten

 

(yes, I work for Microchip, yes, I do this in my spare time, now stop sending PMs)

 

The postings on this site are my own and do not represent Microchip’s positions, strategies, or opinions.

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

Heisen wrote:
I trying to read two bits at a time from variables in flash memory.

 

1. What does "Works" and "Does not work" even mean? In serious programmer's forums describing a problem as "works" or "does not work" gets you banned for a month.

2. Is it a compilation problem or a run-time problem? Does your code compile? 

3. If it doesn't compile, which line is the first line that triggers an error? What error is it?

4. What language is it supposed to be? C or C++? (In AVR-GCC `__flash` is only available in C code: https://www.avrfreaks.net/comment/1338776 )

 

Most importantly: how come none of this information is present in your question?

Dessine-moi un mouton

Last Edited: Fri. Mar 13, 2020 - 11:16 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meolsen wrote:
You're casting away __flash in the SBIT define...

Couldn't understand. Is it a macro problem? Or I am retrieving data wrongly, or both?

 

AndreyT wrote:
What language is it supposed to be?

It is C.

 

AndreyT wrote:
Is it a compilation problem or a run-time problem? Does your code compile? 

Code compiles fine, It is run-time problem. var4 should contain value 3 just like var3 but it's empty.

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

__flash hides the fact that the var is in flash, and needs to be read with lpm. You do not simply want the address of the var, as the address is meaningless except for the lpm instruction. 

 

Just cut out the middleman, and access directly, as the macro you end with for the flash version will look a little more hideous than the sbit macro.

 

#include <avr/io.h>
#include <stdint.h>

 

typedef struct {
    uint8_t b0:2;
    uint8_t b1:2;
    uint8_t b2:2;
    uint8_t b3:2;
} bits_t;

 

const __flash bits_t varFlash = { 3,3,3,3 };

bits_t varRam = { 0,1,2,3 };

int main(void){

    varRam.b1 = varFlash.b3;

    for(;;){}
}

 

 

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

Flawless approach, Thanks. yes 

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

meolsen wrote:
You're casting away __flash in the SBIT define...

Heisen wrote:
Couldn't understand.

 

"casting" is short for "type casting"; a standard feature of the 'C' language - look it up in your 'C' textbook

 

Basically a cast tells the compiler, "I know this is declared as type A, but I want you to treat it as if it were type B"

 

In your case, the type A includes the __flash specifier - which is essential to tell the compiler that the data is in Flash, and requires "special treatment" to access it.

 

If you cast that to something else - which doesn't have the __flash specifier - then it's clearly not going to work!

 

This is the cast:

#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)

Note that lack of __flash !

 

EDIT

 

Extended

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Sat. Mar 14, 2020 - 10:04 AM