2021-01-19 02:32 AM
Hi,
I'm trying to run some code on the STM32H735G Development Kit.
When simply generating a new firmware in CubeMx (v6.1.1), printf doesn't seem to want to work out of the box and the system hangs. I disable FDCAN init and OCTOSPI init and it can at least start up.
I'm using UART3 and added an `__io_putchar` implementation but that makes no difference.
It's only when I add an implementation for `int puts(const char* str)` that printf somewhat works: I can do `printf("text")` but not `printf("num: %d", 5)`.
I guess some stdio binary is not being linked in.
Thanks.
2021-01-19 06:08 AM
Hi @Arno ,
Could please share your .ioc file ?
Thanks!
2021-01-19 06:25 AM
Hi Houssem,
Here is the IOC file I use.
Also, here is the code I added to get output:
in usart.c:
int __io_putchar(int c)
{
HAL_UART_Transmit(&huart3, (uint8_t *)&c, 1U, 0xFFFFU);
return c;
}
int putchar(int c)
{
HAL_UART_Transmit(&huart3, (uint8_t *)&c, 1U, 0xFFFFU);
return c;
}
int puts(const char* str)
{
static const char eol[2] = { '\r', '\n' };
int ctr = 0;
while ((str[ctr] != '\0') && (ctr < 128)) {
HAL_UART_Transmit(&huart3, (uint8_t *)&str[ctr], 1U, 0xFFFFU);
ctr++;
}
HAL_UART_Transmit(&huart3, (uint8_t *)&eol[0], 1U, 0xFFFFU);
HAL_UART_Transmit(&huart3, (uint8_t *)&eol[1], 1U, 0xFFFFU);
return 0;
}
The `puts` and `putchar` implementations should not be needed but they are part of my experiments to get some output.
This is what I changed in main:
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC2_Init();
MX_ADC3_Init();
MX_DAC1_Init();
// MX_FDCAN1_Init();
// MX_FDCAN2_Init();
MX_I2C4_Init();
MX_LTDC_Init();
// MX_OCTOSPI1_Init();
// MX_OCTOSPI2_Init();
MX_SAI1_Init();
MX_TIM1_Init();
MX_TIM4_Init();
MX_TIM5_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_USB_OTG_HS_USB_Init();
MX_RNG_Init();
MX_ETH_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
puts("____________________");
while (1)
{
HAL_GPIO_TogglePin(USER_LED1_GPIO_Port, USER_LED1_Pin);
bool button_val = HAL_GPIO_ReadPin(USER_BUTTON_Port, USER_BUTTON_Pin);
HAL_GPIO_WritePin(USER_LED2_GPIO_Port, USER_LED2_Pin, button_val);
printf("printf\r\n");
printf("printf num %d\r\n", 5);
puts("puts");
putchar('c');
putchar('\r');
putchar('\n');
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
2021-01-20 05:29 AM
Weirdly, sprintf and vsprintf do work.
I tried implementing my own printf which works but still strange why printf specifically does not work.
The solutions in this discussion:
https://community.st.com/s/question/0D50X0000AuqfAaSQI/how-to-redirect-printf
did not work (fflush, '\n' and setvbuf) either.
Here is my implementation:
#define STDOUT_BUFFER_SIZE 128
int __io_putchar(int c)
{
HAL_StatusTypeDef sts = HAL_UART_Transmit(&huart3, (uint8_t*)&c, 1U, 0xFFFFU);
return (sts == HAL_OK) ? c : EOF;
}
static int putstr(const char* str)
{
int ctr = 0;
while ((str[ctr] != '\0') && (ctr < STDOUT_BUFFER_SIZE)) {
if (__io_putchar(str[ctr]) == EOF) {
return EOF;
}
ctr++;
}
return ctr;
}
int printf(const char* format, ...)
{
char buffer[STDOUT_BUFFER_SIZE] = { };
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
return putstr(buffer);
}
2021-01-26 04:48 AM
Turns out that generating the project for STM32CubeIDE (v1.5.1 here) does work with printf support. However when generating a makefile project with the exact same code it does not.
Weirdly also, generating for CubeIDE gives us 2 linker scripts: STM32H735IGKX_FLASH.ld, STM32H735IGKX_RAM.ld (only xx_FLASH is used by CubeIDE)
but when generating a Makefile project you get one: STM32H735IGKx_FLASH.ld (notice the lowercase x in the name as opposed to an uppercase X).
These are also somewhat different.
The makefile is missing the files sysmem.c and syscall.c.
Update:
It now works, used wildcard for Core/Src, this seems to solve it