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

0 Members and 1 Guest are viewing this topic.

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
[gcc C] concatenating text to make up code
« on: October 06, 2018, 07:24:31 pm »
So I want to create functions to set up various things. for example a function may need to be tol which input to use, but there are up to 48 inputs. Writing a switchcase every time just seems very long as it will have 48 case's.

Now for example I may use a function argument "PA5" and i may want to set it up as an input with a pullup and using my little function PA5_input_w_pullup();

Surely there is a way to add the "PA5" and "_input_w_pullup(); together and vastly sreamline the code? some sort of concatenation? but I want to do it on code not string variables.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: [gcc C] concatenating text to make up code
« Reply #1 on: October 06, 2018, 07:29:37 pm »
Use an enumeration and a look-up table.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: [gcc C] concatenating text to make up code
« Reply #2 on: October 06, 2018, 07:45:41 pm »
So I want to create functions to set up various things. for example a function may need to be tol which input to use, but there are up to 48 inputs. Writing a switchcase every time just seems very long as it will have 48 case's.

Now for example I may use a function argument "PA5" and i may want to set it up as an input with a pullup and using my little function PA5_input_w_pullup();

Surely there is a way to add the "PA5" and "_input_w_pullup(); together and vastly sreamline the code? some sort of concatenation? but I want to do it on code not string variables.

what wrong with input_w_pullup(PA5); ?
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #3 on: October 06, 2018, 07:50:13 pm »
So I want to create functions to set up various things. for example a function may need to be tol which input to use, but there are up to 48 inputs. Writing a switchcase every time just seems very long as it will have 48 case's.

Now for example I may use a function argument "PA5" and i may want to set it up as an input with a pullup and using my little function PA5_input_w_pullup();

Surely there is a way to add the "PA5" and "_input_w_pullup(); together and vastly sreamline the code? some sort of concatenation? but I want to do it on code not string variables.

what wrong with input_w_pullup(PA5); ?

It puts me back to square one, I have to look at the argument and decide what to do, this means running through all possible pins and the code to set each pin up.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #4 on: October 06, 2018, 08:02:58 pm »
Use an enumeration and a look-up table.

are enumeration and enum the same thing? enum is about variables, the problem i have is converting a variable text into code and concatenating it with other text to make the code required.
 

Offline tsman

  • Frequent Contributor
  • **
  • Posts: 599
  • Country: gb
 

Offline DC1MC

  • Super Contributor
  • ***
  • Posts: 1882
  • Country: de
Re: [gcc C] concatenating text to make up code
« Reply #6 on: October 06, 2018, 08:15:59 pm »
First of all this may be a case of "I want to X by doing Y, even if I don't know for sure if Y it's the best way to do it or if it's even possible to do X via Y"

There is some information lacking of what are you trying to accomplish but if the function code it's really so much different in between setting the different pins with/without pullups, the fastest way is to make an array of function pointers for each function and use some macro trickery to select them depending on the designators, this will work at compile time only.

If actually there are just some(how) consistent bits twidilng in some registers, the macro system of C/C++ will help you produce values for each of them in an array of whatever size the registers are.

More details are needed for a complete solution with examples.

 Cheers,
 DC1MC
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #7 on: October 06, 2018, 08:26:51 pm »
First of all this may be a case of "I want to X by doing Y, even if I don't know for sure if Y it's the best way to do it or if it's even possible to do X via Y"

There is some information lacking of what are you trying to accomplish but if the function code it's really so much different in between setting the different pins with/without pullups, the fastest way is to make an array of function pointers for each function and use some macro trickery to select them depending on the designators, this will work at compile time only.

If actually there are just some(how) consistent bits twidilng in some registers, the macro system of C/C++ will help you produce values for each of them in an array of whatever size the registers are.

More details are needed for a complete solution with examples.

 Cheers,
 DC1MC

Code: [Select]
static inline void PA0_input(){ PORTA.DIRCLR = 0x01; }
static inline void PA1_input(){ PORTA.DIRCLR = 0x02; }
static inline void PA2_input(){ PORTA.DIRCLR = 0x04; }
static inline void PA3_input(){ PORTA.DIRCLR = 0x08; }
static inline void PA4_input(){ PORTA.DIRCLR = 0x10; }
static inline void PA5_input(){ PORTA.DIRCLR = 0x20; }
static inline void PA6_input(){ PORTA.DIRCLR = 0x40; }
static inline void PA7_input(){ PORTA.DIRCLR = 0x80; }

