Jump to content
43oh

PROGMEM / pointers on CC3200 (SOLVED)


Recommended Posts

Hi everyone,

 

I am new to the CC3200, but moderately familiar with Arduino MEGA2560 and DUE models, one being AVR the other being ARM.

 

My problem is PROGMEM and pointers related, and before you all flame me and tell me there is no progmem in an ARM based system, I know. But, I have already spent days at this and got nowhere, google etc, so if somebody could possibly assist me with this I would be MOST appreciative!

 

So far I have dumped the webserver sketch and have just a few lines of code which I will include in a moment. The following sketch will compile and run on my MEGA and my DUE. It will compile but not run properly on my CC3200, I really hope somebody can tell me how to make it work, or why it doesn't. I have checked and confirmed the <avr/pgmspace.h> file is included in the CC3200 cores folder, and looks remarkably similar to arduino SAM cores version, so that is not the reason. BAFFLED!! Please can someone help?

 

The Arduino IDE version I am using is 1.6.1, and Energia 0101E014 or 0101E015, both have the problem.

 

This is the sketch:-

#include <avr/pgmspace.h>
const uint8_t MAIN_MENU_SIZE = 3;
const char main_menu_1[] PROGMEM = "Something";
const char main_menu_2[] PROGMEM = "Nothing";
const char main_menu_3[] PROGMEM = "Everything";
PGM_P const MAIN_MENU_LABELS[MAIN_MENU_SIZE] PROGMEM = {
  main_menu_1,main_menu_2,main_menu_3};

void setup() {
  char buf[20];
  Serial.begin(115200);
  // I can print out a single menu item like this:
  strcpy_P(buf,main_menu_1);
  Serial.println(buf);
  // To get the same thing out of MAIN_MENU_LABELS,
  // MAIN_MENU_LABELS[1] should be the pointer to main_menu_2 in PROGMEM
  PGM_P menu_pgm_ptr = (PGM_P)pgm_read_word(&(MAIN_MENU_LABELS[1]));
  // So menu_pgm_ptr is a pointer to a string in program space.
  strcpy_P(buf,menu_pgm_ptr);
  Serial.println(buf); // And that works too! (On AVR and ARM on Arduino!! So why not CC3200??)
}

void loop() {
}


The result from both Arduinos is this :-

 

Something

Nothing
 

 

 

The result from the CC3200 is this :-

 

Something

Link to post
Share on other sites

Do you want the solution to still work on AVR? If not, cleaning up the PROGMEM silliness will make the code much more readable (and efficient).

const uint8_t MAIN_MENU_SIZE = 3;
const char main_menu_1[] = "Something";
const char main_menu_2[] = "Nothing";
const char main_menu_3[] = "Everything";
const char* MAIN_MENU_LABELS[MAIN_MENU_SIZE] = {
    main_menu_1,main_menu_2,main_menu_3};

void setup() {
    Serial.begin(115200);
    // I can print out a single menu item like this:
    Serial.println(main_menu_1);
    // To get the same thing out of MAIN_MENU_LABELS,
    // MAIN_MENU_LABELS[1] should be the pointer to main_menu_2
    Serial.println(MAIN_MENU_LABELS[1]); 
}

void loop() {
}

It's probably a bug in avr/progmem.h, which tries to substitute PROGMEM with constructs that work with CC3200.

Link to post
Share on other sites

Don't know the answer off hand - have you tried breaking this line down

PGM_P menu_pgm_ptr = (PGM_P)pgm_read_word(&(MAIN_MENU_LABELS[1]))

(either in the debugger, or using printf's) to see what the value is at each stage on the respective platforms?

 

i.e. 

Serial.println((ulong)MAIN_MENU_LABELS[1]);
Serial.println((ulong)&(MAIN_MENU_LABELS[1]));
Serial.println((ulong)(PGM_P)pgm_read_word(&(MAIN_MENU_LABELS[1])));
Serial.println((ulong)main_menu_2);

(Adding whatever modifiers/coersion to get the output to be the address, and probably want to make come out in hex).

 

What do you get if you do

strcpy_P(buf,main_menu_2);
Serial.println(buf);
Link to post
Share on other sites

@@igor,

 

I didn't think of doing that! :blush:  :rolleyes: Ok, so with the sketch modified to this :- 

#include <avr/pgmspace.h>
const uint8_t MAIN_MENU_SIZE = 3;
const char main_menu_1[] PROGMEM = "Something";
const char main_menu_2[] PROGMEM = "Nothing";
const char main_menu_3[] PROGMEM = "Everything";
PGM_P const MAIN_MENU_LABELS[MAIN_MENU_SIZE] PROGMEM = { main_menu_1, main_menu_2, main_menu_3 };

void setup() {
  char buf[20];
  Serial.begin(115200);
  // I can print out a single menu item like this:
  strcpy_P(buf, main_menu_1);
  Serial.println(buf);
  // To get the same thing out of MAIN_MENU_LABELS,
  // MAIN_MENU_LABELS[1] should be the pointer to main_menu_2 in PROGMEM
  PGM_P menu_pgm_ptr = (PGM_P)pgm_read_word(&(MAIN_MENU_LABELS[1]));
  // So menu_pgm_ptr is a pointer to a string in program space.
  strcpy_P(buf, menu_pgm_ptr);
  Serial.println(buf); // And that works too! (On AVR and ARM on Arduino!! So why not CC3200??)
  Serial.println((unsigned long)MAIN_MENU_LABELS[1], HEX);
  Serial.println((unsigned long) & (MAIN_MENU_LABELS[1]), HEX);
  Serial.println((unsigned long)(PGM_P)pgm_read_word(&(MAIN_MENU_LABELS[1])), HEX);
  Serial.println((unsigned long)main_menu_2, HEX);
  strcpy_P(buf, main_menu_2);
  Serial.println(buf);
}
void loop() {}

The results we get on AVR :-

 

Something

Nothing
F5
E6
F5
F5
Nothing
 

The results on ARM :-

 

Something

Nothing
81DFE
81DEC
1DFE
81DFE
Nothing
 

The results on CC3200 :-

 

Something

 
20004EE2
20004ED0
4EE2
20004EE2
Nothing
 

 

So I can deduce from that, that we have some sort of short/long pointer issue going on, but after that I would not know how to go about fixing it  :(

 

@@chicken,

 

No, I do not require it to work with AVR, I can only assume it already does. I don't know for sure, since I don't have WiFi hardware for my Arduino setup.

 

While I appreciate what you are saying about 'PROGMEM silliness', that is precisely what I have been trying to do for the past multiple hours over several days without success, which is why I came here to ask for help.

 

You made a splendid job of the VERY cut down over simplified example I supplied, maybe you would like to work your 'magic' on the actual sketch I wish to get to work on the CC3200? I have added it as an attachment since approx 700 lines is a bit much to post as code. 

 

Thanks again.

 

 

What I am wondering, since it is clearly the intention of the Energia team to offer compatibility with AVR sketches, hence the inclusion of <avr/pgmspace.h> if this is a bug? Where would I ask/post this?

 

Regards,

 

Graham

 

 

Edit: I did a little reading in the various versions of pgmspace.h and it seems the linker script and linker options should be doing the translation from 16bit addresses to 32bit address, which apparently works on the arduino IDE, but not the Energia any suggestions?

webserver.ino

webserver.h

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...