Jump to content
OMRON Forums

Recommended Posts

Posted

I'm trying to get a user phase routine setup outside of the IDE. I've cross-compiled and inserted the module into the kernel, with the help of this useful bit of information from hbausley in another thread:

 

If you wanted to do your own seperate kernel module and wanted a particular function callable by the phase routine. You would need to EXPORT_SYMBOL the function you wanted callable and Force the address of your function into UserAlgo.PhaseAddr[] with a c application. Once your kernel module is loaded ie. with a insmod yourdrv.ko you could do a cat /proc/kallsyms | grep your_function and you will see what the address of your function is.

 

I have the address of the function. Now how do I set a specific motor to use that phase algorithm?

 

Thanks in advance.

  • Replies 1
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

Posted

klauer:

 

The variables you need to access are read-only in the terminal (gpascii), so you need to write a C program to load your module function. Here are some modified functions that I wrote for this purpose.

 

If you have the address and want to load it, use load_isr_function_from_addr(). Alternatively, you can use load_isr_function() which will find the address for you (based on the function name you supply) and then load it. After your code is loaded, use enable_isr() to start executing your code!

 


unsigned int find_isr_function( const char *functionName )
{
   FILE *fp;
   char *tail;
   char cmd[64];
   char result[128];
   unsigned long addr = 0x00;

   if( !functionName ) return -1;
   if( !pshm ) return -1;

   strcpy(cmd, "cat /proc/kallsyms | grep ");
   strcat(cmd, functionName);

   fp = popen(cmd, "r");
   if( !fp ) return -1;

   while( fgets(result, 127, fp) )
   {
   }

   pclose(fp);

   // if result == cmd, we didn't get a response
   if( strcmp(result, cmd) == 0 ) return -1;

   tail = strchr(result, ' ');
   addr = strtoul(&result[0], &tail, 16);
   return addr;

   return 0;
}

int disable_isr( unsigned char isr )
{
   struct timespec time = { .tv_sec = 0, .tv_nsec = 10000000 };

   if( !pshm ) return -1;
   pshm->Motor[isr].PhaseCtrl = 0;  // stop executing user phase interrupt
   nanosleep(&time, NULL);          // wait 10ms (arbitrary) for ISR to stop executing

   return 0;
}

int enable_isr( unsigned char isr )
{
   if( !pshm ) return -1;

   pshm->Motor[isr].PhaseCtrl = 1;  // start executing phase code

   return 0;
}

int load_isr_function_from_addr( unsigned int addr, unsigned char isr )
{
   // no need to validate ISR because maximum value of unsigned char is 255

   if( disable_isr(isr) < 0 ) return -1;

   pshm->Motor[isr].UserPhase = (PUserCtrl) addr;
   pshm->UserAlgo.PhaseAddr[isr] = addr;

   return 0;
}

int load_isr_function( const char *functionName, unsigned char isr )
{
   if( !functionName || functionName[0] == '\0' ) return -1;
   unsigned int addr = find_isr_function(functionName);
   if( addr == 0x00 ) return -1;

   return load_isr_function_from_addr(addr, isr);
}

Guest
This topic is now closed to further replies.

×
×
  • Create New...