Author Topic: C-code; array of struct ? (Atmel Studio 6)  (Read 58239 times)

0 Members and 1 Guest are viewing this topic.

Offline magiccow

  • Contributor
  • Posts: 18
  • Country: gb
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #150 on: September 13, 2013, 11:45:17 am »
The syntax looks fine, and works on the gcc compiler. I'm guessing it is a quirk of your compiler.

You could try breaking into two steps:

struct _button {
  unsigned int top;
  :
  :
  char *caption;
};

typedef struct _button Button;




c:\> format c: /s
 

Online David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #151 on: September 30, 2013, 12:33:11 am »
Everything is working when I use a fixed size array for the caption inside the structure, but as I add more features to the program it's becoming apparent that fixed size is not the way to go.

Most of the buttons only use a few characters for a caption, but some need up to 30.  So, I thought about storing the pointer in the structure instead of the actual caption.

Code: [Select]
struct Button
{
uint16_t top;
uint16_t left;
uint16_t height;
uint16_t width;
uint8_t GlyphIndex;
unsigned long BgColour;
unsigned long FgColour;
_Bool IsLabel;
_Bool Enabled;
char *Caption;
};

struct Button Buttons[55];

This compiles fine, but the button drawing is wrong.  Each button now draws the text of the last one assigned.

Here's the function that sets up a button:
Code: [Select]
void ButtonSet(uint8_t BtnNo, uint16_t top, uint16_t left, uint16_t height, uint16_t width, uint8_t GlyphIndex, unsigned long BgColour, unsigned long FgColour, _Bool IsLabel, _Bool Enabled, void * caption)
{
Buttons[BtnNo].top = top;
Buttons[BtnNo].left = left;
Buttons[BtnNo].height = height;
Buttons[BtnNo].width = width;
Buttons[BtnNo].GlyphIndex = GlyphIndex;
Buttons[BtnNo].BgColour = BgColour;
Buttons[BtnNo].FgColour = FgColour;
Buttons[BtnNo].IsLabel = IsLabel;
Buttons[BtnNo].Enabled = Enabled;
strcpy(Buttons[BtnNo].Caption, caption);
}

And here's an example call to it:
Code: [Select]
ButtonSet(BtnSetup, BtnRow0Top, 380, BtnHeight, 250, 0, VGA_BLUE, VGA_YELLOW, 0, 1, "SETUP");

So it seems like the pointer to each caption is the same, hence the same caption appearing on all buttons.

There's obviously still a gap in my understanding of how pointers interact with the compiler and how it stores the strings in program memory.

Can anyone take a look please and tell me what bone-headed mistake (or assumption) I've made?
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #152 on: September 30, 2013, 12:45:21 am »
When you write char *Caption you are creating a pointer to the place where a caption may be stored, but you have not made available any storage. The pointer is in effect a pointer to nowhere. This means you cannot use strcpy because this will try to copy characters into a designated storage location that is supposed to already exist. If the destination does not exist it will copy characters into the void (which might, accidentally, happen to work on your machine, but it's not right).

I don't have time to go into details of how to fix the problem right now, but using char *Caption is certainly on the right lines. What you need to do is to store each caption somewhere, and then make the Caption pointer point to that location.

A classic way of doing this is to place all the captions end to end in a single block of memory with each caption terminated by a null. This would preferably be done statically during program initialization. Then you simply make each caption pointer point to the start of the right caption in this memory block. If the captions are fixed, you could allocate the memory block in read-only flash memory as has been hinted earlier in this thread.
 

Online David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #153 on: September 30, 2013, 12:48:22 am »
OK, looks like I've figured this one out.  The issue was in the ButtonSet function.

Changing from:
Code: [Select]
strcpy(Buttons[BtnNo].Caption, caption);
To this:
Code: [Select]
Buttons[BtnNo].Caption = caption;
Solved it!

Thanks for the explanation Ian.   :-+

EDIT: The captions change frequently during program execution.
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #154 on: September 30, 2013, 12:59:33 am »
EDIT: The captions change frequently during program execution.

I see, but are all the possible captions known in advance? Or might they have infinite possibilities?

If all the captions are known in advance you can pre-allocate them in a caption table, then select from them as desired.

For instance, when you write this...

Code: [Select]
ButtonSet(BtnSetup, BtnRow0Top, 380, BtnHeight, 250, 0, VGA_BLUE, VGA_YELLOW, 0, 1, "SETUP");
...the compiler sees the string "SETUP" and makes space for it somewhere in a table of program strings. In an ideal world (if the compiler is clever enough), it will notice two or three uses of "SETUP" and will make them share the same entry in the table to avoid duplication.

What the compiler does is usually fine, however if you take control of the situation you may have the opportunity to fine tune what happens (such as putting the strings in flash memory instead of RAM).

Since I don't have any familiarity with Atmel Studio I can't tell if this is important or necessary to do.
 

Online David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #155 on: September 30, 2013, 01:02:58 am »
Some of the strings are static, while others are user input.

It turns out I'm not out of the woods yet.  The buttons which have no caption (use a glyph instead) are now drawing the last caption.

I'll work though it and see how far I get.   :)
 

Online David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #156 on: September 30, 2013, 01:19:22 am »
The issue is only when the button has been assigned an empty string.

If I assign those to a single space instead and detect that in the drawing function, I can draw nothing instead.

It seems like an ugly work around however.   :-//
 

Online IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #157 on: September 30, 2013, 01:40:07 am »
Maybe the LCD library doesn't like empty strings?
 

Online David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2806
  • Country: au
Re: C-code; array of struct ? (Atmel Studio 6)
« Reply #158 on: September 30, 2013, 02:28:35 am »
Maybe the LCD library doesn't like empty strings?

Doesn't seem to be that.  I added a test for zero length string in there (to bail out if found) and no change.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf