Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


re-directing usart to printf

I’m trying to use printf with usart 2, which is the programing port on the Nucleo401.

Using the following lines the uart2 works ok :-

char *msg = “Hello ARM\n\r”;
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 0xFFFF);

but

printf(“hello arm”);

despite compiling ok, does not.
Do I need to configures a particular uart to work with printf? If so what is the set up code?

Is it even a good idea to use printf in an embeded systems?

I’ve had headaches with getting printf working.
There are some examples under CubeMX that work for the example.
When I do the same examples under another project they don’t work, and the ST-Link doesn’t step into the function either.
When printf is connected with HAL_UART_Transmit() it pends on the charaters being sent.
With the HAL_UART_Transmit_IT(), it transmit a user supplied buffer, but its not a circular buffer, so if a 2nd printf is invoked before the first buffer is empty, it looks to me like it would fail.
Technically since its CubeMX I think the place to ask is
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspxQuestion
I’m currently trying an embedded derivative xprint and tying into a circular buffer - probably my own but another example here
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fHAL_UART_Transmit_IT%20not%20working%20as%20expected&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=42Question


Oooh, I know this one.

The 401 chip has 3 USARTS. ST, when laying out the Nucleo boards does not include a serial port connector. Therefore the choice as to
which USART should be connected to printf was never made, and was never included in the BSP.

Printf, when called, calls a bunch of other routines to get the work done. It eventually boils down to a call to _write that you can find in your
source directory in a file called syscalls.c. The _write routine itterates through the buffer that is passed to it, pulling out characters one at
a time and sending them to a routine called _ _ i o _ p u t c h a r (to show you that there are two underscores before the name).
If you click on the call to _ _io_putchar and hit F3, eclipse will send you to the declaration of the routine. It is somewhere but
there isn’t much point in looking for it, it is empty. It does nothing. It gets called and immediatly returns. The call may even get
optimized out.

But wait, if you look at the declaration, you will notice that it is a “weak” subroutine. This is something that was brought in with C99 that
tells the compiler/linker that this routine, that is declared weak, use it unless there is another one with the same name that isn’t
declared weak, in which case, use the other one instead.

You will find these weak declarations all over the HAL. These are routines that are place holders for ones that you may have to write.

So, what you need to do is provide your own _ _io_putchar routine for the printf chain to call. I suggest this:

void __io_putchar(uint8_t ch) {
	/**
	 * \brief		__io_putchar - A routine to transmit a single character out the serial port
	 * \return		void
	 * \param[in]	ch - uint8_t the character to transmit
	 * \author		andreichichak
	 * \date		Oct 16, 2015
	 * \details		This routine assumes that we will be using UART2. A timeout value of 1ms (4th parameter)
	 * 				gives a retry if the transmit buffer is full when back to back characters are transmitted,
	 * 				avoiding dropping characters.
	 */

	HAL_UART_Transmit(&huart2, &ch, 1, 1);
}


Put this at the bottom of main.c and printf will start working.

To use getc or gets, you have to write a _ _io_getchar routine. I’ll leave that to the student as an exercise.

Andrei from The Great White North (as seen on the embedded.fm podcast)





Fixed the code sections but still can’t stop the editor from bolding __io_putchar.


Oh, by the way:

before main

UART_HandleTypeDef huart2;


after main before loop

GPIO_InitTypeDef GPIO_InitStruct;
	HAL_Init(); /* Initialize the hardware abstraction layer */
	__GPIOA_CLK_ENABLE();
	/**USART2 GPIO Configuration
	 PA2     ------> USART2_TX
	 PA3     ------> USART2_RX
	 */
	GPIO_InitStruct.Pin = GPIO_PIN_2 bitor GPIO_PIN_3;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	__USART2_CLK_ENABLE();
	huart2.Instance = USART2;
	huart2.Init.BaudRate = 9600;
	huart2.Init.WordLength = UART_WORDLENGTH_8B;
	huart2.Init.StopBits = UART_STOPBITS_1;
	huart2.Init.Parity = UART_PARITY_NONE;
	huart2.Init.Mode = UART_MODE_TX_RX;
	huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	huart2.Init.OverSampling = UART_OVERSAMPLING_16;
	HAL_UART_Init(&huart2);

@Andrei: for code sections you can use `CODE()` in curly brackets like this:

{CODE()}
place your code here
{CO DE}


(but remove the blank from the closing tag)


Note that printf uses stdio and in turn do some heap allocation.

Thanks Andrei for the help. Unfortunatly no joy.
I’ve attached my code below which is pretty much the same as you suggested, just formated as CUBE likes it.
One thing to note there doesn’t appear to be a syscalls.c file in the project generated by CUBE.


Same problem :-)


Yes, i have placed syscalls.c into sources directory.

__io_putchar(int ch) is defined in main.c

But... no __io_putchar() calls when using printf();