2017-08-09 01:20 PM
I am trying to create a bit structure at a specified location (in this case at 0x500A the portc odr)
below is in common.h
struct iobits
{unsigned char b0:1;unsigned char b1:1;unsigned char b2:1;unsigned char b3:1;unsigned char b4:1;unsigned char b5:1;unsigned char b6:1;unsigned char b7:1;};extern struct iobits oportc;and this is in the main.c file
at 0x500A struct iobits oportc;
This works with Raisonance compiler, but not the Cosmic.
I then read that the Cosmic needed the following format
struct iobits oprotc @0x500A;
However an error occurs as follows:-
#error clnk Debug\lcc.lkf:1 bad address (0x500a) for zero page symbol _oportc
If I declare it without absolute address or another variable with the same format it works.
In common.h
extern struct iobits oportc;
extern oportd;and in main.c
struct iobits oportc;
oportd @0x500A; void main(void){oportd = 0x55; // this is located at 0x500A
op_str = 1; // this is located in page zero.Any help would be most appreciated.
2017-08-11 01:17 AM
Hello,
considering the address I guess your structure is a constant: see here
http://cosmicsoftware.com/faq/faq3.php
about how to declare a constant at a fixed memory address (using the #pragma section is also the general way to declare all types of complex variables at fixed memory addresses)Regards,
Luca
2017-08-11 06:04 AM
,
,
Hi Luca,
Thanks for the prompt reply, but I am confused about it !
0x500A is the sfr section of the stm8sxxx range. So it is not a constant.
oportd @0x500A, works and I can treat it as a variable.
struct iobits oprotc @0x500A, to me is the same, but does not work.
I would prefer to know why this is rather than just accept it does not work.
If you can explain I would appreciate it.
Also I did see the FAQ, but assumed it did not relate to this example as it was not a constant.
If that is the only way to do it then OK. I understand the ♯ pragma part.
However I have not had to use the linker before so I am not sure how and where to get the +seg .iconst -b 0xe0000 into it.
Sorry to go on, but I like to understand things and I do appreciate you taking the time to respond in the first place.
Regards....Gene
2017-08-11 06:36 AM
Hi,
sorry I did not read your initial post carefully enough; of course 0x500A is in the SFR range and it's not a constant.
I will have to confirm the following with our dev team, but I believe the issue is that the direct way of specifying a variable at an absolute address is only valid for simple variables (like you found with your oportd example), but for more complex variables (like structures or initialized variables) you will have to use the ♯ pragma and associated linker commands.
I will confirm the details next week, but I would suggest you check the way GPIOs are managed in the libraries provided by ST (file stm8s.h for example) to find a simple and proven way to manage SFRs.
Regards,
Luca
2017-08-11 06:53 AM
Hi Luca,
Thanks again for the prompt reply and explaining the reasons behind my example.
I am aware of the standard ways of handling SFR's, but my method gives a very easy (to me) and fast way to turn port bits on/off.
With &sharpdefine clk oportc.b0 and then clk=1; results in a single bit set or clk=0; bit reset at assembly time.
I have used this method for some years now and would like to continue using it under the Cosmic compiler.
So if I can continue with it then all my old code can be converted easily from Raisonance to Cosmic.
In closing I would still like some guidance if you can about adding the (+seg .iconst -b 0xe0000) to the Linker.
In anticipation and my sincere thanks for your help so far.
Regards.....Gene
2017-08-16 07:32 AM
Hello,
please contact me via email: luca dot
mailto:ubiali@comic
dot fr for further explanation (once everything is clear I will update this thread)Regards,
Luca
2018-02-10 08:09 AM
Hi,
Using Cosmic STM8 FSE, I've used this :
//------------------
typedef struct { // Bits structure
uint8_t bit_0 :1;
uint8_t bit_1 :1;
uint8_t
bit_2 :1;
uint8_t
bit_3 :1;
uint8_t
bit_4 :1;
uint8_t
bit_5 :1;
uint8_t
bit_6 :1;
uint8_t
bit_7 :1; }BITS;//------------------ and then:
#define My_Port_A (*(BITS*)GPIOA) // Point on first address of PORT A that's GPIOA_BASE (0x5000)
#define
My_Port_
C
(*(BITS*)GPIOC)
// Point on first address of PORT A that's GPIOC_BASE (0x
500A)
// Tested example on STM8L151C6:
My_Port_A.bit_7 = 1; // compiles to bset 20480,#7, write a '1' on ODR bit 7, of port A
My_Port_A.bit_7 = 0;
// compiled to bres
20480,#7,
write a
'0'
on ODR bit 7, of
port A
//.....
My_Port_C.bit_7 = 1; // compiled to bset 20490,#7, write a '1' on ODR bit 7, of port C
My_Port_C.bit_7 = 0;
// compiledto bres
20490,#7,
write a
'0'
on ODR bit 7, of
port C
Bye,
Sisto2018-02-10 02:24 PM
It is much easier to simply type cast a pointer to the structure and point it to the address. That's how it is typically done.