0
votes

A very novice question I'm afraid, but I've tried my best to understand this and have got nowhere as I have little experience with C programming.

I'm currently picking up an old project from a year or two ago from Instructables: https://www.instructables.com/id/Jar-of-Fireflies/

This includes a C file for firmware written for a Firefly pattern, however this was written a good 12 years ago.

However... I am not following the instructable to the Nth degree. Instead I am using a DIP AtTiny85, which I have previously programmed using an Arduino as ISP. And hence want to be able to compile the code in Arduino IDE or Atmel Studio, with Visual Micro plugin.

Every time this is compiled in Arduino IDE, I receive the following error: 'prog_uint8_t' does not name a type, and this causes lots of errors to roll through.

From what I understand, this deceleration was removed/changed as part of the AVR GCC in around 2010ish... Is there anyway I can get this to compile correctly to run the code? Maybe using a macro or including a library. I have tried a few libraries such as #include <stdint.h>, but believe this should be taken care of as part of automated <Arduino.h> include. I'm sure if I brought the proper programmer my problem may go away but I'm sure there is an easy fix for this..?

Code provided as .tgz in instructable link above which includes headers, c executables, hex etc.,

for quick reading of the main c executable declarations....

const prog_uint8_t about[] = "Jar of Fireflies\n"
        "Design and Implementation by Xander Hudson ([email protected])\n"
        "Idea and Inspiration by Kayobi Tierney\n"
        "Special thanks to Katie Horn for getting me to think about 
electronics";
const prog_uint8_t version[] = "$Revision: 1.41 $ $Date: 2007/01/10 
04:35:55 $";

#define LEDS_OFF ~(_BV(PIN_A) | _BV(PIN_B))

#define WATCHDOG_OK  WDTCR |= _BV(WDIE)

uint8_t pickapin (uint8_t);
const Song *pickasong (void);
uint8_t randwaitval (void);
uint8_t randbits (uint8_t);
uint8_t pickmaster (void);
uint8_t randscaleval (void);
void showbootup (void);

volatile uint8_t ch1restcount;
volatile uint8_t ch2restcount;

volatile uint8_t ch1nextnote;
volatile uint8_t ch2nextnote;

volatile uint8_t ch1scale;
volatile uint8_t ch2scale;
volatile uint8_t ch1nextscale;
volatile uint8_t ch2nextscale;

uint8_t mood = 2;
uint16_t mood_count = 30;   // WDT cycles before changing mood

volatile uint8_t masterpinmask;

Errors:

   In file included from C:\Program Files         
(x86)\Arduino\libraries\Firefly/firefly.h:12:0,

             from     
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:
C:\Program Files (x86)\Arduino\libraries\Firefly/songs/songs.h:4:11: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t  *notes; 

       ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:14:0,

             from         
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/bootsong.h:3:7: error: 'prog_uint8_t' does not name a type

