微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

程序调用延迟 – C&Linux

我正在为活动假肢修复新硬件。 我的系统有一个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] 举报,一经查实,本站将立刻删除。

相关推荐