我正在为活动假肢修复新硬件。 我的系统有一个BeagleBone Black RevCembedded式计算机和一些定制板。 BeagleBone Black(BBB)运行Debian Linux。
我写了一个C控制台应用程序来从Linux的其他董事会。 在terminal上,我可以发送类似“./plan execute_1 set_pid_gains 10 50 0”的命令来改变在我的电机驱动器上运行的控制回路的增益。 “计划”function是用C编写的,它通过SPI发送消息。
程序可以正常工作,我可以发送所有我想要的命令。 但是,当我们从Python开始testing(使用Popen调用C程序)时,我们意识到它并没有像我们想要的那样快。
为了复制和隔离问题,我编写了一个在我的networking上发送3个命令的shell脚本(fxa_test_z_1):
beaglebone黑色gpioselect不工作
如何在BeagleBoneBlack上启用和使用SPI
整合WiFiencryption狗与Beaglebone黑色问题
设备树中使用什么“兼容”键?
libphy:PHY 4a101000.mdio:01在Beagleboneblack中找不到
#!/bin/bash # Places FlexSEA in Impedance control mode # Use with care! # Set control mode to 'z' (4) ./plan execute_1 set_control 4 # Current loop gains: ./plan execute_1 set_current_gains 10 50 0 # Choose from one of these: ./plan execute_1 set_z_gains 1 0 0 echo "FlexSEA in Stiffness mode"
每个function之间有14ms的延迟(用示波器测量)。 我跑了很多小实验来隔离这个问题。 打开和closuresspI端口,发送SPI命令和parsingagv []不是问题。 如果我在同一个程序调用中多次调用它们,则每个串行数据包之间的延迟时间大约为700us。
调用“nice -n -19 ./fxa_test_z_1”并没有改变任何东西。
==
我能做些什么来使这些函数调用更快? 有没有希望我可以让他们去亚MS?
现在我试图避免对我的代码做重大的修改,因为我们想明天testing我们的控制循环。
谢谢!
杰夫
gstreamerstream式传输到Nginx rtmp服务器
准确的Beagle Bone Black计时器中断?
如何交叉编译Openwrt的.c文件?
Linux相当于Windows的“启动”文件夹
本地库bluecove_arm不可用
在plan再次运行之前,您可以让plan做更多的工作来加快速度。 开始一个过程是一个很大的工作,所以你不想经常做这个事情。
为了让plan做更多的工作,可以在stdin或者文件中给它一个命令列表。 棘手的部分然后解析每一行来提取单独的命令和参数。 由于你现有的代码已经从argv读取命令,所以使用strtok将命令解析成类似argv的数组是很容易的:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_COMMAND_LEN 256 #define MAX_ARGS 64 char *fake_argv[MAX_ARGS]; /* For compatibility with existing parser. */ const char *delims = " n"; int main(int argc,char *argv[]) { char command[MAX_COMMAND_LEN]; while( fgets(command,sizeof(command),stdin) ) { int fake_argc = 0; fake_argv[fake_argc] = strtok(command,delims); while( fake_argv[fake_argc] != NULL ) { fake_argv[++fake_argc] = strtok(NULL,delims); } { int i; /* debug print... you can remove this block */ printf("Handling command: [%s],argc %dn",command,fake_argc); for( i = 0; i < fake_argc; ++i ) { printf(" arg: [%s]n",fake_argv[i]); } } /* ... do the stuff you were already doing except Now with fake_argv */ } return 0; }
然后,你的bash脚本可以只是一组线,你喂你的程序:
./plan << END_COMMAND_LIST execute_1 set_control 4 execute_1 set_current_gains 10 50 0 execute_1 set_z_gains 1 0 0 END_COMMAND_LIST
现在plan过程被创建一次,并在退出之前运行3个命令。
我把个人的代码和我的main()合并在一起,它可以工作,我可以每760us发送一个新的命令(比以前快18倍!)
我的代码可能没有那么优雅,但其他人可能从一个完整的解决方案中受益,所以这里是:
//**************************************************************************** // main: FlexSEA Plan project: console app to control FlexSEA slaves //**************************************************************************** //**************************************************************************** // Include(s) //**************************************************************************** #include <stdio.h> #include <stdlib.h> #include <string.h> #include "../inc/flexsea_console.h" #include "../inc/plan_spi.h" #include "flexsea_local.h" //**************************************************************************** // Local variable(s) & deFinitions //**************************************************************************** int analog0 = 0; //Choose between single multiple commands console app: //#define SINGLE_COMMAND #define MULTIPLE_COMMANDS #ifdef SINGLE_COMMAND #ifdef MULTIPLE_COMMANDS #error "Pick one Command option!" #endif #endif #define MAX_COMMAND_LEN 256 #define MAX_ARGS 8 char *fake_argv[MAX_ARGS]; const char *delims = " n"; //**************************************************************************** // External variable(s) //**************************************************************************** extern unsigned char execute_1_data[]; //**************************************************************************** // Function(s) //**************************************************************************** int main(int argc,char *argv[]) { #ifdef MULTIPLE_COMMANDS char command[MAX_COMMAND_LEN]; char string1[20],string2[20] = "quit"; char default_argv[] = ""; int i = 0; #endif //MULTIPLE_COMMANDS //Open SPI: flexsea_spi_open(); #ifdef MULTIPLE_COMMANDS while(fgets(command,stdin)) { int fake_argc = 1; //Fills fake_argv with empty strings to avoid sending old values with new commands for(i = 0; i < MAX_ARGS; i++) { fake_argv[i] = default_argv; } //First argument fake_argv[fake_argc] = strtok(command,delims); //Other arguments while( fake_argv[fake_argc] != NULL ) { fake_argv[++fake_argc] = strtok(NULL,delims); } //Enable for terminal debug only: /* for(i = 0; i < MAX_ARGS; i++) { printf("fake_argv[%i] = %sn",i,fake_argv[i]); } */ //Do we want to exit? (exit when "quit" is received) strcpy(string1,fake_argv[1]); if(!strcmp(string1,string2)) { printf("Quitting.n"); break; } else { //Parser for console commands: flexsea_console_parser(fake_argc,fake_argv); //Can we decode what we received? decode_spi_rx(); } } #endif //MULTIPLE_COMMANDS #ifdef SINGLE_COMMAND //Parser for console commands: flexsea_console_parser(argc,argv); //Can we decode what we received? decode_spi_rx(); #endif //SINGLE_COMMAND //Close SPI: flexsea_spi_close(); return 0; }
我的测试shell脚本是:
#!/bin/bash # How quickly can we send serial commands? ./plan << END_COMMAND_LIST execute_1 set_leds 0 255 0 0 execute_1 set_leds 0 255 0 0 execute_1 set_leds 0 255 0 0 execute_1 set_leds 0 255 0 0 execute_1 set_leds 0 255 0 0 END_COMMAND_LIST
非常感谢您的帮助!
杰夫
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。