浅析ESP8266_NONOS_SDK-2.2.0_tcpclient

二、实验现象 程序功能:接收tcp服务器发来的信息,串口输出;同时串口发送,回传 三、源码分析 1.程序入口 2.设置为station+ap模式,设置路由器参数连接

一、编译烧录

attachments-2020-09-A4NYHXpB5f5f0541f0854.jpgattachments-2020-09-O8HZnwwZ5f5f054fc2470.jpg二、实验现象

attachments-2020-09-ejcyHt0u5f5f05c7082b1.jpg程序功能:接收tcp服务器发来的信息,串口输出;同时串口发送,回传

三、源码分析

1.程序入口

attachments-2020-09-qw884knV5f5f063e32d1d.png

2.设置为station+ap模式,设置路由器参数连接

attachments-2020-09-cr8TLNXl5f5f06859c402.png

3.  Set timer to check whether router allotted an IP

attachments-2020-09-JiAFx5WR5f5f06b4079a7.png

4.user_check_ip()函数中,以tcp客户端的方式连接tcp服务器


  1. /******************************************************************************
  2. * FunctionName : user_check_ip
  3. * Description : check whether get ip addr or not
  4. * Parameters : none
  5. * Returns : none
  6. *******************************************************************************/
  7. void ICACHE_FLASH_ATTR
  8. user_check_ip(void)
  9. {
  10. struct ip_info ipconfig;
  11. //disarm timer first
  12. os_timer_disarm(&test_timer);
  13. //get ip info of ESP8266 station
  14. wifi_get_ip_info(STATION_IF, &ipconfig);
  15. if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0)
  16. {
  17. os_printf("Connected to router and assigned IP!\r\n");
  18. // Connect to tcp server as NET_DOMAIN
  19. user_tcp_conn.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
  20. user_tcp_conn.type = ESPCONN_TCP;
  21. user_tcp_conn.state = ESPCONN_NONE;
  22. #ifdef DNS_ENABLE
  23. tcp_server_ip.addr = 0;
  24. espconn_gethostbyname(&user_tcp_conn, NET_DOMAIN, &tcp_server_ip, user_dns_found); // DNS function
  25. os_timer_setfn(&test_timer, (os_timer_func_t *)user_dns_check_cb, &user_tcp_conn);
  26. os_timer_arm(&test_timer, 1000, 0);
  27. #else
  28. const char esp_tcp_server_ip[4] = {192,168,1,2}; // remote IP of TCP server
  29. os_memcpy(user_tcp_conn.proto.tcp->remote_ip,esp_tcp_server_ip,4);
  30. user_tcp_conn.proto.tcp->remote_port =8234; // remote port
  31. user_tcp_conn.proto.tcp->local_port = espconn_port(); //local port of ESP8266
  32. espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb); // register connect callback
  33. espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb); // register reconnect callback as error handler
  34. espconn_connect(&user_tcp_conn);
  35. #endif
  36. }
  37. else
  38. {
  39. if ((wifi_station_get_connect_status() == STATION_WRONG_PASSWORD ||
  40. wifi_station_get_connect_status() == STATION_NO_AP_FOUND ||
  41. wifi_station_get_connect_status() == STATION_CONNECT_FAIL))
  42. {
  43. os_printf("Connection to router failed!\r\n");
  44. }
  45. else
  46. {
  47. //re-arm timer to check ip
  48. os_timer_setfn(&test_timer, (os_timer_func_t *)user_check_ip, NULL);
  49. os_timer_arm(&test_timer, 100, 0);
  50. }
  51. }
  52. }


同时注册了user_tcp_connect_cb函数



       espconn_regist_connectcb(&user_tcp_conn, user_tcp_connect_cb); // register connect callback
       espconn_regist_reconcb(&user_tcp_conn, user_tcp_recon_cb); // register reconnect callback as error handler
       espconn_connect(&user_tcp_conn);


5.user_tcp_connect_cb函数中注册了tcp接收处理函数和tcp发送函数,以及tcp断开连接函数

attachments-2020-09-tCHVmi0J5f5f085fcbec3.png

6.user_tcp_recv_cb函数,TCP接收处理

attachments-2020-09-l6xAaGcQ5f5f088d4499d.png

7.user_tcp_sent_cb函数,TCP发送处理

attachments-2020-09-BobpyaYp5f5f08b1003e9.png

8.连上服务器时,做了如下处理

attachments-2020-09-JmhP1E825f5f08dcddb3f.png
attachments-2020-09-7SKrq3yr5f5f09319d5c1.png

attachments-2020-09-DWnMXEsl5f5f091540550.png

向TCP服务器发送了如下数据

attachments-2020-09-C5QvClZR5f5f096a03381.png


