"cast to pointer of integer..." warning

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

I'm doing a C project in Atmel Studio 7. The target is the ATmega169. I'm using the eeprom to store a few critical items. So far, my code seems to run OK, but I always get the following warning on every line where I access the eeprom:

"cast to pointer from integer of different size[-Wint-to-pointer-cast]"

Example code snippet:

uint8_t channelCount; // eeprom address
    uint8_t IRData;
    uint8_t eData;
    for (channelCount = 0;channelCount < 7;channelCount++)
    {
        eData = eeprom_read_byte((uint8_t*)channelCount);
This line gets a warning.

 

As far as I can determine, I'm using the AVRGCC eeprom functions correctly, so why the warning?

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

See Tip #1 (in my signature, below; may not be visible on mobile) for how to properly post source code.

 

eeprom_read_byte( (uint8_t*)channelCount );  // This line gets a warning.

 

channelCount  is a uint8_t; you are casting it to a pointer.

 

I think you meant to cast its address to a pointer ?

ie,

eeprom_read_byte( (uint8_t*) &channelCount );  

but that cast is entirely unnecessary - just put

eeprom_read_byte( &channelCount );  

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: Wed. Jan 8, 2020 - 06:44 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If channelCount really is the numeric value of the eeprom address then you are casting a uint8_t integer value to a pointer, but a pointer is bigger than 8 bits (16 bits on AVR platform).

In which case adding another cast would get rid of the warning

 

eeprom_read_byte((uint8_t *)(uintptr_t)channelCount)

 

this is first casting to uintptr_t which wil be an unisgned type of whatever size it needs to be for a pointer, in AVR platform equivalent to uint16_t.

 

If this is what you are doing, there are other ways to use eeprom where the linker will assign the eeprom address, I think using EEMEM attribute when defining a variable that will be located in eeprom, in this case you would just use &channelCount.

 

 

 

 

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

Personally I would create an array of uint8_t in EEMEM then symbolically read from the locations &arrayname[channelCount] as channelCount iterates.

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

Well, I was writing my code based upon the examples shown in the .pdf explaining how to use the eeprom, by Dean Camera. In his examples, the eeprom address was just a number (46, to be exact) which, perhaps, defaulted to an int? However, the examples all showed casting that value of 46 to an uint8_t*, not a uint16_t*. So, is this tutorial incorrect, or is there some hidden issue that I'm not recognizing?

This is from the Microschip (Atmel owners now) online reference:

Function eeprom_read_byte()

uint8_t eeprom_read_byte(
	const uint8_t * __p)

Read one byte from EEPROM address __p. 

I don't know how significant the __p syntax shown is, but could that be the source (no pun intended) of the problem? Does __p indicate something more than just a generic variable?

 

Just for fun, I tried replacing (uint8_t*) with the ampersand (&), and that did not work. No build error, but running the hardware, the eeprom data were not changed. As you can see, I am obviously not very pointer savvy.

 

At this point, it looks as if using EEMEM might be the way to go. I did a separate small project and fiddled with it, and here's what seemed to work:

/*
 * eepromIntTest.c
 *
 * Created: 1/8/2020 2:01:09 PM
 * Author : Dave
 */ 

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

uint8_t eAddress;
uint8_t eData;
uint8_t temp;

uint8_t EEMEM eeData[8];

int main(void)
{
    temp = 0x00;
	for (eAddress = 0;eAddress < 7;eAddress++)
	{
		// write initial value of temp to ee
		eeprom_update_byte(&eeData[eAddress],temp);
		// read it back
		eData = eeprom_read_byte(&eeData[eAddress]);
		// now flip the bits and write back
		eeprom_update_byte(&eeData[eAddress],~eData);
	}
    while (1) 
    {
    }
}

 

This worked as expected running on the AVRDragon, so I think I'll go with it. I'd still be curious to know about why the AVR GCC reference shows the syntax it does, but for now, no warnings!

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

davetelling wrote:
the eeprom address was just a number (46, to be exact) which, perhaps, defaulted to an int? However, the examples all showed casting that value of 46 to an uint8_t*, not a uint16_t*.

Which isn't really the way to do it. If you have plain variables in RAM you don't just pick arbitrary addresses for them and place your char or uint16_t array at address 46. You let the linker place it for you. So why wouldn't you do that for EEPROM as well?

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

davetelling wrote:
I don't know how significant the __p syntax shown is

None at all - it's just a variable name

 

It's no different to

uint8_t eeprom_read_byte( const uint8_t *doris )

Read one byte from EEPROM address 'doris'. 

 

Does __p indicate something more than just a generic variable?

No.

 

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...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

davetelling wrote:
Well, I was writing my code based upon the examples shown in the .pdf explaining how to use the eeprom, by Dean Camera. In his examples, the eeprom address was just a number (46, to be exact) which, perhaps, defaulted to an int?

Yes, an integer constant like 46 is of type int, which happens to be the same width (16 bits) as a pointer (16 bits) on AVR platform.

So eeprom_read_byte((uint8_t *)46) doesn't generate the warning.

In your original code, if channelCount was defined as uint16_t rather than uint8_t then you wouldn't get the warning.

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

davetelling wrote:
I tried replacing (uint8_t*) with the ampersand (&)

Do you understand the difference between what those 2 things do?

 

I am obviously not very pointer savvy

Pointers are absolutely key to 'C' programming - so it's really important that you spend time mastering them!

 

Fortunately, they are a standard part of the language - not specific to AVR or microcontrollers - so any general 'C' textbook or tutorial should cover them.

 

Here are some 'C' learning & reference resources: http://blog.antronics.co.uk/2011...

 

that did not work. No build error, but running the hardware, the eeprom data were not changed

It was never an error - only a warning.

 

It is important to understand that "no compiler errors" simply means that you have no errors in your use of the language syntax or semantics - it tells you nothing about whether you program will actually work!

 

Having no build errors is necessary - but by no means sufficient.

 

It's like the spelling checker in your wordprocessor: it can tell you that all your words are correctly spelled, but it cannot tell you that your sentence makes any sense, or conveys the meaning you intended.

 

 

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...