Нет последовательного вывода после ретаргетинга и вызова fopen()

Я пытаюсь реализовать базовое приложение на встроенном устройстве с помощью lwIP. Я настроил базовый проект, ретаргетинг работает, как и ожидалось.

Однако, когда я добавляю lwIP в проект и вызываю lwip_init() У меня больше нет выхода. Если я пропущу звонок lwip_init() все возвращается на круги своя.

Что еще интереснее, если я позвоню fopen() такое же поведение, как и раньше, у меня нет другого выхода на серийник. Я не получаю вывод, независимо от того, использую ли я ретаргетинг printf() функция или если я использую функцию водителя USART_SendData(),

Что я не так понял?

Я разместил ниже файл retarget.c и мой Main.cpp (если я откомментирую BLOCK 1 или же BLOCK 2У меня больше нет вывода) вместе с кодом инициализации.

Примечание: ретаргетированные функции отправляют данные USART3 а также USART_SendData() отправляет его в USART1.

Я также пытался использовать порт ITM для отладки, но у меня такое же поведение.

retarget.c:

#include <stdio.h>
#include <LibSTM/stm32f10x_usart.h>
#include <rt_sys.h>

#pragma import(__use_no_semihosting_swi)

struct __FILE { int handle; };
FILE __stdout;
FILE __stdin;
FILE __stderr;
FILE *__aeabi_stdin;
FILE *__aeabi_stdout;
FILE *__aeabi_stderr;

int fputc(int ch, FILE *f)
{
    while (!(USART3->SR & 0x0080));
    USART3->DR = ch;

    return (ch);
}

int ferror(FILE *f)
{
    return EOF;
}

void _ttywrch(int ch)
{
    fputc(ch, stdout);
}

void _sys_exit(int return_code)
{
    label:  goto label;
}

//retargeting since otherwise lwIP inclusion produces errors
//http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3844.html
#define DEFAULT_HANDLE 0x100

const char __stdin_name[] = "my_stdin";
const char __stdout_name[] = "my_stdout";
const char __stderr_name[] = "my_stderr";

int _sys_write(FILEHANDLE fh, const unsigned char * buf, unsigned len, int mode){
    int i;
    for(i=0;i<len;i++)
    {
        fputc(buf[i], stdout);
    }

    return 0;
}

FILEHANDLE _sys_open(const char* name, int openmode){
    return DEFAULT_HANDLE;
}
int _sys_istty(FILEHANDLE fh){
    return 0;
}

int _sys_seek(FILEHANDLE fh, long pos){
    return -1;
}

long _sys_flen(FILEHANDLE fh){
    return 0;
}

int _sys_close(FILEHANDLE fh){
    return 0;
}

int _sys_ensure(FILEHANDLE fh){
    return 0;
}

main.cpp:

#include <HW/HWSetup.h>
#include <stdio.h>
#include "lwip/init.h"

int main()
{
    HWSetup();
    printf("Start!\r\n");

    /* //BLOCK 1
    FILE *f;
    f = fopen("foobar", "r");
    */

    /* //BLOCK 2
    lwip_init();
    */

    printf("End!\r\n");

    while(1){
        USART_SendData(USART1, 'x');
    }
}

HWSetup.cpp:

#include <HW/HWSetup.h>
#include <stdio.h>

void SetupGPIO()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
}

void SetupTraces()
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // Trace GPIO

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    // Trace USART
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 921600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;
    USART_Init(USART3, &USART_InitStructure);
    USART_Cmd(USART3, ENABLE);
}

void SetupUSART_RS232()
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // USART1 GPIO

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    USART_InitTypeDef USART_InitStructure;

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No ;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_Init(USART1,&USART_InitStructure);
}

void HWSetup()
{
    SetupGPIO();
    SetupUSART_RS232();
    SetupTraces();
}

Я также попытался отладить код, но после того, как я вступил в BX R0 (который я ожидаю, чтобы получить меня в main()), мне просто нужно прекратить отладку, так как я не могу видеть, куда он идет, и у меня нет никакого другого контроля над отладчиком:

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
    IMPORT  __main
    IMPORT  SystemInit
        LDR     R0, =SystemInit
        BLX     R0
        LDR     R0, =__main
        BX      R0
        ENDP

1 ответ

Следующий код работал для меня с LPC1788 и µVision5 с микролибом и без него:

//retarget minimum requirements to work with printf 

#include <stdio.h>
#include <rt_misc.h>
#ifndef __MICROLIB
#pragma import(__use_no_semihosting_swi)    // some projects need this, some don't like it
#endif
#include <rt_sys.h>

extern void $Super$$_sys_open(void);
extern int  sendchar(int ch);  //needed for printf 
extern int  getch(void);  //needed for scanf 


FILEHANDLE $Sub$$_sys_open(const char *name, int openmode)
{
 return 1; /* everything goes to the same output */
}

extern void $Super$$_sys_close(void);
int $Sub$$_sys_close(FILEHANDLE fh)
{
 return 0;
}

extern void $Super$$_sys_write(void);
int $Sub$$_sys_write(FILEHANDLE fh, const unsigned char *buf,
              unsigned len, int mode)
{
 //your_device_write(buf, len);

 return 0;
}

extern void $Super$$_sys_read(void);
int $Sub$$_sys_read(FILEHANDLE fh, unsigned char *buf,
             unsigned len, int mode)
{
 return -1; /* not supported */
}

extern void $Super$$_ttywrch(void);
void $Sub$$_ttywrch(int ch)
{
 //char c = ch;
 //your_device_write(&c, 1);
  sendchar(ch);
}

extern void $Super$$_sys_istty(void);
int $Sub$$_sys_istty(FILEHANDLE fh)
{
 return 0; /* buffered output */
}

extern void $Super$$_sys_seek(void);
int $Sub$$_sys_seek(FILEHANDLE fh, long pos)
{
 return -1; /* not supported */
}

extern void $Super$$_sys_flen(void);
long $Sub$$_sys_flen(FILEHANDLE fh)
{
 return -1; /* not supported */
}

extern void $Super$$_sys_exit(void);
long $Sub$$_sys_exit(FILEHANDLE fh)
{
 return -1; /* not supported */
}

//eof

надеюсь, это тебе тоже поможет.

Не забудьте инициализировать uart в main или попытаться поместить инициализацию в _sys_open()

Другие вопросы по тегам