Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我需要在嵌入式系统中以十六进制形式打印可变数量的字符以进行调试_C_Printf_Hexdump - Fatal编程技术网

C 我需要在嵌入式系统中以十六进制形式打印可变数量的字符以进行调试

C 我需要在嵌入式系统中以十六进制形式打印可变数量的字符以进行调试,c,printf,hexdump,C,Printf,Hexdump,在C语言中,我需要在嵌入式系统中以十六进制形式打印可变数量的字符以进行调试。因为这是调试跟踪宏的一部分,所以我希望避免printf无法处理的循环或其他逻辑。我也不想声明任何新的变量来防止Heisenbug问题。输出空间也是一个问题,所以我想以十六进制格式转储它 uint8_t* buffer; uint8_t length; MakeString(*message, &buffer, &length); //Function that puts some values in

在C语言中,我需要在嵌入式系统中以十六进制形式打印可变数量的字符以进行调试。因为这是调试跟踪宏的一部分,所以我希望避免
printf
无法处理的循环或其他逻辑。我也不想声明任何新的变量来防止Heisenbug问题。输出空间也是一个问题,所以我想以十六进制格式转储它

uint8_t* buffer;
uint8_t length;

MakeString(*message, &buffer, &length);  //Function that puts some values in buffer and sets length
我正在寻找一个printf,它可以使用缓冲区和长度来生成如下内容:

0x1A1B1C0A02
对于{1A,1B,1C,0A,02}和长度=5的值

我知道
%.*s
%*
可以处理大小变量。没有for/while循环,有没有办法做到这一点

我想你可以挂起一些串口缓冲区emoty中断,从缓冲区读取一个字节,然后在串口上发出两个字节。。。没有循环本身

或者做这样卑鄙的事情(这个例子只对长度0到10有效)

int printbuf(无符号字符*缓冲区,int长度)
{

#定义b(x)buffer[x我过去使用过如下内容:

void
to_hex(char *output, size_t out_len, uint8_t const *input, size_t in_len)
{
        static const char digits[] = "0123456789abcdef";
        if (out_len < 1) {
                return;
        }

        --out_len; /* reserve space for that NUL terminator */
        while (out_len > 1 && in_len) {
                *output++ = digits[(*input & 0xF0) >> 4];
                *output++ = digits[*input & 0x0F];
                out_len -= 2;
                ++input, --in_len;
        }
        if (in_len) {
                *output++ = digits[(*input & 0xF0) >> 4];
        }
        *output = '\0';
}
void
到十六进制(字符*输出,大小输出,单位8常量*输入,大小输入)
{
静态常量字符位数[]=“0123456789abcdef”;
如果(输出长度<1){
返回;
}
--out_len;/*为NUL终止符保留空间*/
while(out\u len>1和in\u len){
*输出++=数字[(*输入&0xF0)>>4];
*输出++=位数[*输入&0x0F];
out_len-=2;
++输入,-in_len;
}
如果(以英语){
*输出++=数字[(*输入&0xF0)>>4];
}
*输出='\0';
}
它使用的唯一内存是静态和常量,因此通常在BSS中分配。如果您有一个内存映射输出设备,那么您可以简化此操作,省略输出缓冲区并直接写入内存位置。您可以对此进行更多优化,并将其隐藏在宏后面,以便在发布版本中省略它


我工作过的系统没有
printf
sprintf
实现,因此我们通常使用自己的十六进制转储代码。

消息的类型是什么?它的长度是如何确定的?作为替代,您可以编写自己的“带循环的复杂函数”在单独的.c文件中,然后使用宏来调用它。在调试版本中,宏必须调用函数,而在发布版本中,它不能执行任何操作。除非您使用的是电路内硬件模拟器,否则无法避免海森堡。如果您在错误代码中添加任何内容,则可以消除bug在其他地方,或者将其作为一个良性错误。您可能不想声明新变量,但不会避免使用堆栈。@MarkShevchenko函数参数是局部变量我猜他在那里时错过了
。@Jasen…当这也被接受时,我很惊讶。如果您分析n输入长度。
void
to_hex(char *output, size_t out_len, uint8_t const *input, size_t in_len)
{
        static const char digits[] = "0123456789abcdef";
        if (out_len < 1) {
                return;
        }

        --out_len; /* reserve space for that NUL terminator */
        while (out_len > 1 && in_len) {
                *output++ = digits[(*input & 0xF0) >> 4];
                *output++ = digits[*input & 0x0F];
                out_len -= 2;
                ++input, --in_len;
        }
        if (in_len) {
                *output++ = digits[(*input & 0xF0) >> 4];
        }
        *output = '\0';
}