so say i want to write a function like set_pin_as_input(); with the argument being PA0, PA1.....

At the moment I would write a switch case system calling out the appropriate code. but surely there is a way to join together the variable part: PA0" etc and "_input();"
 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2603
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #8 on: October 06, 2018, 08:30:39 pm »
At the moment I would write a switch case system calling out the appropriate code. but surely there is a way to join together the variable part: PA0" etc and "_input();"

Yes, that's what ## is for.  But you can do this much more simply.  For AVR style parts you might do something like this:

Code: [Select]
#define IO_OUTSET(...) IO_OUTSET_SUB(__VA_ARGS__)
#define IO_OUTSET_SUB(port, pin)  PORT##port |= (1<<pin)

Which you'd then use like:

Code: [Select]
IO_OUTSET(A,1);
The two levels of macros is helpful because the first macro substitution expands macros in the arguments, which allows things like this to work:

Code: [Select]
#define LED_PIN B,3
IO_OUTSET(LED_PIN);

If you tried to do that without the extra layer of indirection, the preprocessor would complain about not having enough arguments for the macro.

You can make similar macros for enabling pullups, and then do more complicated macros that do multiple things like this:

Code: [Select]
#define IO_INPUT_PULLUP(...) IO_INPUT_PULLUP_SUB(__VA_ARGS__)
#define IO_INPUT_PULLUP_SUB(port, pin)  do { \
    IO_DIR_IN(port, pin); \
    IO_PULLUP_EN(port, pin); \
} while(0);
« Last Edit: October 06, 2018, 08:35:47 pm by ajb »
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #9 on: October 06, 2018, 08:35:40 pm »
sure but i am looking at writing a function that takes multiple input arguments. so say which input pin do i want to use and which event system channel will i use. I could even throw in which counter do I want to use.
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4427
  • Country: dk
Re: [gcc C] concatenating text to make up code
« Reply #10 on: October 06, 2018, 08:36:12 pm »
So I want to create functions to set up various things. for example a function may need to be tol which input to use, but there are up to 48 inputs. Writing a switchcase every time just seems very long as it will have 48 case's.

Now for example I may use a function argument "PA5" and i may want to set it up as an input with a pullup and using my little function PA5_input_w_pullup();

Surely there is a way to add the "PA5" and "_input_w_pullup(); together and vastly sreamline the code? some sort of concatenation? but I want to do it on code not string variables.

what wrong with input_w_pullup(PA5); ?

It puts me back to square one, I have to look at the argument and decide what to do, this means running through all possible pins and the code to set each pin up.

isn't PA5 defined a something sensible? like #define PA5 GPIOA,GPIO_Pin_5

