Author Topic: [gcc C] concatenating text to make up code  (Read 19868 times)

0 Members and 1 Guest are viewing this topic.

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: [gcc C] concatenating text to make up code
« Reply #125 on: October 11, 2018, 08:48:47 pm »
Here virtual ports are just mappings into bit accessible region. So you have an alternative for the regular registers, which you can access using bit set/clear instructions. You don't need OUTSET/OUTCLR, since you have dedicated instructions to do so. In C this is virtually useless.
« Last Edit: October 11, 2018, 08:53:36 pm by ataradov »
Alex
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: [gcc C] concatenating text to make up code
« Reply #126 on: October 12, 2018, 12:08:22 am »
On my last post where I posted an example, I also tacked on the comment at the end that the PORTBASE could be changed to the vport address. I then realized the spacing of those addresses (4) did not make sense and saw that these vport registers are just a minimal set. I deleted the comment, but you may have seen it before I deleted it. Didn't mean to send you on the wrong path with vport, although now you know.

I probably shouldn't cause more confusion, but...

Here's what (I think) can be done using vport addresses. This is the exact same code as I posted in my previous post, except now using vport addresses. The calculation of the vport port offset (a,b,c...) is different (>>3) and the register offsets are different ([1]=OUT, [2]=IN), but otherwise the its mostly the same except now the IN/OUT/CBI/SBI instructions are available.

I think this is correct, but not 100% certain.

Code: [Select]
//test.c
#include <stdint.h>
#include <stdbool.h>

typedef enum {
    A0=0x00, A1, A2, A3, A4, A5, A6, A7,
    B0=0x20, B1, B2, B3, B4, B5, B6, B7,
    C0=0x40, C1, C2, C3, C4, C5, C6, C7,
    D0=0x60, D1, D2, D3, D4, D5, D6, D7,
    E0=0x80, E1, E2, E3, E4, E5, E6, E7,
    F0=0xA0, F1, F2, F3, F4, F5, F6, F7,
    //all my pin info here
    SW1=A2, LED1=B3
} PIN_t;

//added VPORTBASE- also added 0x20 offset as
//vport addresses are IO addresses (in iom4809.h), seems we
//need to get vport address into a 'mem' address range
//so the compiler will see its in the IO address range (confusing, yes)
//go read srf_defs.h for a good time
enum { PORTBASE= 0x400, VPORTBASE = 0x20 };

static inline bool pin_get(PIN_t pin)
{
    //VPORTBASE offset [2] is IN register
    return ( (volatile uint8_t*)(VPORTBASE+(pin>>3)) )[2] & (1<<(pin&7));
}
static inline void pin_set(PIN_t pin, bool tf){
    //VPORTBASE offset [1] is OUT register
    if(tf)( (volatile uint8_t*)(VPORTBASE+(pin>>3)) )[1] |=  1<<(pin&7);
    else  ( (volatile uint8_t*)(VPORTBASE+(pin>>3)) )[1] &= ~(1<<(pin&7));
}

void main()
{
    pin_set( LED1, pin_get(SW1) );

    for(;;);
}
/*
./avr-gcc -C -Os test.c && ./avr-objdump -d a.out

Disassembly of section .text:

00000000 <main>:
   0:   12 9b           sbis    0x02, 2 ; 2
   2:   02 c0           rjmp    .+4             ; 0x8 <__zero_reg__+0x7>
   4:   2b 9a           sbi     0x05, 3 ; 5
   6:   01 c0           rjmp    .+2             ; 0xa <__zero_reg__+0x9>
   8:   2b 98           cbi     0x05, 3 ; 5
   a:   ff cf           rjmp    .-2             ; 0xa <__zero_reg__+0x9>
*/

edit-
and to make it complete by setting the pin dirs, one could add
Code: [Select]
typedef enum { DIR_IN, DIR_OUT } DIR_t;

static inline void pin_dir(PIN_t pin, DIR_t dir)
{
    //VPORTBASE offset [0] is DIR register
    if(dir)( (volatile uint8_t*)(VPORTBASE+(pin>>3)) )[0] |=  1<<(pin&7);
    else  ( (volatile uint8_t*)(VPORTBASE+(pin>>3)) )[0] &= ~(1<<(pin&7));
}
with this added to main
Code: [Select]
    pin_dir( LED1, DIR_OUT );
    pin_dir( SW1, DIR_IN );
