We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I'm trying to implement a basic application on an embedded device using lwIP. I got the basic project set up, the retarget-ing works as expected.
However when I add lwIP into the project and call lwip_init() I have no more output. If I leave out the call to lwip_init() everything is back to normal.
What's more interesting, is that if I call fopen() the same behavior appears as before, I have no other output on the serial. I get no output no matter if I use the retarget-ed printf() function or if I use the driver's function USART_SendData().
What did I got wrong?
I posted below the retarget.c file and my Main.cpp (if I un-comment either BLOCK 1 or BLOCK 2, I have no more output).
Note: the retarget-ed functions send data to USART3 and USART_SendData() sends it to USART1.
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 //infocenter.arm.com/.../index.jsp #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'); } }
I stepped through it with the debugger and in the Reset_Handler when I try to step into main or if I set a break point in main it won't go there and then I have no more debug capabilities, I cannot step, I can only stop/restart debugging.
I tried this both with lwip_init() and with fopen(), same behavior. I'll look into lwip_init() to see what it does, though I'm not sure it will help because the same thing is reproducible with fopen().
"In particular, what does it do to interrupts..." I'm not sure what you're trying to say here.
Is it faulting, or locking up in SystemInit()?
I don't see any code that initializes the USART, or the pins it's supposed to interface too.
Considered using the SWV Serial Debugger output stream?
"Is it faulting, or locking up in SystemInit()?": Neither, it gets past SystemInit() just fine.
; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP
After I step in at BX R0 (which I expect to get me into main()) I just have to stop debugging since I cannot see where it's going, nor I have any other control over the debugger.
Here is the initialization code:
#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(); }
"Considered using the SWV Serial Debugger output stream?": If I don't get this solved... eventually I will try that, but I'd like to get this working since I wouldn't have to rely on the JTAG port and the IDE to do the "printf debugging".
Hello again,
I tried to use the ITM port for debugging, but I run in exactly the same issue. I get output, unless I call fopen and/or lwip_init().
Any ideas?
After I step in at BX R0 (which I expect to get me into main())
__main is not equal to main().
If you want to debug __main, you have to switch to dis-assembly window.
I'm trying to implement a basic application on an embedded device using lwIP.
Do you have any successful experiences with Filesystem or TCP/IP on MCU?
You need to prepare and initialize something, before you can call fopen(). On X86 platform, what you need is simply [ #include <stdio.h> ].
Not at all, I'm a beginner on the embedded side.
TCP/IP, Filesystem might be trivial to developers like Andrew Neil or Westonsupermare Pier; but personally, I think TCP/IP, Filesystem are very difficult.
It is necessary for a beginner to start with a working evaluation board + working lwIP example code; otherwise it costs too much time.
On the other hand, we become experienced by solving a lot of problems.