so a function like input_w_pullup((GPIO_TypeDef* port, uint32_t pin) just needs to access the right registers using the supplied pointer









 

Offline ajb

  • Super Contributor
  • ***
  • Posts: 2603
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #11 on: October 06, 2018, 08:38:53 pm »
sure but i am looking at writing a function that takes multiple input arguments. so say which input pin do i want to use and which event system channel will i use. I could even throw in which counter do I want to use.

Mostly pin numbers and event channels are either numeric subfields within registers or bits at a specific offset, so you would have to look at how the relevant registers are structured and figure out the best way to do that.  Worst case, you might need a const array to use as a lookup table or something.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #12 on: October 06, 2018, 08:49:26 pm »
Code: [Select]
static inline void PA0_input(){ PORTA.DIRCLR = 0x01; }
static inline void PA1_input(){ PORTA.DIRCLR = 0x02; }
static inline void PA2_input(){ PORTA.DIRCLR = 0x04; }
static inline void PA3_input(){ PORTA.DIRCLR = 0x08; }
static inline void PA4_input(){ PORTA.DIRCLR = 0x10; }
static inline void PA5_input(){ PORTA.DIRCLR = 0x20; }
static inline void PA6_input(){ PORTA.DIRCLR = 0x40; }
static inline void PA7_input(){ PORTA.DIRCLR = 0x80; }

Every one of those functions is exactly the same except for the value "0x01" etc. So it is very wasteful to write eight functions instead of one function with a parameter. You could do it more compactly like this:

Code: [Select]
static inline void PA_input(unsigned int pin) { PORTA.DIRCLR = pin; }

And you would call it like this:

Code: [Select]
PA_input(PA3);

In some header file you would have a definition for PA3 and others like this:

Code: [Select]
#define PA3 0x08
 

Offline ataradov

  • Super Contributor
  • ***
  • Posts: 11258
  • Country: us
    • Personal site
Re: [gcc C] concatenating text to make up code
« Reply #13 on: October 06, 2018, 08:51:49 pm »
This https://github.com/ataradov/mcu-starter-projects/blob/master/samd21/hal_gpio.h sounds exactly what you want. Obviously port this to AVR.
Alex
 

Offline martinjaymckee

  • Contributor
  • Posts: 16
Re: [gcc C] concatenating text to make up code
« Reply #14 on: October 06, 2018, 08:53:22 pm »
Macros can be made to work with more arguments if you wish.  They are rarely a good solution, however.  The question has been asked before but I will repeat it.  Why do you need the code to work this way?  It is clear (and certainly reasonable!) that you want to get away from using a massive switch statement to handle this.  What isn't clear, however, is why that would be a problem.  When at all possible, I prefer to avoid macros because they happen only on text before the compiler sees the program.  That can lead to annoying bugs and inconsistency in how the code works.  Still, they would work here -- either as ,
Code: [Select]
input_w_pullup(PA5);or as something like,
Code: [Select]
input_w_pullup(PORTA, 5);Actually, these could be easily implemented as static inline functions and have the same cost as a macro.

I usually code in C++ and handle the same thing by wrapping the port/pin in a class.  That way I can pass them around as one piece of data.  This works just fine in pure C too (as it may look for an AVR).  It takes a bit of work to get the compiler to see that it can remove all the abstraction cost though.  So just immediate functions might be preferable.

I would look very closely at the comments by IanB and ajb.  They are pointing you in a good direction as they are showing how you can make a function handle multiple situations without a massive switch/case statement.  Even if it takes some math to calculate offsets or something, trust the compiler.  They are exceptionally good these days.  You'd be surprised what it can figure out it doesn't need.

Cheers,
Martin Jay McKee
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [gcc C] concatenating text to make up code
« Reply #15 on: October 06, 2018, 09:53:31 pm »
C is next to useless for meta-programming (code that generates code). If you really want to do this, the best way might be to write a program or script to generate the C source you need, and incorporate running that into your Makefile or build scripts.

I would question the motivation for wanting to do this. It seems like a square peg for a round hole, and in a few months you will be wondering why you did this.

The pnly use case I can see would be if you needed to log or breakpoont when the register gets changed, or it you wanted to have a 'shadow register' that can be read when the underlying hardware register is write-only, or a read causes undesirable side effects.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: [gcc C] concatenating text to make up code
« Reply #16 on: October 06, 2018, 10:51:06 pm »
There's an important distinction based on when the "PA5" becomes known.

If it is known at compile time, you create a macro or a set of macros and use one of them. Or you just write code directly.

If it only becomes known at run time, you think of a data type or structure which would best hold "PA5" then you write a single function which accepts the data of such type and produces the desired action(s).

Either way, you don't need 50 different functions.
 

Offline TK

  • Super Contributor
  • ***
  • Posts: 1722
  • Country: us
  • I am a Systems Analyst who plays with Electronics
Re: [gcc C] concatenating text to make up code
« Reply #17 on: October 06, 2018, 11:03:23 pm »
sure but i am looking at writing a function that takes multiple input arguments. so say which input pin do i want to use and which event system channel will i use. I could even throw in which counter do I want to use.
What you can do is to assign each argument a weight in binary (1, 2, 4, 8, 16, and so on) and use AND / OR operators to separate them inside the function, so you can pass only 1 argument.

Something like:
Code: [Select]
#define PA0 b00000001
#define PA1 b00000010
#define PA2 b00000100
#define PA3 b00001000
#define PA4 b00010000
#define PA5 b00100000
#define PA6 b01000000
#define PA7 b10000000

void function(arg) {
    if (arg & PA1) {
        do something
}

void main() {
    argument = PA1 | PA5;
    function(argument);
}
 

Offline sleemanj

  • Super Contributor
  • ***
  • Posts: 3024
  • Country: nz
  • Professional tightwad.
    • The electronics hobby components I sell.
Re: [gcc C] concatenating text to make up code
« Reply #18 on: October 06, 2018, 11:05:27 pm »
Maybe something like (note using typeof GCC extention since I don't know what the type of PORTA is, maybe you'd have to jiggle about with that to work out what works)...

Code: [Select]
  // Note that you must declare it first, at least in my experiment, otherwise GCC will complain about type mismatch
  void inputMode( typeof (PORTA) &thePort, uint8_t thePin );

  void inputMode( typeof (PORTA) &thePort, uint8_t thePin )
  {
     thePort.DIRCLR = 1<<thePin;
  }

  ...

  inputMode(PORTA, 1);

~~~
EEVBlog Members - get yourself 10% discount off all my electronic components for sale just use the Buy Direct links and use Coupon Code "eevblog" during checkout.  Shipping from New Zealand, international orders welcome :-)
 

Offline donotdespisethesnake

  • Super Contributor
  • ***
  • Posts: 1093
  • Country: gb
  • Embedded stuff
Re: [gcc C] concatenating text to make up code
« Reply #19 on: October 06, 2018, 11:05:56 pm »
It's funny how people hate on Arduino's inefficient digitalWrite() then get stuck trying to write a better one.

Micros are fast, it doesn't usually matter if you need a switch statement, unless you need to bitbang serial comms at high speed. You can go to great lengths with preprocessor trickery, code generators, are macros which generate C++ templates but is it really worth it.

However, if you want an efficient preprocessor solution, have a look at the way Marlin does it.
Bob
"All you said is just a bunch of opinions."
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #20 on: October 07, 2018, 07:22:09 am »
It's funny how people hate on Arduino's inefficient digitalWrite() then get stuck trying to write a better one.

Micros are fast, it doesn't usually matter if you need a switch statement, unless you need to bitbang serial comms at high speed. You can go to great lengths with preprocessor trickery, code generators, are macros which generate C++ templates but is it really worth it.

However, if you want an efficient preprocessor solution, have a look at the way Marlin does it.

Yes funny enough I am back there. I want to write a function where I set up a counter to measure PWM, so i need at the very least to determine which pin I am using as an input and which event channel i am using (ATmega 0-series)
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #21 on: October 07, 2018, 07:38:35 am »
I take it I can use string variables to put a bit of text in? As the compiler is efficient this will all come out anyway in optimisation. The idea is to simplify program writing.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: [gcc C] concatenating text to make up code
« Reply #22 on: October 07, 2018, 08:03:35 am »
I take it I can use string variables to put a bit of text in? As the compiler is efficient this will all come out anyway in optimisation. The idea is to simplify program writing.
Unless a variable is guaranteed to never be written to - which means it is declared as static (so it has no external linkage) & const (so it can never be changed) the compiler will not be able to optimize anything away. When it comes to string constants I'm pretty sure it will not be optimized away - for example the checksum for a constant string can be calculated at compile time, but I doubt that a compiler will optimize "cksum = checksum(my_constant_string);" away and replace it with a constant.

Sometimes you can jump though hoops and use "inline" functions to widen the scope of constant propagation, but it really bad form to plan on this working.

A C program's executable code is 'frozen' when it is compiled and linked - it usually ends up in a read-only segment of memory, or written to a controller's flash in the case of microcontrollers like most Arduino variants. So anything that makes new code on the fly is out.

An aside: This makes me recall, that In the '80s my standard 'speed test' for scientific pocket calculators was to calculate factorial(69) - they should have just used a 70 entry lookup table :-)
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 11885
  • Country: us
Re: [gcc C] concatenating text to make up code
« Reply #23 on: October 07, 2018, 09:08:58 am »
I take it I can use string variables to put a bit of text in? As the compiler is efficient this will all come out anyway in optimisation. The idea is to simplify program writing.

Not in the way you are thinking, not unless you use the C preprocessor as indicated higher up the thread.

I do think you are somehow barking up the wrong tree here. "Concatenating text to make up code" is not the solution to problem you are trying to solve.

Instead of this, you should be thinking of function parameters and various operations in involving bit patterns like shifting, AND'ing and OR'ing them together. In the computer's world the "text" that needs concatenating is groups of bits, not human letters and numbers.
 

Offline SimonTopic starter

  • Global Moderator
  • *****
  • Posts: 17816
  • 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 #24 on: October 07, 2018, 09:46:44 am »
So I am plunging into the switch statements. Some will be hummungus, this in itself does not concern me as I know the compiler will strip out the unused stuff. But it will take a while to write, is there a clever program out there that manipulates text that I can use to generate the mundane stuff?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf