В настоящее время я работаю над микроконтроллером STM32, который связывается по последовательному каналу (UART Communication) с последовательным терминалом, установленным на моем компьютере (TeraTerm).
Я реализовал функцию на своем STM32, чье поведение такой же, как printf. Для этого я использовал va_start MACRO, va_list, vprint и va_end.
Вот различные функции:
-> printf, как (используя функцию 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