cac001 0 Posted May 7, 2006 Report Share Posted May 7, 2006 (edited) Bug description: Pointer manipulation of ROM based literal strings fail Steps to reproduce: Compile sample code Expected behavior: Value returned by PickString is not valid for ROM based strings. Is the problem 100% reproducible: Always occurs IDE version: SourceBoost IDE version 6.35 Compiler: BoostC Compiler version: 6.35 Target device: PIC16F877A OS: Windows XPpro SP2 #include <system.h> // target 16F877A //Configuration Bits #pragma DATA _CONFIG, _CP_OFF & _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_OFF & _HS_OSC //20 MHz quartz #pragma CLOCK_FREQ 20000000 /* Sample code to demonstrate issues with ROM pased literal string pointers */ #define ROM rom /* fails when strings are in ROM */ //#define ROM /* works when strings are in RAM */ ROM char *var_names = "Hot_Thres \0" "Hot_Peak_Thres \0" /* use a smaller number of string so they will fit into RAM "Hot_No_Control \0" "Cold_Thres \0" "Phase_3_Counts \0" "Hot_Close_Inc \0" "CloseTemp \0" "Close_Multiplier \0" "Close_Divider \0" "Start_Samp \0" */ "SwInc \0" "OffsetFromLimit \0"; unsigned char j,c; ROM char * PickString(unsigned char index) { unsigned int offset = 0; while (index) { if (var_names[offset] == 0) { if (var_names[offset+1] == 0) { return 0; } index--; } offset++; }; c = var_names[offset]; return (&var_names[offset]); } void main() { ROM char *cur_string; while (1) { for (j=0; j<11; j++) { cur_string = PickString(j); if (cur_string) { c = cur_string[0]; } else { c = 0; // string not found } } } } Edited May 8, 2006 by cac001 Quote Link to post Share on other sites
Pavel 0 Posted May 7, 2006 Report Share Posted May 7, 2006 Your code uses a clever approach but unfortunatly it won't work. In the code each rom string is identified as an 8 bit long number as opposed to 16 bit long pointer used for ram string. And the & operand operates with ram strings only. Using & with a rom string will produce undocumented results (maybe we even should make compiler generate an error for such code). However your code slightly changed can use an offset to identify a substring inside a rom string and this should work fine. Something like: //This function converts a substring index into an offset of the start of this substring unsigned char PickString(unsigned char index) { unsigned char offset = 0; while (index--) { while( var_names[offset++] ); } return offset; } void main() { unsigned char cur_string; while (1) { for (j=0; j<11; j++) { cur_string = PickString(j); // Value of 'cur_string' now points to the start of a substring 'j' ... } } } Regards, Pavel Quote Link to post Share on other sites
cac001 0 Posted May 8, 2006 Author Report Share Posted May 8, 2006 Does this mean that BoostC does not support dynamic pointers to ROM based static data? For example: rom char *var_names = "Hot_Thres \0" "Hot_Peak_Thres \0"; rom char *cur_string; cur_string = &var_names[str_offset]; c = cur_string[0]; Fails because BoostC cannot dynamically create the pointer to var_names[str_offset] when the var_names array is located in ROM. And this code: rom char *var_names = "Hot_Thres \0" "Hot_Peak_Thres \0"; c = var_names[str_offset]; works because the address of var_names is known at compile time. If this is true then the help file entry on the rom storage class really needs a few more details. Quote Link to post Share on other sites
Pavel 0 Posted May 8, 2006 Report Share Posted May 8, 2006 Does this mean that BoostC does not support dynamic pointers to ROM based static data? Yes that's correct. All addresses for ROM based data must be known at compile time. Regards, Pavel Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.