When I used the mps2-an385 model on QEMU, I found that I can’t use getchar() function to receive input string from terminal, however the printf() is normal , when I try to create a task to use getchar(), something error occured as the following:
qemu: fatal: Lockup: can’t escalate 3 to HardFault (current priority -1)
Is that means this model can’t support using UART to receive strings input from the terminal? If not, which function in FreeRTOS should I use?
Hi @lishihong-1,
Unfortunately I cannot comment on the MPS2-AN385 models ability to do UART input… The FreeRTOS-Kernel does not handle UART. It’s possible using getchar is causing a hard fault because it is not threadsafe. Try encapsulating the call in a critical section (taskENTER_CRITICAL(); getchar(); taskEXIT_CRITICAL()). You could try creating a program that does not have FreeRTOS at all and just echos back input as output as in just a main function that calls getchar putchar in a while(1) loop.
In fact, I try to modify the main_blinky.c directly, the code is shown below:
#include <stdio.h>
#include <string.h>
/* UART 输入缓冲区大小 */
#define UART_BUFFER_SIZE 100
int main_blinky(void)
{
char cInputBuffer[UART_BUFFER_SIZE];
size_t xIndex = 0;
int c;
printf("UART Input Program Started. Type something and press Enter:\r\n");
while (1)
{
/* 使用 getchar() 接收字符 */
c = getchar();
if (c != EOF) /* 检查是否接收到有效字符 */
{
if (c == '\r' || c == '\n') /* 检测到回车键 */
{
cInputBuffer[xIndex] = '\0'; /* 添加字符串结束符 */
printf("Received: %s\r\n", cInputBuffer); /* 输出接收到的字符串 */
xIndex = 0; /* 重置缓冲区索引 */
}
else if (xIndex < UART_BUFFER_SIZE - 1)
{
cInputBuffer[xIndex++] = (char)c; /* 存储字符到缓冲区 */
}
}
}
return 0;
}
then the qemu terminal report this: Calling prvGetRegistersFromStack() from fault handler
Should I need to adjust the UART configuration in main.c, or use some ISR function to operate UART receive? The UART configuration is shown below:
#define UART0_ADDRESS ( 0x40004000UL )
#define UART0_DATA ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 0UL ) ) ) )
#define UART0_STATE ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 4UL ) ) ) )
#define UART0_CTRL ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 8UL ) ) ) )
#define UART0_BAUDDIV ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 16UL ) ) ) )
#define TX_BUFFER_MASK ( 1UL )
Can you search for prvGetRegistersFromStack
function in your code and see where it is called from? My guess is that it is being called from Hard Fault handler and if that is correct, you are getting a hard fault while using getchar and FreeRTOS is not involved here. This means that the issue is not related to FreeRTOS but to Qemu. I’d suggestion reaching out to Qemu maintainers as well.
In fact, this function is written in startup_gcc.c, but I can’t get any information from it. What’s more, I wonder if anyone has faced the same problem when using this demo to emulate UART input on qemu. (Because I’m not sure if the official mps2-an385 demo has made any configuration related to UART receive mode.)
Assuming that you are talking about this demo, prvGetRegistersFromStack is called from the Hard Fault Handler.
It’s true that the prvGet is called from Hard Fault Handler, but it dosen’t output where the error occurs(maybe the program even not enter main function?) and what I mean is that if getchar() is not support by qemu, what function and what configuration in this demo can I use to receive input from UART? Because I don’t know the original configuration in demo include UART receive mode or not.
Ah, got it. You can use debugger and setup a breakpoint in main to confirm. Another alternative is to remove the getchar and see if you still get hard fault.
As I said before, I am not familiar with the Qemu model and cannot help with this question. Did you try asking Qemu maintainers?
As @aggarg pointed out, you should reach out to QEMU support as this seems to be an issue with the model itself. You can find support channels here Support - QEMU. If you are able to get this resolved, please update here if you do not mind .
I think you may have some misunderstand. Maybe the reason of the getchar() error is that the configuration about UART receive is not include in this demo, then consequence is the qemu’s error information ? In fact, in this demo’s main.c have some UART configuration like this:
/* printf() output uses the UART. These constants define the addresses of the
required UART registers. */
#define UART0_ADDRESS ( 0x40004000UL )
#define UART0_DATA ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 0UL ) ) ) )
#define UART0_STATE ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 4UL ) ) ) )
#define UART0_CTRL ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 8UL ) ) ) )
#define UART0_BAUDDIV ( * ( ( ( volatile uint32_t * )( UART0_ADDRESS + 16UL ) ) ) )
#define TX_BUFFER_MASK ( 1UL )
I‘m not sure these code are written by staffs of FreeRTOS or staffs of QEMU? If the "CORTEX_MPS2_QEMU_IAR_GCC"demo was officially made by FreeRTOS, it’s reasonable for me to think that perhaps among your colleagues there is someone who is familiar with how to configure the UART of this emulated board.
Thank you for clarifying. I understand that it is likely a UART configuration issue.
The UART reading and writing functionality is not part of the FreeRTOS kernel. While we do provide examples, FreeRTOS cannot support all hardware-specific UART peripherals across the diverse range of microcontrollers and development boards available.
That means although in this demo the developers of FreeRTOS realize the function of UART output through rewrite printf function and configuration UART, but it can’t guarantee that the UART input realization? Or should I post this question in another section of the forum with another tags?
That means the demo utilizes UART but we have not developed the UART peripheral or the corresponding driver.
No, that won’t be any beneficial.