且行停 发表于 2023-10-26 19:17:54

求助,sscanf在串口中断卡死的现象

在ZYNQ7010的裸机下跑官方的串口例程,在串口中断里面使用sscanf,sscanf带有正则表达式时程序卡死,不带时则正常运行
这是卡死的
这是不卡死的
程序源码如下:


#include "stdio.h"
#include "sleep.h"
#include "xparameters.h"
#include "xplatform_info.h"
#include "xuartps.h"
#include "xil_exception.h"
#include "xil_printf.h"
#include "xscugic.h"


#define INTC                                XScuGic
#define UART_DEVICE_ID                XPAR_XUARTPS_1_DEVICE_ID
#define INTC_DEVICE_ID                XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID                XPAR_XUARTPS_1_INTR

#define TEST_BUFFER_SIZE        100
/************************** Function Prototypes *****************************/

int UartPsIntrExample(INTC *IntcInstPtr, XUartPs *UartInstPtr, u16 DeviceId, u16 UartIntrId);
static int SetupInterruptSystem(INTC *IntcInstancePtr, XUartPs *UartInstancePtr, u16 UartIntrId);
void Handler(void *CallBackRef, u32 Event, unsigned int EventData);
int rsscanf(const char* str, const char* format, ...);
/************************** Variable Definitions ***************************/

XUartPs UartPs        ;                        /* Instance of the UART Device */
INTC InterruptController;        /* Instance of the Interrupt Controller */
int m_uCommRxNum = 0;


static u8 SendBuffer;        /* Buffer for Transmitting Data */
static u8 RecvBuffer;        /* Buffer for Receiving Data */

volatile int TotalReceivedCount;
volatile int TotalSentCount;
int TotalErrorCount;

int main(void)
{
        int Status;

        xil_printf("start ran UART Interrupt Example Test\r\n");

        Status = UartPsIntrExample(&InterruptController, &UartPs, UART_DEVICE_ID, UART_INT_IRQ_ID);
        if (Status != XST_SUCCESS)
        {
                xil_printf("UART Interrupt Example Test Failed\r\n");
                return XST_FAILURE;
        }

        xil_printf("Successfully ran UART Interrupt Example Test\r\n");
        return XST_SUCCESS;
}

int UartPsIntrExample(INTC *IntcInstPtr, XUartPs *UartInstPtr,
                        u16 DeviceId, u16 UartIntrId)
{
        XUartPs_Config *Config;
        int Index;
        u32 IntrMask;
        int Status;

        Config = XUartPs_LookupConfig(DeviceId);
        Status = XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
        Status = XUartPs_SelfTest(UartInstPtr);
        Status = SetupInterruptSystem(IntcInstPtr, UartInstPtr, UartIntrId);

        IntrMask =
                XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING |
                XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL |
                XUARTPS_IXR_RXOVR;

        XUartPs_SetInterruptMask(UartInstPtr, IntrMask);

        XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_LOCAL_LOOP);
        XUartPs_SetRecvTimeout(UartInstPtr, 8);

        for (Index = 0; Index < TEST_BUFFER_SIZE; Index++)
        {
                SendBuffer = (Index % 26) + 'A';
                RecvBuffer = 0;
        }

        xil_printf("success.\r\n");
        Xil_ExceptionEnable();

        while (1)
        {
                for(int i = 0; i < 666000; i++)
                {
                        for(int j = 0; j < 1000; j++)
                        {

                        }
                }

                XUartPs_Send(UartInstPtr, SendBuffer, TEST_BUFFER_SIZE);
        }

        return Status;
}
u32 ymd = 0;
u32 hms = 0;
u32 srate = 0;
u32 slen = 0;
u32 p5;
u32 p6;
u32 p7;


void Handler(void *CallBackRef, u32 Event, unsigned int EventData)
{
        /* All of the data has been sent */
        if (Event == XUARTPS_EVENT_SENT_DATA) {
                TotalSentCount = EventData;
        }

        /* All of the data has been received */
        if (Event == XUARTPS_EVENT_RECV_DATA) {
                TotalReceivedCount = EventData;
                XUartPs_Recv(&UartPs, RecvBuffer, 200);
        }

        char str = "1 2 3 4 5 6 7 ";

        if (Event == XUARTPS_EVENT_RECV_TOUT) {
                TotalReceivedCount = EventData;
                xil_printf("status is 2.\r\n");
                sscanf(str,"%u% %u %u %u %u %u %u", &ymd, &hms, &srate, &slen,&p5,&p6, &p7);
                xil_printf("ymd is %d.\r\n", ymd);
        }

        if (Event == XUARTPS_EVENT_RECV_ERROR) {
                TotalReceivedCount = EventData;
                TotalErrorCount++;
                xil_printf("XUARTPS_EVENT_RECV_ERROR.\r\n");
        }

        if (Event == XUARTPS_EVENT_PARE_FRAME_BRKE) {
                TotalReceivedCount = EventData;
                TotalErrorCount++;
                xil_printf("XUARTPS_EVENT_PARE_FRAME_BRKE.\r\n");
        }

        if (Event == XUARTPS_EVENT_RECV_ORERR) {
                TotalReceivedCount = EventData;
                TotalErrorCount++;
                xil_printf("XUARTPS_EVENT_RECV_ORERR.\r\n");
        }
}


static int SetupInterruptSystem(INTC *IntcInstancePtr,
                                XUartPs *UartInstancePtr,
                                u16 UartIntrId)
{
        int Status;

        XScuGic_Config *IntcConfig; /* Config for interrupt controller */

        /* Initialize the interrupt controller driver */
        IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        if (NULL == IntcConfig) {
                return XST_FAILURE;
        }

        Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                                        IntcConfig->CpuBaseAddress);
        if (Status != XST_SUCCESS) {
                return XST_FAILURE;
        }

        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler) XScuGic_InterruptHandler,
                                IntcInstancePtr);

        Status = XScuGic_Connect(IntcInstancePtr, UartIntrId, (Xil_ExceptionHandler) XUartPs_InterruptHandler,
                                  (void *) UartInstancePtr);
        if (Status != XST_SUCCESS) {
                return XST_FAILURE;
        }

        XUartPs_SetHandler(UartInstancePtr, (XUartPs_Handler)Handler, UartInstancePtr);

        XScuGic_Enable(IntcInstancePtr, UartIntrId);
        return XST_SUCCESS;
}


eric2013 发表于 2023-10-26 20:43:16

C库用的那个,libc还是newlib,可以在电脑端单独测试下试试。正常的话,你这个程序放在中断外试试。

且行停 发表于 2023-10-26 22:29:48

eric2013 发表于 2023-10-26 20:43
C库用的那个,libc还是newlib,可以在电脑端单独测试下试试。正常的话,你这个程序放在中断外试试。

现在用的vivado 2018.3版本,SDK保持的默认设置,所以应该是libc,这个库是ARM的我不知道怎么在电脑上跑起来,sscanf函数在中断外是正常的
页: [1]
查看完整版本: 求助,sscanf在串口中断卡死的现象