9.串口接收中断


  1. /******************************************************************************
  2. * FunctionName : uart0_rx_intr_handler
  3. * Description : Internal used function
  4. * UART0 interrupt handler, add self handle code inside
  5. * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
  6. * Returns : NONE
  7. *******************************************************************************/
  8. LOCAL void
  9. uart0_rx_intr_handler(void *para)
  10. {
  11. /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
  12. * uart1 and uart0 respectively
  13. */
  14. uint8 RcvChar;
  15. uint8 uart_no = UART0;//UartDev.buff_uart_no;
  16. uint8 fifo_len = 0;
  17. uint8 buf_idx = 0;
  18. uint8 temp,cnt;
  19. //RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
  20. /*ATTENTION:*/
  21. /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
  22. /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
  23. /*IF NOT , POST AN EVENT AND PROCESS IN SYSTEM TASK */
  24. if(UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)){
  25. DBG1("FRM_ERR\r\n");
  26. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
  27. }else if(UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)){
  28. DBG("f");
  29. uart_rx_intr_disable(UART0);
  30. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR);
  31. system_os_post(uart_recvTaskPrio, 0, 0);
  32. }else if(UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)){
  33. DBG("t");
  34. uart_rx_intr_disable(UART0);
  35. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR);
  36. system_os_post(uart_recvTaskPrio, 0, 0);
  37. }else if(UART_TXFIFO_EMPTY_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_TXFIFO_EMPTY_INT_ST)){
  38. DBG("e");
  39. /* to output uart data from uart buffer directly in empty interrupt handler*/
  40. /*instead of processing in system event, in order not to wait for current task/function to quit */
  41. /*ATTENTION:*/
  42. /*IN NON-OS VERSION SDK, DO NOT USE "ICACHE_FLASH_ATTR" FUNCTIONS IN THE WHOLE HANDLER PROCESS*/
  43. /*ALL THE FUNCTIONS CALLED IN INTERRUPT HANDLER MUST BE DECLARED IN RAM */
  44. CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA);
  45. #if UART_BUFF_EN
  46. tx_start_uart_buffer(UART0);
  47. #endif
  48. //system_os_post(uart_recvTaskPrio, 1, 0);
  49. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR);
  50. }else if(UART_RXFIFO_OVF_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_OVF_INT_ST)){
  51. WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_OVF_INT_CLR);
  52. DBG1("RX OVF!!\r\n");
  53. }
  54. }


ESP8266串口接收到数据后,system_os_post(uart_recvTaskPrio, 0, 0);



  1. void ICACHE_FLASH_ATTR
  2. uart_init(UartBautRate uart0_br, UartBautRate uart1_br)
  3. {
  4. /*this is a example to process uart data from task,please change the priority to fit your application task if exists*/
  5. system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); //demo with a task to process the uart data
  6. UartDev.baut_rate = uart0_br;
  7. uart_config(UART0);
  8. UartDev.baut_rate = uart1_br;
  9. uart_config(UART1);
  10. ETS_UART_INTR_ENABLE();
  11. #if UART_BUFF_EN
  12. pTxBuffer = Uart_Buf_Init(UART_TX_BUFFER_SIZE);
  13. pRxBuffer = Uart_Buf_Init(UART_RX_BUFFER_SIZE);
  14. #endif
  15. /*option 1: use default print, output from uart0 , will wait some time if fifo is full */
  16. //do nothing...
  17. /*option 2: output from uart1,uart1 output will not wait , just for output debug info */
  18. /*os_printf output uart data via uart1(GPIO2)*/
  19. //os_install_putc1((void *)uart1_write_char); //use this one to output debug information via uart1 //
  20. /*option 3: output from uart0 will skip current byte if fifo is full now... */
  21. /*see uart0_write_char_no_wait:you can output via a buffer or output directly */
  22. /*os_printf output uart data via uart0 or uart buffer*/
  23. //os_install_putc1((void *)uart0_write_char_no_wait); //use this to print via uart0
  24. #if UART_SELFTEST&UART_BUFF_EN
  25. os_timer_disarm(&buff_timer_t);
  26. os_timer_setfn(&buff_timer_t, uart_test_rx , NULL); //a demo to process the data in uart rx buffer
  27. os_timer_arm(&buff_timer_t,10,1);
  28. #endif
  29. }


uart_init()函数中system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen);  //demo with a task to process the uart data


  1. LOCAL void ICACHE_FLASH_ATTR ///
  2. uart_recvTask(os_event_t *events)
  3. {
  4. if(events->sig == 0){
  5. #if UART_BUFF_EN
  6. Uart_rx_buff_enq();
  7. #else
  8. uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT;
  9. uint8 d_tmp = 0;
  10. uint8 idx=0;
  11. for(idx=0;idx<fifo_len;idx++) {
  12. d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
  13. uart_tx_one_char(UART0, d_tmp);
  14. }
  15. WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR|UART_RXFIFO_TOUT_INT_CLR);
  16. uart_rx_intr_enable(UART0);
  17. #endif
  18. }else if(events->sig == 1){
  19. #if UART_BUFF_EN
  20. //already move uart buffer output to uart empty interrupt
  21. //tx_start_uart_buffer(UART0);
  22. #else
  23. #
    • 发表于 2020-09-14 14:17
    • 阅读 ( 126 )

0 条评论

请先 登录 后评论
淡若清风
淡若清风

35 篇文章

作家榜 »

  1. 淡若清风 35 文章
  2. 杨杨 2 文章
  3. seaky 0 文章
  4. 15139236712 0 文章
  5. selectcc 0 文章
  6. 温志亮 0 文章
  7. jamesfan007 0 文章
  8. Gavin 0 文章