Skip to main content
Visitor II
August 9, 2017
Question

structure @0xXXXX

  • August 9, 2017
  • 4 replies
  • 2555 views
Posted on August 09, 2017 at 22:20

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.

    This topic has been closed for replies.

    4 replies

    Visitor II
    August 11, 2017
    Posted on August 11, 2017 at 10:17

    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

    Visitor II
    August 11, 2017
    Posted on August 11, 2017 at 13:04

     ,

     ,

    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

    Visitor II
    August 11, 2017
    Posted on August 11, 2017 at 13:36

    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

    Visitor II
    August 16, 2017
    Posted on August 16, 2017 at 16:32

    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

    Visitor II
    February 10, 2018
    Posted on February 10, 2018 at 17:09

    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,

    Sisto
    Visitor II
    February 10, 2018
    Posted on February 10, 2018 at 23:24

    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.