klauer Posted August 23, 2013 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.
shansen Posted August 23, 2013 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); }
Recommended Posts