Troubles with multiple functions in a component
sudo comp --install orient.comp
make KBUILD_EXTRA_SYMBOLS=/usr/realtime-2.6.32-122-rtai/modules/linuxcnc/Module.symvers -C /usr/src/linux-headers-2.6.32-122-rtai SUBDIRS=`pwd` CC=gcc V=0 modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-122-rtai'
CC [M] /tmp/tmpSForP8/orient.o
orient.comp:110: warning: function declaration isn’t a prototype
orient.comp: In function ‘shift_the_transmission’:
orient.comp:113: error: implicit declaration of function ‘orient_the_spindle’
orient.comp: At top level:
orient.comp:182: warning: function declaration isn’t a prototype
orient.comp:181: warning: conflicting types for ‘orient_the_spindle’
orient.comp:113: note: previous implicit declaration of ‘orient_the_spindle’ was here
orient.comp:249: warning: function declaration isn’t a prototype
orient.comp:264: warning: function declaration isn’t a prototype
orient.comp: In function ‘run_the_spindle’:
orient.comp:338: error: invalid storage class for function ‘_’
orient.comp:337: warning: ISO C90 forbids mixed declarations and code
orient.comp:444: error: invalid storage class for function ‘__comp_get_data_size’
orient.comp:444: error: expected declaration or statement at end of input
orient.comp:444: error: expected declaration or statement at end of input
orient.comp:444: error: expected declaration or statement at end of input
make[2]: *** [/tmp/tmpSForP8/orient.o] Error 1
make[1]: *** [_module_/tmp/tmpSForP8] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-122-rtai'
make: *** [modules] Error 2
Am I trying to do something beyond the scope of a component? There is no info in the comp section of the hal manual on multiple functions in a component. Help, please....Thanks,
JR
Please Log in or Create an account to join the conversation.
I have had problems trying to hive off sections of code into other functions before, albeit it compiled OK.
I put a truth table into a function to save repeating it 3 times and it did not work. Repeat the code at appropriate stages and it worked fine.
There are some other issues,
you are testing a bit pin for an integer value above 1
the FUNCTION(_) switch code has no breaks between values, so it will run through the whole lot to the end from wherever the switch value is
What I suggest you do is have a proper state machine within FUNCTION(_)
Each value does something, resets the state value and returns. Next time it does whatever that state value requires, resets to next value and returns etc etc
It seems rather cumbersome looking at the code, but only one case nnnn: is ever executed at one time and then it breaks, waiting for the next thread poll, so it is just a long list.
Attached is a copy with just the FUNCTION(_) left in, references to functions commented out and bit pin changed to s32
This compiles.
What you need to do is have a seperate progress_index value that determines the switch level you are at, instead of orient_cond which just relates to that state, substitute the function calls for
further cases in the switch statement
These can be broken up into seperate stages, don't want a case: to contain another switch(), want it to do something, set a new progress_level and return as quickly as possible.
regards
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
It seemed to make more sense to break it into subroutines, or functions.
Normally it does, there is something about the way rt components run that seems to often screw it up if you have seperate functions being called from within the main routine
I started realizing I was constantly repeating rhe same code over and over.
There are many ways to skin a cat.
What I did on a toolchanger that had electromechanical and pneumatic components, which required a different delay to ensure they were engaged before continuing, was have 2 progress_levels which held the delays required.
When I needed a delay, I set the progress_level to the one required and set another variable return_level to where I wanted to return to afterwards.
Thus 6 different levels could use the same delay code then return back to the next level to continue the sequence.
FUNCTION(_)
{
switch (progress_level)
{
.
.
case 5: // rotate back to original place
if(position_cmd < position_req )
break;
return_level = 27; // you can return to wherever you want after the routine finishes, makes it very flexible
progress_level = 26;
break;
.
.
.
case 25: //
if(delay_index < shortdelay)
{
delay_index++;
break;
}
delay_index = 0;
progress_level = return_level;
break;
case 26:
if(delay_index < extralongdelay)
{
delay_index++;
break;
}
delay_index = 0;
progress_level = return_level;
break;
case 27: // special level only for initial toolnumber setting on startup
toolposition = starttool;
update = 1;
toolchanged = 1;
progress_level = 6;
break;
case 30:
break; // should never get here but if we do then loop endlessly doing nothing
default:
progress_level = 30;
rtapi_print_msg(RTAPI_MSG_ERR, "Unsupported state in triacchanger - now disabled - unload triacchanger");
}
}
I left the breaks out of the main part of the comp so it would fall thru to what ever was being asked of it. It seemed easier then endless if-else's.
The main thing you need to do in a rt component is get done and return as soon as possible.
Unfortunately a switch() directs flow to the case nnn: that matches the variable, like a position on a ladder.
Once that 'rung of the ladder' is complete, unless there is a break; to exit the switch(), the execution continues to the cases below it, moving down the rungs of the ladder as it were.
Normally there is also a default: which is a catchall to trap any out of range values etc and warn or abort as req (as per the example
regards
Please Log in or Create an account to join the conversation.
i get the following errors:
It is often helpful to look at the C-code that comp creates to see what is happening.
The problem is probably that your function declarations need a (void) in the argument list.
Please Log in or Create an account to join the conversation.
How do I do this, just void in the parentheses?
void my_func (void) ??
Thanks. I also suspect the declaration error will go away if the functions are listed in a different order, apparently you cant call a function before it is defined Thanks again.
JR
Please Log in or Create an account to join the conversation.
orient.comp:444: error: invalid storage class for function ‘__comp_get_data_size’
This is the error relating to different declarations of prototype and function, the missing void Andy mentioned.
You had a missing closing bracket to one of the functions, can't remember which, which I think is throwing a peculiar error to do with this final function, because it is seen as being within another unterminated function.
I also suspect the declaration error will go away if the functions are listed in a different order, apparently you cant call a function before it is defined
C traditionally has the functions listed above main() and thus they are declared before used, but even so they must be in the right order, no ref to func 2 in func 1 when func2 has not been declared.
Is often much easier to prototype the function after the includes and then they can be anywhere.
regards
Please Log in or Create an account to join the conversation.
I had some time last nite to get back to the errors I had been getting. I rearranged the functions in order, added void to the argument list(thanks Andy), found a curly bracket that was backwards and it compiled. I attached it below in case any one is interested in the format that worked for me. This component is still being fine tuned. Thanks for everyones help. Upward and onward...
JR
Please Log in or Create an account to join the conversation.
I'm afraid that it may compile but can't see how it would work.
You have a main loop function FUNCTION(_) which contains 4 other functions.
The functions should be external to the main loop
I have re-written it with prototypes to allow forward declaration of the functions, thus they can be below the main loop without throwing errors
Also if you try to compile it you get this warning
orientw.comp: In function ‘shift_the_transmission’:
orientw.comp:182: warning: case label value exceeds maximum value for type
orientw.comp:188: warning: case label value exceeds maximum value for type
orientw.comp:195: warning: case label value exceeds maximum value for type
orientw.comp:213: warning: case label value exceeds maximum value for type
orientw.comp:226: warning: case label value exceeds maximum value for type
This is because you are switching a bit value (0 or 1) and testing it for integer values between 18 and 22
param rw bit shift_trans; // condition of transmission
I changed it to s32.
I have changed the name of the component to orientw, as the name must be the same as the file name or you get problems.
The new file compiles, but I cannot test it on this system at present
Hope it helps
regards
Please Log in or Create an account to join the conversation.
JR
Please Log in or Create an account to join the conversation.