Advice for constant string arrays in C

Discussion in 'Embedded Systems and Microcontrollers' started by takao21203, Jul 20, 2012.

  1. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    Hello I request your help for the following:

    I want to store constant data inside arrays for various purposes.

    Sometimes this would be small strings, sometimes arrays with binary data.

    I have tried around a lot using the C compiler for this purpose. All I was able to do so far is the following:

    Code ( (Unknown Language)):
    1. #define chr_a 0x04,0b11110,0b00101,0b00101,0b11110
    2. #define chr_b 0x04,0b11111,0b10101,0b10101,0b01110
    4. const char s_chr_a[]={chr_a};
    5. const char s_chr_b[]={chr_b};
    7. const char* const alpha_chr[]={s_chr_a,s_chr_b};
    At first I define the data as a sequence of 8-bit pieces.

    Then I create a const string containing this sequence.

    Then I put numerous similar const strings into an array.

    It compiles correctly, and I used it a few times.

    I can obtain single array elements easily.

    But, is it possible to make the definition more easy?

    Is it possible for instance to put all the sequences directly in the const char * const array?

    Creating numerous const strings works but maybe it can be avoided.

    Another question I have if it is possible to build an array containing 5 bit elements (for instance), and only taking up 5 bits storage space?

    I have shown an excerpt of a program that I am currently working on.
    Previously, I only used textual strings, but now it is data pieces only requiring 5 bits.

    I do know that PICs for instance on 16F baseline store constant string data using sequences of RETLW instructions, and then 8-bit values are returned.

    If there is any easy advice, please do it.

    But I can also continue to use it as explained above.

    Edit: The reason why define is used to put together 8bit data is that normally I use this to support various languages. Some character sets are multiple byte, so I build them using cascading define sequences.

    Edit: Actually currently I convert an assembler data table to C language. So the original data looks like this:
    Code ( (Unknown Language)):
    1. /*
    2. lc_d:
    3.  dw 4
    4.  dw b'11111'
    5.  dw b'10001'
    6.  dw b'10001'
    7.  dw b'01110'
    8. lc_e:
    9.  dw 4
    10.  dw b'11111'
    11.  dw b'10101'
    12.  dw b'10101'
    13.  dw b'10001'
    14. lc_f:
    15.  dw 4
    16.  dw b'11111'
    17.  dw b'00101'
    18.  dw b'00101'
    19.  dw b'00001'
    Last edited: Jul 20, 2012
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    There's no need to do it in two steps like that:
    Code ( (Unknown Language)):
    2. const char s_chr_a[]={0x04,0b11110,0b00101,0b00101,0b11110};
    3. const char s_chr_b[]={0x04,0b11111,0b10101,0b10101,0b01110};
    Again yes, first ways offhand I can think of is to create these by shoving the 5 bit words together:

    Sample data:
    Code ( (Unknown Language)):
    1. element  value
    2.    0     10000
    3.    1     10010
    4.    2     10100
    5.    3     10110
    6.    4     11000
    7.    5     11010
    Now these get strung together:

    Code ( (Unknown Language)):
    1. 11010 11000 10110 10100 10010 10000
    parsing to bytes:
    Code ( (Unknown Language)):
    1.  0b110101 0b10001011 0b01010010 0b01010000
    And drop into array:
    Code ( (Unknown Language)):
    1.  const char Packed[] = {0b110101 0b10001011 0b01010010 0b01010000}
    To access these, you need to compute the offset byte count and bit count, shift things over, all the time keeping in mind the 5 bit words can and do overlap byte boundaries so you want to use integer types (for the current byte and the next byte too) to handle the character data.

    You'll probably want to make a helper program to make the arrays for you from the raw 5 bit data too.

    You could probably get the compiler to do a lot of this work for you if you define a long (32 bit) structure of the 5 bit entities so you only loose 2 out of 32 bits (6%)as opposed to 3 out of 8 bits (37%).

    I'm still playing with that method. I can get 5 bit elements but have yet to keep them confined to the 32 bits.
  3. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    I was more asking if there is a way to put the individual strings in the strings array. The define's are required for multibyte characters, where I want to use symbolic names for individual characters.

    But here I use it for font data.

    Apparently on a 16f59. There is also another big problem, I was not able to find a way to deference the array pointer.

    When I use:
    Code ( (Unknown Language)):
    1. void process(const char* a)
    2. {char x= *a;
    the compiler tells me it can't generate code for that.

    On midrange PICs and 18F, it actually works. But not on baseline.

    All what's possible is to pass
    Code ( (Unknown Language)):
    1. &alpha_chr[2]
    instead of
    Code ( (Unknown Language)):
    1. alpha_chr[2]
    And that does not work for dereferencing, somehow.
    I get the correct value for the individual strings, but then
    the dereferencing does not work.

    I have spent hours, including to examine the disassembly.

    Using the MPLABX SIM is even worse, it is not able to step through the dereferencing, and jumps incorrectly.

    However, on the hardware it executes without stack corruption.

    I have then displayed the obtained values in binary on the LED matrix!

    It seems to be a 16bit value is generated, for the memory page, and the offset.

    I have even written a direct access function for the string table using big A...

    at 0xF1, there is a small piece of code generated by the compiler to access string tables, I figured out parameters are passed via memory address 0x0a, and 0x0b. It is possible to access it manually, even if the generated assembly code to do so is more lengthy.

    After some hours guesswork, I was able to obtain the character data!

    Code ( (Unknown Language)):
    1. unsigned char get_b(const char* a,unsigned char idx)
    2. {
    3.     ab=a;
    4.     ab0=ab;
    5.     ab1=ab>>8;
    7.     STATUS=0;
    8.     ab2=idx;
    10. #asm
    11. GLOBAL _ab,_ab0,_ab1,_ab2,_x
    12.     MOVF (_ab0),W
    13.     movwf 0x0a
    14.     movf (_ab1),W
    15.     MOVWF 0x0b
    16.     call 0xf1
    17.     movwf (_x)
    19.     movf (_x),W
    20.     movwf 0x0a
    21.     movf (_ab2),W
    22.     addwf 0x0a,f
    23.     movf (_ab1),w
    24.     movwf 0x0b
    25.     call 0xf1
    26.     movwf _x
    27. #endasm
    28.     return(x);
    29. }
    The next thing is how can I do the actual scrolling?

    On a larger PIC, I have copied the proportional font data into a large Array, which is then parsed line by line.

    However I don't have so much buffer RAM available.

    I think I need to compute the total length in bits, then increase this bits pointer, and compute the offset each time it is increased, means parse through all the character data.

    It is not clear to me how I can do this efficiently, for instance if I want to keep the width adjustable (characters can have different width in terms of bytes).

    Also I need to rotate the output.

    Somehow I am thinking of a projection algorithm, that gets a single scan line, and then projects it to the display memory.

    Eventually, it is way too much effort to implement it on a 16f59.

    Even if it is possible from the viewpoint of memory footprint- there are about 30% program memory used up now, including the font data.

    I should use a more powerful PIC, simply, and put the computed scroll bitmap in a larger RAM buffer. But, since the scrolling does only happen a few times/second, it should be possible to process all the font data, even if this takes 10k or 20k inctruction cycles.

    I have read through the compiler manual there is not much information about strings at all. There is no information that apparently on the baseline PICs, dereferencing is not possible, only to use the & operator. But then the final dereferencing on the individual character level simply does not work!

    Using big A is really a final resort.
  4. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    ErnieM, I think he's talking about using a 2 dimensional array?

    If these are for text strings I think that's an ugly way of doing it. I would just put all the text strings into one array, then use 2 indexing variables to select which text string and which character.

    It's a good goal with embedded coding to keep it simple in design, then work from there. Some array and pointer techniques from Windows programming etc are not a good idea in an embedded design.
  5. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    And how would you do that in C?

    How would you know the index value?
    It could be more than 256 bytes.

    By the way I have done it like that in assembler, used a relocation table with 256 bytes for the whole ASCII, pointing into the string table.

    I have now a SUPER 16F59- with 2K RAM buffer.

    Otherwise these chips would never see opportunity to be used.

    Yes there are serial SRAM chips now.

    But the wires for 256 bytes are not so many...just a few.

    If you know any good way to use constant tables in XC8, let me know.

    Reloctation/indexing tables I had sufficienct in assembler,
    was quite a hassle for nested LCD menu's.
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    I'm not following what you want.

    You would need to show an example. This works for me:
    Code ( (Unknown Language)):
    1. #include <htc.h>
    3. const char Str[] = "ABCD";
    4. void process(const char* a);
    6. main(void)
    7. {
    8.   process(&Str);
    9.   process(&Str[0]);
    10.   process(&Str[1]);
    11.   process(&Str[2]);
    12.   process(&Str[3]);
    13. }  
    15. void process(const char* a)
    16. {
    17.   char x = *a;
    18. }  

    It builds without warning and the simulator has no trouble telling me the value of x.

    I could not follow the remainder of your post. Please being up a single problem at a time to discuss.
  7. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    I don't think I would want to craft indexing for string tables manually.

    The following works quite well, larger than 256 bytes no problem.

    Code ( (Unknown Language)):
    1. const char* const months_jp[]=
    2. {s_ichigatsu,s_nigatsu,s_sangatsu,\
    3.  s_shigatsu,s_gogatsu,s_rokugatsu,s_shichigatsu,\
    4.  s_hachigatsu,s_kugatsu,s_juugatsu,s_juuichigatsu,s_juunigatsu};
    5. const char* const months_jp_lt[]=
    6. {"ichigatsu","nigatsu","sangatsu","shigatsu","gogatsu","rokugatsu",\
    7.  "shichigatsu","hachigatsu","kugatsu","juugatsu","juuichigatsu","juunigatsu"};
    8. const char* const months_en[]=
    9. {"January","February","March","April","May","June","July",\
    10.  "August","September","October","November","December"};
    11. const char* const months_en_sh[]=
    12. {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
    just for the baseline PICs, the compiler is not able to create code for dereferencing.

    Maybe there is a way to do it in C. It is not clear to me why the compiler can't do it.

    And you see as well, the english strings I spell directly in the strings array.
    Last edited: Jul 21, 2012
  8. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    OK I will try your sample for 16F59.

    However, I ask how to dereference arrays in the form const char* const xxxx[]={str1,str2,str3};

    I have given example code above, that works well on midrange 16F, and 18F.

    On the baseline I have done it manually using big A.

    I am trying to get along with the project, so I have mentioned additional issues. But I have solved it by adding a 2K RAM.

    This project is mainly for my own entertainment, and to improve my programming skills.

    I know it could be done simply using a 18F (for instance).
  9. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    OK I tried, using the 16f59, MPLABX 1.30 + XC8 1.01

    I get a zero value.

    Maybe I am doing something wrong, or it needs to be spelled slightly differently?

    2 screenshots attached. I get a virtual address for the string table,
    but the value I obtain from dereferencing is zero.
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    It's hard to tell from screen shots as what is being moused over isn't clear. Plus it only can show one variable. Did MPLABX do away with the watch window? That can show an explicit set of variables.

    What did process return? Did it work correctly?

    It does for me, under MPLAB 8.84/CX8v1.00

    Code ( (Unknown Language)):
    2. #include <htc.h>
    4. const char Str[] = "ABCD";
    5. char process(const char* a);
    7. main(void)
    8. {
    9.   char XX;
    10.   XX = process(&Str[0]);
    11.   XX = process(&Str[1]);
    12.   XX = process(&Str[2]);
    13.   XX = process(&Str[3]);
    14. }  
    16. char process(const char* a)
    17. {
    18.   char x = *a;
    19.   return x;
    20. }  
  11. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    Have you used 16f59?

    I can only obtain zero.

    There are also various issues using MPLABX. I always had issues with MPLAB, the PICKIT2, and sometimes also PICKIT3.

    -Make sometimes will freeze and needs to be terminated with task manager
    -Menus sometimes disappear when I hover the topics. This has improved with 1.30, but is still present

    -Memory areas are apparently mixed up, assembler code that is generated simply stops inbetween at 3ff. I fixed that with putting the main function at 0x400.

    -I had serious troubles with my assembler containing routine, until I have now also put it at 0x0050 absolutely.

    -There have been various issues with putting data variables into memory, even if more than 50% are left. I also solved that by putting some variables into page zero absolutely.

    Altogether it is a nightmare to use the 16f59.
    I still can't use the debugger (MPLAB SIM) properly, it even has issues with the TRIS instruction.

    But I have not tried maybe it is better now having some stuff at absolute addresses.

    Using 16F midrange or 18F, none of the serious issues above is present. Except the MAKE sometimes will freeze.

    I tried to run MPLAB SIM again, it seems to be mixing up things when the string routine is called. The PCL will contain 0x82, that is also the first entry from the string table. However I can't trace into it (single step).

    But I made letters A-D working now, I can store them into the RAM, read back, and display them. I give up for now, it's 4.29AM here

    I wonder if I can make this program working as intended...having all these issues.

    And, if you can maybe test for a const char* const[] string table?

    The entries from the string table were actually returned in the hardware program, but after that, I have not been successful to do the second deferencing, to get individual bytes from the string. I tried hours yesterday,
    including to display things in binary on the small LED matrix display.

    Code ( (Unknown Language)):
    1. unsigned char get_b(const char* a,unsigned char idx) @ 0x050
    2. {
    3.   // ab=a;
    4.   // ab0=ab;
    5.   // ab1=ab>>8;
    7.     ab0=((unsigned int)(a));
    8.     ab1=((unsigned int)(a))>>8;
    10.     STATUS=0;
    11.     ab2=idx;
    14. #asm
    15.  GLOBAL _ab,_ab0,_ab1,_ab2,_x
    17.     MOVF (_ab0),W
    18.     movwf 0x0a
    19.     movf (_ab1),W
    20.     MOVWF 0x0b
    21.     call 0xf1
    22.     movwf (_x)
    24.     bcf (_STATUS),5
    25.          bcf (_STATUS),6
    26.     incf (_ab0),f
    27.     MOVF (_ab0),W
    28.     movwf 0x0a
    29.     movf (_ab1),W
    30.     MOVWF 0x0b
    31.     call 0xf1
    32.     movwf (_x2)
    34.     bcf (_STATUS),5
    35.          bcf (_STATUS),6
    36.     movf (_x),W
    37.     movwf 0x0a
    38.     movf (_ab2),W
    39.     addwf 0x0a,f
    40.     movf (_x2),w
    41.     movwf 0x0b
    42.     call 0xf1
    43.    movwf (_x)
    45.              bcf (_STATUS),5
    46.          bcf (_STATUS),6
    47. #endasm
    49.   //  display_data[0]=(x>>5)&0x1f;
    50.   //  display_data[1]=x&0x1f;
    51.   //  display_data[2]=(x2>>5)&0x1f;
    52.   //  display_data[3]=x2&0x1f;
    53.     return(x);
    54. }
    This is what I am using now, not that I would be very fond of it.
  12. WBahn


    Mar 31, 2012
    Have you looked into bit fields? I don't know if that will do what you want, nor do I know if it is a practical approach on a MCU or with compiler's that target an MCU.
  13. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    yes I saw this in various C books, on websites, inside manuals etc.

    But I did not yet feel sufficient enough to attempt to cram large amounts of elements into an array, using said bitfields.

    The compiler somehow would generate code (means AND masks) to aquire the bits? And if I load them into an 8 bits char, also clear it before loading?

    I will read through it again.

    The assembler construct works well enough in terms of stability, seems to be I am doing everything required (manually) to read from the compiler generated string tables.

    I still don't understand what is the reason why the compiler can not do this for me like on midrange and 18F.

    So if I have some element in the form const char* const data1[]={"STR1","STR2"};

    I can pass data1[0] (for instance) to a function having the parameter form void func_a(const char* a)

    Then in turn I can dereference using *a, which gives me the first character from string 1 (element 0).

    After that I can simply increment a as pointer.

    On the baseline, all what is possible to compile is to pass &data1[0] to the said function.

    I have examined the values obtained all the way through using binary display on the small LED matrix.

    The string tables use a high word of 0x80 for page 0, 0x81 for page 1, etc.,
    then followed by the index inside the same page for the element. *actually first the high word, then the index, see attach.

    The (compiler generated) function (or code piece) excepts two parameters, the page number OR'ed with 0x80, as well the index.

    The final string table only contains a data element!

    I have also tried to do a second dereferencing (passing the address with the & operator), however it simply does not work!

    I have spent hours on this. As I wrote above on midrange and 18F, I simply pass the element literally. Some kind of built-in dereferencing?

    I have again created code to display the obtained pointer value (&alpha_chr[0]), and to display it on the LED matrix. It is a bit lengthy, however, it does not work inside the debugger.

    I can successfully obtain the entries from the first level string table.

    So if I spell &alpha_chr[0], actually I obtain a 16-bit virtual address.
    This address in turn is passed to the compiler string fetcher.

    I have taken a screen shot from the first level table.

    And the main function is included, with some code deactivated.

    I get (on the LED matrix) flipping through the virtual addresses for the first level string table.

    So, this is 0x8081, 0x8083, 0x8085, etc.

    However, I need to do a second deferencing.

    Since the data is in the form const char* const data1[]

    I have not yet been successful with this!

    Code ( (Unknown Language)):
    1. void main(void) @ 0x400
    2. {
    3.     const char* curr_chr_size2_ptr;
    4.     unsigned char curr_chr_size2,disp2,disp3;
    5.     unsigned int disp;
    7.     ConfigureOscillator();
    8.     InitApp();
    10.     tsize=0;
    11.     for(i=0;i<26;i++){tsize+=get_b(&alpha_chr[i],0);}
    13.     chr_curr=0;
    14.     while(1)
    15.     {
    16.         if(TMR0>0x80)
    17.         {TMR0=0;
    18.          refresh();
    19.          scrollstep_ctr++;
    20.         }
    22.         if(scrollstep_ctr>200)
    23.         {
    24.             scrollstep_ctr=0;
    25.             do_scroll();
    27.             curr_chr_size=get_b(&alpha_chr[chr_curr],0);
    29.             curr_chr_size2_ptr=&alpha_chr[chr_curr];
    30.             curr_chr_size2=*curr_chr_size2_ptr;
    32.             disp=(unsigned int)(curr_chr_size2_ptr);
    33.             disp2=((unsigned int)(disp))>>8;
    34.             disp3=((unsigned int)(disp));
    36.     display_data[0]=(disp2>>5)&0x1f;
    37.     display_data[1]=disp2&0x1f;
    38.     display_data[2]=(disp3>>5)&0x1f;
    39.     display_data[3]=disp3&0x1f;
    41.     display_data[4]=(curr_chr_size2>>5)&0x1f;
    42.     display_data[5]=curr_chr_size2&0x1f;
    44.    //         for(i=0;i<5;i++){store_ram(16+i,0);
    45.    //         display_data[display_pos[i]]=0;}
    47.    //         for(i=0;i<curr_chr_size;i++)
    48.    //         {store_ram(16+i,get_b(&alpha_chr[chr_curr],i+1));}
    50.             chr_curr++;
    51.             if(chr_curr>25)chr_curr=0;
    53. //            for(i=0;i<curr_chr_size;i++)
    54.   //          {display_data[display_pos[i]]=load_ram((16+(curr_chr_size-1))-i);}
    55.         }
    56.     }
    57. }[/i][/i][/i]

    The refreshing code for the matrix is not included.

    Relevant are these lines:
    Code ( (Unknown Language)):
    1.     curr_chr_size2_ptr=&alpha_chr[chr_curr];
    2.             curr_chr_size2=*curr_chr_size2_ptr;
    I want to obtain byte 0 from element 0, which is the size of the element, which I have stored manually in every element.
    After that, the data. So I also need to increment this pointer.

    I guess if I would pass the element without the &qualifier,
    one level of dereferencing already will be done.

    How can I do the 2-level dereferencing?
    What are the required typcasts?
    Is it possible at all?

    It does not matter if it is complicate to spell.
    I would prefer to do it in C, instead of using assembler.

    I am also sorry it is a bit complex. It is way over a forum thread maybe to include documentation of all steps that I have taken, screen shots from all the memory, the string fetcher etc.

    If you don't follow/don't understand enough, I can supply more information.
  14. WBahn


    Mar 31, 2012
    My guess is that it is a simply matter of the compiler seeing a certain operation and saying, "for this pattern, I need to generate this sequence of assembly instructions" and, for base parts, the resources needed to support that sequence simply aren't there. That doesn't mean that the pattern can't be implemented, just that the compiler hasn't been taught how within the resource constraints.
  15. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    So maybe something like
    Code ( (Unknown Language)):
    1. const char* lvl2= (const char*)(*lvl1);
    can do the job?

    If lvl1 is
    Code ( (Unknown Language)):
    1. const char* lvl1=&alpha_chr[0];

    I made a video showing the output of above code on the LED matrix.

    Bit0 is at the top, towards Bit7 at the bottom.

    The first two lines are displaying 16bits value of the pointer I obtained, see post #14.
    The third line suggests to be indeed the index part again of a virtual pointer.

    Hampering to my efforts really is the fact baseline code can not execute correctly in MPLABX SIM.
    I use latest v. 1.30
    Even the TRIS instruction causes the simulator to stop, I get around this by changing the PC manually.
    The numerical value obtained for the string pointer is incorrect, then after this when the string fetcher is called, the Simulator will enter an endless loop.

    Only when I have done the typecasts to display 16 bits value on real hardware (LED display), I have indeed gained more understanding how strings are used/generated etc. by PIC C.

    I also made a video stepping through a small piece of code, where I obtain the 16bit virtual address.
    All I get is zero...and this is apparently incorrect. It works in real hardware.
    The Simulator seems to have a problem with the typecasts.
    Last edited: Jul 23, 2012
  16. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    Yes seems to be some kind of top-level dereferencing is built-in as compiler ability, but not for baseline.

    1. It can be done in assembler
    2. Maybe there is a way to do it in C, I have obtained some new ideas. Also to display the 16-bit values, to obtain them at all, I had to do typecasting all the way through.

    There is no sufficient documentation about this in the compiler manual.

    Maybe there are some (PIC specific) books with such topics?

    However I don't want to have a stack of beginner's books around, with mostly irrelevant information. Books I have for Windows programming...mostly 3D graphics stuff.

    I would consider to buy one book if it teaches me some professional aspects of PIC micro C.
  17. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012
    Ugly isn't it?

    Code ( (Unknown Language)):
    2. curr_chr_size2_ptr=&alpha_chr[chr_curr];
    3. curr_chr_size2=*curr_chr_size2_ptr;
    4. lvl2=   ((const char*)\
    5.          (\
    6.          (*curr_chr_size2_ptr)\
    7.          |\
    8.          (\
    9.          ((unsigned int)(*(curr_chr_size2_ptr+1)))<<8)\
    10.          )\
    11.          );
    13. curr_chr_size2=*((const char*)(lvl2));
    Apparently the compiler is not intelligible enough to load a 16bit value from the string table. Even if the (const char*) typecase is used, only 8bits are loaded. So it is required also to load the high byte, which is stored at the next address inside the string table.

    Isn't there an easier way to do this? Or is it uncommon to use jagged arrays inside PIC C? Or is it that normally I would have to use determined indexing? Means fixed length strings?

    A little better:
    Code ( (Unknown Language)):
    2.         lvl22=*(curr_chr_size2_ptr+1)<<8;
    3.         lvl22<<=8;
    4.         lvl22|=*(curr_chr_size2_ptr);
    5.         lvl2=(const char*)lvl22;
    All the code needed to get the pointer to the first string character from a string table in the format
    const char* const[]={"str1","str2"}

    Code ( (Unknown Language)):
    2.      curr_chr_size2_ptr=&alpha_chr[chr_curr];
    3.      lvl22=*(curr_chr_size2_ptr+1);
    4.      lvl22<<=8;
    5.      lvl22|=*(curr_chr_size2_ptr);
    6.      lvl2=((const char*)(lvl22));
    7.      curr_chr_size2=*lvl2;
    Last edited: Jul 23, 2012
  18. WBahn


    Mar 31, 2012
    What is a "jagged array"?

    When you say:

    const char* constr[]={"str1","str2"};

    You are saying that you have an array consisting of two pointers. One pointer points to the first character of the first string and the second pointer points to the first character of the second string. Nothing 'jagged' about it.
  19. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    I still have no dea what you are trying to accomplish and what is the issue.

    It appears you are having problems using string pointer arrays for the PIC16F59. These work for me just fine using the MPLAB (not X) simulator for the PIC16F59 device:

    Code ( (Unknown Language)):
    2. #include <htc.h>  // for PIC16F59
    3. const char* Strings[]={"a1","bb22","ccc333"}; // define "jagged" array
    4. char Buffer[10];
    5. void FillBuffer(char* Dest,const char* Source);
    7. main(void)
    8. {
    9.   FillBuffer(Buffer, Strings[0]);
    10.   FillBuffer(Buffer, Strings[1]);
    11.   FillBuffer(Buffer, Strings[2]);
    12. }  
    14. void FillBuffer(char* Dest, const char* Source)
    15. {
    16.   while ( (*Dest++ = *Source++) != 0);
    17. }  
    After each call to FillBuffer the contents of Buffer are inspected in the watch window and contain the expected characters.
  20. takao21203

    Thread Starter Distinguished Member

    Apr 28, 2012

    I clearly wrote that this form does not compile.
    I have to use the & operator.

    The reason why it compiles on your machine are unknown to me.

    Also jagged = javascript array

    means multidimension array. Not to implement a definition in terms of of PIC programming topics. Only for some kind of reference. There are abilities to deal with arrays built into javascript.

    I also wrote that it does compile for 16F midrange and 18f.

    In addition the issue is solved, as I figured out how it can be done in C.

    Remember that pointer could be obtained from anywhere, or where the information can be found that I always can use the automatic dereferencing?

    I have now gained understanding how the compiler is dealing with constant data on the 16F.

    Thank you for your help.