c - 从 struct can_frame 的选项卡中检索十六进制 argv[]

标签 c arrays segmentation-fault can-bus socketcan

我正在研究 socket CAN 并实现了以下代码:

int main(int argc, char **argv)
{
char *sendSoc = NULL;
char *receiveSoc = NULL;
char specifiedType;
struct can_frame sendFrame;
struct can_frame receiveFrame;

int sendSocket=-1, receiveSocket=-1;
int can_id;
int type=-1;
int dat,k=0,iter=0, sendCount, interval;

struct can_filter sendSocket_filter;
struct can_filter receiveSocket_filter; 

unsigned long long value = 0;

if (argc < 8) 
{
    fprintf(stderr, "Usage: %s [<canSendInterface>] [<canReceiveInterface>] <id> <type> <interval(µs)> <sendCount> <can-msg>\n"
    "<id> identifier=ID CAN Identifier\n"
    "<type> type is 's' for standard and 'e' for extended frame\n"
    "<interval(us)> send message repetition rate\n"
    "<sendCount> send message COUNT times\n"
    "<can-msg> can consist of up to 8 bytes given as a space separated list - data must be in hexadecimal\n"
    "          <data0> <data1> <data2> <data3> <data4> <data5> <data6> <data7>",
    argv[0]);
    return 1;
}

sendSoc = argv[1];
receiveSoc = argv[2];

sscanf(argv[3], "%x", (unsigned int *) & sendFrame.can_id);
sendFrame.can_dlc = 8;

sendSocket_filter.can_id = sendFrame.can_id;
receiveSocket_filter.can_id = sendFrame.can_id;

sscanf(argv[4], "%c", &specifiedType);
if( specifiedType == 's')
{
    type = STANDARD;
    sendSocket_filter.can_mask = 0x000007ff;
    receiveSocket_filter.can_mask = 0x000007ff;
}   
else if( specifiedType == 'e')
{
    type = EXTENDED;
    sendSocket_filter.can_mask = 0x1fffffff;
    receiveSocket_filter.can_mask = 0x1fffffff;
}
else
{
    printf("Bad Type Entered \n");
}

interval = atoi(argv[5]);
sendCount = atoi(argv[6]);

if( (type == STANDARD) && (sendFrame.can_id > 0x7ff) ) 
{
    printf("Error: CAN-ID too big for standard frame \n");
    exit(-1);
}

if( (type == EXTENDED) && (sendFrame.can_id > 0x1fffffff) ) 
{
    printf("Error: CAN-ID too big for extended frame \n");
    exit(-1);
}

printf("here\n");

for(k=0; k<9; k++) 
{
    sscanf(argv[7+k], "%x", &dat);
    sendFrame.data[k] = (unsigned char)(dat & 0xff);
    printf("sendFrame.data[%d] vaut %d\n",k,sendFrame.data[k]);
}

printf("test\n");
return 0;

}

我系统地遇到了段错误。

基本上,我正在调用脚本 ./scriptname can0 can1 0x1ffff e 10 5 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x1E

结果是:

  LA
  sendFrame.data[0] vaut 1
  sendFrame.data[1] vaut 2
  sendFrame.data[2] vaut 3
  sendFrame.data[3] vaut 4
  sendFrame.data[4] vaut 5
  sendFrame.data[5] vaut 6
  sendFrame.data[6] vaut 7
  sendFrame.data[7] vaut 30
  Segmentation fault

在 can.h 中,结构是:

   52  * struct can_frame - basic CAN frame structure
   53  * @can_id:  the CAN ID of the frame and CAN_*_FLAG flags, see above.
   54  * @can_dlc: the data length field of the CAN frame
   55  * @data:    the CAN frame payload.
   56  */
   57 struct can_frame {
   58         canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
   59         __u8    can_dlc; /* data length code: 0 .. 8 */
   60         __u8    data[8] __attribute__((aligned(8)));
   61 };

目前我不明白为什么会出现这个Segmentation fault。目的是通过专用套接字在 CAN 上发送这些值。

提前致谢

最佳答案

使用 for 循环:

for(k=0; k<9; k++) 
{
    sscanf(argv[7+k], "%x", &dat);
    sendFrame.data[k] = (unsigned char)(dat & 0xff);
    printf("sendFrame.data[%d] vaut %d\n",k,sendFrame.data[k]);
}

您正在到达 argv[7+8] = argv[15]。但是您的命令中只有 14 个输入参数:

./scriptname can0 can1 0x1ffff  e  10   5  0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x1E
             [1]  [2]    [3]   [4] [5] [6] [7]  [8]  [9]  [10] [11] [12] [13] [14]

所以您的 argv 数组中的最后一个元素是 argv[14]

段错误来自对 argv[15] 的访问,这是一个不存在于您的 argv 数组中的元素。

您对 sendFrame.data 有同样的错误。该数组定义了 8 个元素长度并带有 for 循环

for(k=0; k<9; k++)

您正在浏览 sendFrame.data 数组的 9 个元素。这也是导致段错误的原因

关于c - 从 struct can_frame 的选项卡中检索十六进制 argv[],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27184714/

相关文章:

c - 字符串 - 数据类型

ruby-on-rails - 如何访问 Ruby splat 参数?

c - 为C中的动态 float 组赋值

arrays - VBA - 创建空数组

c - 使用 strcpy 的段错误

c - 如何避免 C 中的这种段错误?

c++ - 在没有库的情况下用 C 解析 XML。

c - 如何从c中的文件中读取结构?

c - scanf() 中的错误

c - 插入二叉树时出现段错误