View previous topic :: View next topic |
Author |
Message |
haxan7
Joined: 27 Jul 2013 Posts: 79
|
struct with a constant member |
Posted: Sat Nov 22, 2014 1:26 am |
|
|
How do I declare a constant int in a struct.
I am trying to do the following, but its causing compilation error.
Code: |
typedef struct{
const uint16_t baud;
char delimiter[5];
} _DEVICE_SETTINGS;
|
I want to be able to pass the baudrate to setup_uart function that only accepts constants.
PIC24
Compiler v5.025 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 22, 2014 1:04 pm |
|
|
CCS won't let you combine flash and ram in the same structure.
If you want to use 'const' in the normal C way, where a variable
is stored in RAM but is read-only, then you can add this line
after your PIC #include line:
Then it will compile. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Sat Nov 22, 2014 1:11 pm |
|
|
Key to understand, is that setup_uart, is _not_ a function. It is a preprocessor directive, handled at compile time.
If you want multiple selectable baud rates, you have to do it like:
Code: |
#define B9600 1
#define B19200 2
int8 speed=B9600;
switch (speed)
{
case B9600:
setup_uart(9600);
break;
case B19200:
setup_uart(19200);
break;
}
|
This then generates both sets of code to setup the UART for the two rates. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
Re: struct with a constant member |
Posted: Tue Nov 25, 2014 6:04 am |
|
|
haxan7 wrote: | How do I declare a constant int in a struct.
I am trying to do the following, but its causing compilation error.
Code: |
typedef struct{
const uint16_t baud;
char delimiter[5];
} _DEVICE_SETTINGS;
|
|
Ttelmah has told you that this is not the way to control baudrates.
However, in C in general, but not necessarily in CCS C, const members of structures are unusual, but can be done. The important point to remember is that such consts must be initialised when the structure is instantiated, in other words when an actual instance of one is declared:
Code: |
typedef struct _DEVICE_SETTINGS {
const uint16_t baud;
char delimiter[5];
} _DEVICE_SETTINGS;
_DEVICE_SETTINGS My_Settings = { 9600, "abcd" };
|
After a structure is created, const members cannot be assigned: they are const after all!
In CCS C consts and normal variables are stored in totally separate memory spaces. This restricts what can be done with consts. The compiler cannot ordinarily create a pointer to a const. Consts often cannot be used a parameter to expecting a non-const. String literals, e.g. "This is a string", are different from variable arrays of char. Routines expecting one will not normally handle the other.
To make consts readable from RAM requires some special code, such as the #device CONST=READ_ONLY, which places all consts in RAM rather than ROM - that might also make it possible to have a pointer to consts. For strings there is #device PASS_STRINGS=IN_RAM that forces string literals (i.e. string constants) to be copied into RAM before being passed as parameters to routines. Both use more RAM than the default methods so are not much use if you want to pass large const arrays, such as parsing tables, message lists and graphical display font maps, which are larger than the available RAM. |
|
|
|