c - va_start 意外行为
问题描述
我目前正在开发一个 STM32 MCU,它通过串行链路(UART 通信)与安装在我的计算机上的串行终端(TeraTerm)进行通信。
我在我的 STM32 上实现了一个函数,其行为与 printf 相同。为此,我使用了 va_start MACRO、va_list、vprint 和 va_end。
以下是不同的功能:
--> printf like(使用UART函数发送数据)
/**
* \fn APP_errors_t SER_send_multiple(char* ui8_data_p, ...)
* \brief function to send multiple data (like the printf function) via the serial link
* \param ui8_data_p, string that will be sent via serial link
* \param ... next data
* \return Any of the following values:
* SER_OK_E : if init is a success
* other : value if failure
*/
APP_errors_t SER_send_multiple(char* ui8_data_p, ...)
{
APP_errors_t ret;
va_list argp;
va_start(argp, ui8_data_p);
ret = vprint(ui8_data_p, argp);
if(ret!= SER_OK_E)
{
SER_send("Error in SER_send_multiple function\r", strlen("Error in SER_send_multiple function\r"));
}
va_end(argp);
return ret;
}
--> 函数 vprint 用于合并所有拆分的
/**
* \brief APP_errors_t vprint(const char *fmt, va_list argp)
* \param fmt This is the C string that contains the text to be written to the str
* \return Any of the following values:
* SER_OK_E : if init is a success
* other : value if failure
*/
// todo, cas ou le message à envoyer est trop grand ?
static APP_errors_t vprint(const char *fmt, va_list argp)
{
char string[SER_TX_MAX_SIZE];
if(0 < vsprintf(string,fmt,argp)) // build string
{
return SER_send(string, strlen(string));
}
// dead code
return SER_OK_E;
}
--> 上面函数调用的函数
/**
* \fn APP_errors_t SER_send(char* ui8_data_p, uint16_t ui16_size)
* \brief function to send data via the serial link
* \param ui8_data_p, string that will be sent via serial link
* \param ui16_size, number of chars that we want to send
* \return Any of the following values:
* E_OK : if init is a success
* other : value if failure
*/
APP_errors_t SER_send(char* ui8_data_p, uint16_t ui16_size)
{
if(HAL_UART_Transmit(&huart2, (uint8_t*)ui8_data_p, ui16_size, SER_SEND_TIMEOUT) != HAL_OK)
{
return SER_TRANSMIT_ERROR_E;
}
return SER_OK_E;
}
所以有什么问题 ?
在另一个函数中,我正在调用 SER_send_multiple(char* ui8_data_p, ...) 函数:
SER_send_multiple("Pin does not exist %s \r", args[OFF_PIN]);
args 是一个 char * 数组:
但在 TeraTerm 我收到:
所以MCU只是发送第一个字符。
这是所有代码(第一行只是一个测试):
SER_send_multiple("Pin does not exist : %s \r", args[OFF_PIN]);
SPCMD_arguments_T const * pins = &all_pins_a[inc];
while(ui8_found != 1 && pins->name_cmd != NULL) {
if(strcmp(args[OFF_PIN], pins->name_cmd ) == 0) {
GPIO_InitStruct.Pin = pins->value_define;
ui8_found = 1;
}
pins = &all_pins_a[++inc];
}
//uint8_t length = strlen(args[OFF_PIN]);
if(!ui8_found)
{
SER_send_multiple("Pin does not exist : %s \r", args[OFF_PIN]);
return 1;
}
最后,如果我取消注释 uint8_t length = strlen(args[OFF_PIN]); TeraTerm 正在接收:
那么那里到底发生了什么?这是一个废话,取消注释这条线不应该改变我的应用程序的行为吗?
有什么线索吗?
问候
AJT
解决方案
推荐阅读
- libgdx - 在水平组中包装标签文本(LIBGDX)
- wordpress - 账单地址作为新订单电子邮件 woocommerce 中的谷歌地图链接
- node.js - 在收到用户输入之前如何阻止?
- dart - 对于 "pubsub.stream.listen(print, onDone: (){print('done')}). " , "onDone:" 永远不会工作
- r - 时间序列月发生率
- mercurial - 如何从 hg repo 中删除变更集而不丢失之后提交的变更集
- javascript - 按字母顺序取消连续字符的资格。Sol [ASCII 格式]
- android - 识别内存泄漏
- scala - scala rdd flatmap 从一行生成多行以填充行间隙问题
- python - 知道图像中的单一 RGB 颜色,而不是 OpenCV 的范围