resulting in this additional code
Code: [Select]
   0:   23 9a           sbi     0x04, 3 ; 4
   2:   02 98           cbi     0x00, 2 ; 0
« Last Edit: October 12, 2018, 12:39:24 am by cv007 »
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #127 on: October 12, 2018, 06:42:21 am »
It's working, my dyslexic eyes did not see the difference between 0x0400 and 0x04000
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #128 on: October 13, 2018, 10:57:44 am »
So I am now looking into the counter registers and of course now we have 16 bit registers. so does uint16_t simply make this work? or have I bypassed that much of the compiler that I need to do the arithmetic to add together the two 8 bit memory locations?
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: [gcc C] concatenating text to make up code
« Reply #129 on: October 13, 2018, 12:06:27 pm »
Compilers know how to work with 8/16/32/64 bit numbers, you just need to tell it.

You can now also figure out why array type access can go wrong when dealing in array types larger than a byte. Read the comments in code.
So in this case the normal 'pointer method' is used (*) with the 'normal' byte addition taking place before the compiler knows it's going to be a uint16_t pointer.
The code below shows the compiler can access the 16bit register (actually 2 8bit registers since this is an 8bit micro), and it also does it in the correct order (because they know all about these things- read avr mega0 manual 7.5.6).

Code: [Select]
//test.c
#include <stdint.h>

enum { TCB_BASE = 0x0A80 };
typedef enum { TCB_0, TCB_1, TCB_2, TCB_3 } TCBn_t;

static inline uint16_t tcb_count(TCBn_t n)
{
    return *(volatile uint16_t*)(TCB_BASE+(n<<4)+0x0A);
    //now we can no longer use 'array' type access, since 0x0A
    //is a byte offset and the array element is a 'uint16_t'
    //so the the actual offset value in bytes would be 0x0A*(sizeof(uint16_t)
    //try it so see the register values accessed- will be wrong
    //return ( (volatile uint16_t*)(TCB_BASE+(n<<4)) )[0x0A];
}

uint16_t c;
void main()
{
    c = tcb_count(TCB_0);
    for(;;);
}

//2 bytes loaded from CNT, stored in global variable

//notice the compiler reads the low byte first, which is correct
//(they know all about these type of things)

/*
00000010 <main>:
  10:   80 91 8a 0a     lds     r24, 0x0A8A     ; 0x800a8a <__bss_end+0xa28>
  14:   90 91 8b 0a     lds     r25, 0x0A8B     ; 0x800a8b <__bss_end+0xa29>
  18:   90 93 61 00     sts     0x0061, r25     ; 0x800061 <_edata+0x1>
  1c:   80 93 60 00     sts     0x0060, r24     ; 0x800060 <_edata>
  20:   ff cf           rjmp    .-2             ; 0x20 <main+0x10>

*/
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #130 on: October 13, 2018, 01:31:10 pm »
I am sorry but you have confused me.

From what you say I can do as i proposed: simply use a 16 bit type pointer and the compiler deals with the rest.

I ask as i know that if i use the manufacturers definitions i can just read/write a 16bit register name as the IDE have built in tools that deal with it as it would any 16 bit+ variable. I am though not using those defines i am writing to a memory location, so when I point to one 8 bit address with a 16bit pointer does the compiler simply put the extra 8 bits in the next address location?

Alternatively i manually do the 16bit read/write procedure described in the manual (which i have done in the past).
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: [gcc C] concatenating text to make up code
« Reply #131 on: October 13, 2018, 02:31:39 pm »
Quote
he IDE have built in tools that deal with it as it would any 16 bit+ variable. I am though not using those defines i
The built in tool is the compiler. The compiler doesn't care where the defines come from, and actually the compiler doesn't really deal with defines at all- by the time the compiler gets to work the pre-processor has done a big search and replace on all your code. You are dealing with the search and replace, I prefer to talk directly to the compiler when possible. The end result can be the same, but one of us has to figure out what is happening in the search and replace.

My examples use no defines, and the compiler does what its told. We are all talking to the same compiler, you just have to tell it what you want in whatever method you want.