const prog_uint8_t bootsongnotes[] = {0, 4, 9, 16, 24, 33, 41, 47, 50, 49, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/bootsong.h:5:26: error: 'bootsongnotes' was not declared in this scope

 Song bootsong = { sizeof(bootsongnotes), bootsongnotes };

                      ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/bootsong.h:5:42: error: 'bootsongnotes' was not declared in this scope

 Song bootsong = { sizeof(bootsongnotes), bootsongnotes };

                                      ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:25:0,

             from         
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2a.h:6:7: error: 'prog_uint8_t' does not name a type

const prog_uint8_t song2anotes[] = {2, 29, 81, 123, 130, 104, 63, 24, 2, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2a.h:20:24: error: 'song2anotes' was not declared in this scope

 Song song2a = { sizeof(song2anotes), song2anotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2a.h:20:38: error: 'song2anotes' was not declared in this scope

 Song song2a = { sizeof(song2anotes), song2anotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:26:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2b.h:6:7: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t song2bnotes[] = {1, 31, 89, 126, 119, 85, 42, 6, 1, 1,

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2b.h:19:24: error: 'song2bnotes' was not declared in this scope

  Song song2b = { sizeof(song2bnotes), song2bnotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2b.h:19:38: error: 'song2bnotes' was not declared in this scope

Song song2b = { sizeof(song2bnotes), song2bnotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:27:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2c.h:6:7: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t song2cnotes[] = {2, 25, 70, 117, 146, 144, 111, 61, 18, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2c.h:21:24: error: 'song2cnotes' was not declared in this scope

Song song2c = { sizeof(song2cnotes), song2cnotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2c.h:21:38: error: 'song2cnotes' was not declared in this scope

 Song song2c = { sizeof(song2cnotes), song2cnotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:28:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2d.h:6:7: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t song2dnotes[] = {1, 27, 72, 109, 121, 104, 61, 17, 1, 1, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2d.h:17:24: error: 'song2dnotes' was not declared in this scope

 Song song2d = { sizeof(song2dnotes), song2dnotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2d.h:17:38: error: 'song2dnotes' was not declared in this scope

 Song song2d = { sizeof(song2dnotes), song2dnotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:29:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2e.h:6:7: error: 'prog_uint8_t' does not name a type

const prog_uint8_t song2enotes[] = {1, 26, 73, 116, 131, 115, 80, 39, 8, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2e.h:21:24: error: 'song2enotes' was not declared in this scope

Song song2e = { sizeof(song2enotes), song2enotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2e.h:21:38: error: 'song2enotes' was not declared in this scope

 Song song2e = { sizeof(song2enotes), song2enotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:30:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2f.h:6:7: error: 'prog_uint8_t' does not name a type

const prog_uint8_t song2fnotes[] = {2, 36, 94, 130, 121, 79, 27, 1, 1, 1, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2f.h:17:24: error: 'song2fnotes' was not declared in this scope

 Song song2f = { sizeof(song2fnotes), song2fnotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2f.h:17:38: error: 'song2fnotes' was not declared in this scope

 Song song2f = { sizeof(song2fnotes), song2fnotes };

                                  ^

In file included from C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:31:0,

             from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2g.h:6:7: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t song2gnotes[] = {2, 42, 99, 121, 96, 42, 3, 1, 1, 1, 1, 

   ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2g.h:14:24: error: 'song2gnotes' was not declared in this scope

 Song song2g = { sizeof(song2gnotes), song2gnotes };

                    ^

C:\Program Files (x86)\Arduino\libraries\Firefly/songs/song2g.h:14:38: error: 'song2gnotes' was not declared in this scope

 Song song2g = { sizeof(song2gnotes), song2gnotes };

                                  ^

In file included from 
C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino:8:0:

C:\Program Files (x86)\Arduino\libraries\Firefly/firefly.h:133:7: error: 
'prog_uint8_t' does not name a type

 const prog_uint8_t bitmasks[] = { 

   ^

 Firefly01:11: error: 'prog_uint8_t' does not name a type

 const prog_uint8_t about[] = "Jar of Fireflies\n"

   ^

Firefly01:15: error: 'prog_uint8_t' does not name a type

  const prog_uint8_t version[] = "$Revision: 1.41 $ $Date: 2007/01/10 04:35:55 $";

   ^

In file included from C:\Users\Andrew\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:28:0,

             from sketch\Firefly01.ino.cpp:1:

C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino: In function 'int main()':

Firefly01:230: error: 'const Song' has no member named 'notes'

                 temp = pgm_read_byte(&ch1song->notes[ch1noteptr++]);

                                                ^

Firefly01:244: error: 'const Song' has no member named 'notes'

                 temp = pgm_read_byte(&ch2song->notes[ch2noteptr++]);

                                                ^

Firefly01:288: error: 'const Song' has no member named 'notes'

         temp = pgm_read_byte(&ch1song->notes[ch1noteptr++]);

                                        ^

Firefly01:313: error: 'const Song' has no member named 'notes'

         temp = pgm_read_byte(&ch2song->notes[ch2noteptr++]);

                                        ^

C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino: In function 
'void showbootup()':

Firefly01:379: error: 'const Song' has no member named 'notes'

             ch1nextnote = pgm_read_byte(&ch1song->notes[ch1noteptr++]);

                                                   ^

C:\Users\Andrew\Documents\Arduino\Firefly01\Firefly01.ino: In function 'uint8_t randbits(uint8_t)':

Firefly01:485: error: 'bitmasks' was not declared in this scope

 return ((lfsr & 0xFF) & pgm_read_byte(&bitmasks[bits]));    

                                        ^

exit status 1
'prog_uint8_t' does not name a type

// ------------------- END OF ERRORS

I expect the program to compile, once a way is defined for unsigned 8/16/32 bit int deceleration's.

If anyone could help me better understand that'd be great. As I'd rather not have write my own code when someone has spent ages getting the firefly alogrithims nice! But please I am willing to learn so any links to stuff like this would be good too.

2
It's pretty common for an older program's "portability improving" typedefs to have been lost. Try adding the line typedef uint8_t prog_uint8_t; somewhere near the top, and see how many of the errors go away.Steve Summit

2 Answers

0
votes

It was depreciated however you should be able to get it to work by adding the following code before your usage of prog_uint8_t

#define __PROG_TYPES_COMPAT__
#include  <avr/pgmspace.h>

typedef uint8_t PROGMEM prog_uint8_t;
0
votes

prog_uint8_t

This typedef provided by (very) old headers from avr-libc. The problem is that they used __attribute__((__progmem__)) in a typedef which is not supported by avr-gcc / avr-g++: progmem is a variable attribute and not a type attribute, c.f. avr-gcc ABI.


#define __PROG_TYPES_COMPAT__
#include  <avr/pgmspace.h>

This is not the solution: Whilst it "fixes" the build errors, it will invoke Undefined Behavior because progmem is not a type attribute. These types have been are deprecated for a reason!


typedef uint8_t PROGMEM prog_uint8_t;

This is not the solution: Whilst it "fixes" the build errors, it will invoke Undefined Behavior because progmem is not a type attribute.


typedef uint8_t prog_uint8_t;

This is not the solution: Whilst it "fixes" the build errors, objects declared with that type will be located in RAM, hence pgm_read_xxx() which is used to read data from flash / program memory will read garbage because the data is in the wrong address space. In principle, you could use that typedef and use vanilla C++ accesses instead of reading by means of pgm_read_xxx, but that is not what you want because PROGMEM was introduced to put const variables in flash and not into RAM. This is because for most AVRs, .rodata is located in RAM and not in flash. See however the note below.

So what is the solution then?

The proper solution is to use PROGMEM as defined by #include <avr/pgmspace.h> to all the object definitions that formerly used these dreaded prog types: Use

const uint8_t array_flash[] PROGMEM = { 1, 2 };

instead of the incorrect

const prog_uint8_t array_flash[] = { 1, 2 };

As you are using C++ and hence address spaces like __flash are not available, I won't go into that.

Note: There are AVR devices with a linear address space. For such devices, .rodata is located in flash. This means that for such devices, there is no advantage in using PROGMEM+pgm_read_xxx; in the contrary, you are just writing code that is less portable and hard to read and to maintain. Instead, use vanilla C++.

The device families to which this applies are avrtiny and avrxmega3 as listed in the avr-gcc documentation.