klauer Posted August 23, 2013 Share Posted August 23, 2013 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. Link to comment Share on other sites More sharing options...
shansen Posted August 23, 2013 Share Posted August 23, 2013 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); } Link to comment Share on other sites More sharing options...
Recommended Posts