edit- here is a 'define' version-
Code: [Select]
//test.c
#include <stdint.h>
#define TCB0_BASE 0x0A80
#define TCB0_COUNT_OFFSET 0x0A
#define TCB0_COUNT() *(volatile uint16_t*)(TCB0_BASE+TCB0_COUNT_OFFSET)

uint16_t c;
void main()
{
    c = TCB0_COUNT();
    for(;;);
}

/*
//compiled with --save-temps
//in test.i you can see what the pre-processor did
//and the compiler uses this file as its source
//and looks like this (for the part we are interested in)-
//(you can see the result of simple search and replace)

uint16_t c;
void main()
{
    c = *(volatile uint16_t*)(0x0A80+0x0A);
    for(;;);
}

//and the same result
00000010 <main>:
  10:   80 91 8a 0a     lds     r24, 0x0A8A     ; 0x800a8a <__bss_end+0xa28>
  14:   90 91 8b 0a     lds     r25, 0x0A8B     ; 0x800a8b <__bss_end+0xa29>
  18:   90 93 61 00     sts     0x0061, r25     ; 0x800061 <_edata+0x1>
  1c:   80 93 60 00     sts     0x0060, r24     ; 0x800060 <_edata>
  20:   ff cf           rjmp    .-2             ; 0x20 <main+0x10>


*/
« Last Edit: October 13, 2018, 02:51:21 pm by cv007 »
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #132 on: October 13, 2018, 02:50:19 pm »
The only defines I am using is to allocate names to memory addresses to make the code more readable and so that if they come out with a similar chip (ATmega 1-series) that puts things in different memory locations I can still use the same functions if i rewrite the memory allocation definitions again. This is not dissimilar to how it already works.

If they make a new chip with the same TCBn peripheral but stick all of it's registers as are at a different offset all i need to do is change one definition and all of the current code will work.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: [gcc C] concatenating text to make up code
« Reply #133 on: October 13, 2018, 03:02:12 pm »
Quote
If they make a new chip with the same TCBn peripheral but stick all of it's registers as are at a different offset all i need to do is change one definition and all of the current code will work.
Makes no difference
I change this line
enum { TCB_BASE = 0x0A80 };

you change this line
#define TCB_BASE 0x0A80

same result

If they make new parts in the same series, they are not going to start moving peripheral addresses around. If they come out with another series, kiss most of your code goodbye anyway.
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #134 on: October 13, 2018, 03:16:35 pm »
Well I gather that they have new tiny series out already which likely use the same peripheries. I am confused why the names ever happened and why they are sticking as it it clear that all AVR's will now go up to 64KB of address space as they use a 16bit address bus and all use the AVR cpu and I expect all of the peripheries are the same so I could use my code on tiny's. To make the new mega's they have taken the xmega architecture and knocked the address space down and moved it to 5V silicon. I suspect the 1-series will perhaps come back with more memory space (16MB address space anyone?)

using defines or variables is amounting to the same thing but I am using pure numbers for the compiler not variables that will either be optimised out or stick around in overhead.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2539
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #135 on: October 13, 2018, 04:01:19 pm »
Quote
If they make a new chip with the same TCBn peripheral but stick all of it's registers as are at a different offset all i need to do is change one definition and all of the current code will work.
Makes no difference
I change this line
enum { TCB_BASE = 0x0A80 };

you change this line
#define TCB_BASE 0x0A80

same result

Except that there is a subtle difference between the two.

In the "enum" case, the compiler creates an actual variable that's used at run time.

In the "#define" case, separate constants are created for each instance that it's used at compile time.  The pre-processor replaces each instance of TCB_BASE with 0x0A80 and then the code is compiled.

I haven't been following this thread, so you would need to determine which is appropriate.
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #136 on: October 13, 2018, 04:09:35 pm »
Quote
If they make a new chip with the same TCBn peripheral but stick all of it's registers as are at a different offset all i need to do is change one definition and all of the current code will work.
Makes no difference
I change this line
enum { TCB_BASE = 0x0A80 };

you change this line
#define TCB_BASE 0x0A80

same result

Except that there is a subtle difference between the two.

In the "enum" case, the compiler creates an actual variable that's used at run time.

In the "#define" case, separate constants are created for each instance that it's used at compile time.  The pre-processor replaces each instance of TCB_BASE with 0x0A80 and then the code is compiled.

