cancel
Showing results for 
Search instead for 
Did you mean: 

structure @0xXXXX

Gene Letchford
Associate II
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.

7 REPLIES 7
luca239955_stm1_st
Senior II
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

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

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

Posted on August 11, 2017 at 13:53

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

luca239955_stm1_st
Senior II
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

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
henry.dick
Senior II
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.