I haven't been following this thread, so you would need to determine which is appropriate.

The difference is that with enum the value is checked which i can see no use for. I am using this stuff to write arduino style functions so once written and verified they will never be edited again, only invoked
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3140
  • Country: ca
Re: [gcc C] concatenating text to make up code
« Reply #137 on: October 13, 2018, 04:17:09 pm »
I change this line
enum { TCB_BASE = 0x0A80 };

you change this line
#define TCB_BASE 0x0A80

same result

It is, but even in this rudimentary case defines are more flexible. For example, you can change the define later:

Code: [Select]
#define TCB_BASE get_tcb_base()
and it'll change this automatically through all your files.

Or this:

Code: [Select]
#ifndef TCB_BASE
  #define TCB_BASE 0x0A80
#endif

This way if you define TCB_BASE in the upstream .h file then it will use your define, otherwise it'll fall back to the default value.

Or this:

Code: [Select]
#ifdef USE_BOOTLOADER // this will come from the command line
  #define TCB_BASE get_tcb_base()
#else
  #define TCB_BASE 0x0A80
#endif

There are countless things you can do with macros which cannot be done without them.

 
The following users thanked this post: Siwastaja

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #138 on: October 13, 2018, 04:40:58 pm »
Quote
If they make a new chip with the same TCBn peripheral but stick all of it's registers as are at a different offset all i need to do is change one definition and all of the current code will work.
Makes no difference
I change this line
enum { TCB_BASE = 0x0A80 };

you change this line
#define TCB_BASE 0x0A80

same result

Except that there is a subtle difference between the two.

In the "enum" case, the compiler creates an actual variable that's used at run time.

In the "#define" case, separate constants are created for each instance that it's used at compile time.  The pre-processor replaces each instance of TCB_BASE with 0x0A80 and then the code is compiled.

I haven't been following this thread, so you would need to determine which is appropriate.

In this case there is no variable used at run time since we're dealing with static inline functions. It's all compiler magic. The resulting assembly code was even produced as proof of identical results by either method.

But as you said, you haven't been following the thread.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2539
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #139 on: October 13, 2018, 05:19:51 pm »
I guess you are right.  An enum would be evaluated at compile time.
I don't know why I was thinking the compiler would typically create an array of values in memory.
I should know better...  :palm:
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #140 on: October 13, 2018, 08:08:08 pm »
If I remove iom4809.h will it hurt me? trying to find alternate names for definitions is getting problematic
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #141 on: October 13, 2018, 08:12:41 pm »
I guess you are right.  An enum would be evaluated at compile time.
I don't know why I was thinking the compiler would typically create an array of values in memory.
I should know better...  :palm:

I am working on the assumption that the compiler will decide that actually putting my actual functions into the code is a waste of time and will calculate the address values and stuff the value I supply into it, even done repeatedly it will be more efficient than carrying out the calculations in the resulting code.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 825
Re: [gcc C] concatenating text to make up code
« Reply #142 on: October 13, 2018, 08:49:09 pm »
Quote
The difference is that with enum the value is checked which i can see no use for

eventually, as you have already seen, you will want to slim down the defines and will end up with defines that takes an argument or more (macros)
once you start taking arguments, you have the possibility of using 'incorrect' arguments

type checking can help eliminate those type of user errors

Code: [Select]
#include <stdint.h>

//example- this is defined 'somewhere' else, included by one of my include files
//just placing it here as an example
#define TCB0 (*(volatile uint8_t *) 0x0A80)

#define TCB_BASE 0x0A80
#define TCB_COUNT_OFFSET 0x0A
#define TCB_0 0x00
#define TCB_1 0x10
#define TCB_2 0x20
#define TCB_3 0x30
#define TCB_COUNT(n) *(volatile uint16_t*)(TCB_BASE+n+TCB_COUNT_OFFSET)

uint16_t c;
void main()
{
    c = TCB_COUNT(TCB_0); //ok
   
    //if I misuse the name, we may or may not get an error
    //in this case, not, and the result will be incorrect
    //and you will never know, except you will have to eventually
    //figure it out (why is my tcb count always wrong?)
    //with typed arguments, the compiler will tell you when you use a wrong type
    c = TCB_COUNT(TCB0);
   
    for(;;);
}

/*
Quote
There are countless things you can do with macros which cannot be done without them.

I would agree some things can only be done with defines, but I would not characterize it as countless.
The problem is when people think its countless, and seek to prove it- where the result will certainly look countless as it becomes very difficult to decipher- jumping from one file to another, eventually getting to what you are looking for. I seek every opportunity to get out of the define world, although not always possible. I have drivers for every peripheral + usb for pic32mm and I have a total of 6 defines- 2 for isr declarations and 4 for usb descriptor generation- I could not come up with alternatives in those cases.

Quote
If I remove iom4809.h will it hurt me? trying to find alternate names for definitions is getting problematic
Yes if you use something inside of it. No if you do not.
If you read the top of that file, you will see that they want you to use io.h, which then includes the iomxxxx.h file for you- determined by what you have set as the target micro in the ide (typically, and propagates via an ide generated command line define).


I guess this shows you have not compiled any code with that include. If you had, you would have seen an error "Include <avr/io.h> instead of this file."

If you are not compiling any code, why not?
If you are not compiling any code, do you realize you have to at some point?
If you are not compiling any code, tell me now- so I can quit posting examples.
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #143 on: October 13, 2018, 09:01:13 pm »
I am compiling which is why I ask about iom4809.h, I have defined TCB0, TCB1, TCB2 & TCB3 as 0, 1, 2, 3, but I get a warning that these defines already exist in iom4809.h
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: [gcc C] concatenating text to make up code
« Reply #144 on: October 13, 2018, 09:04:05 pm »
You can remove it, but it is a really bad idea to not use manufacturer header files. Your code will be instantly incompatible with all other code. So someone (including you) can't just borrow a snippet of the code to be included in another project that already uses vendor header files. This practice looks like  late 90s when vendor supplied files were horrible, and thank god we are over that BS now.
Alex
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #145 on: October 13, 2018, 09:19:39 pm »
The current header files are designed for the "atmel start" bullshit and very little use to me. unless i can calculate on memory addresses as discussed earlier then nothing the manufacturer has to offer is much use.

I'm not sure how AVR code is going to run on anything else anyway, I will of course have to write a new header file of my own for any new chip with a different memory layout. I am already writing code for the largest chips in the series and they are cheap enough to not not bother with a tiny. If I have to deal with anything else it will likely be an ARM
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: [gcc C] concatenating text to make up code
« Reply #146 on: October 13, 2018, 09:26:42 pm »
The current header files are designed for the "atmel start" bullshit
Not really. Those files are the same as they were before Atmel Start. They are more of the XMega style, not the classical AVR, but still.

and very little use to me.
You are just doing thing that re not necessary in real life. But that's fine.

I will of course have to write a new header file of my own for any new chip with a different memory layout.
This is the worst idea ever. This will also make you unhireable in the industry. Or you will have to re-learn all the things for a real job. Nobody in their right mind will write custom header files. It is a huge headache.

I am already writing code for the largest chips in the series and they are cheap enough to not not bother with a tiny. If I have to deal with anything else it will likely be an ARM
ARM uses similar style of header files.
Alex
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #147 on: October 13, 2018, 09:40:10 pm »
so can i write set_output(PORT_A, PIN_1); with the iom4809.h file? once everything has been converted to text by that file how do I manipulate any input I give to match the variables assigned to the registers in text form without using a lot of C code like switch cases, in other words:

GOTO The start of this discussion!
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11236
  • Country: us
    • Personal site
Re: [gcc C] concatenating text to make up code
« Reply #148 on: October 13, 2018, 09:45:40 pm »
so can i write set_output(PORT_A, PIN_1); with the iom4809.h file? once everything has been converted to text by that file how do I manipulate any input I give to match the variables assigned to the registers in text form without using a lot of C code like switch cases, in other words:
You can, but you should reuse as many defines as possible from that file.  So you should keep it included are make sure that your own definitions don't conflict wit the standard ones. Right now it is probably not important, once you have to integrate someone else's code in your project and you run into the conflicts, you will see why it was important to not have those conflicts.
Alex
 

Online SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17814
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: [gcc C] concatenating text to make up code
« Reply #149 on: October 13, 2018, 09:49:23 pm »
How? At the moment I cannot make much sense of that file as it appears that to reference anything I have to pull together different sections that are likely to be many lines apart.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf