1135|3

7003

帖子

11

TA的资源

版主

楼主
 

【DigiKey“智造万物,快乐不停”创意大赛】 移植FreeRTOS + LVGL +Lwip实现TCPclient [复制链接]

 

 

【前言】

在前面我用rtthread studio+lvgl实现了基本的demo,但是在移植lwip上面出现问题,因此改为freertos+lvgl+lwip来搭建开发环境。

【开发环境】

Win11 + STM32CubeIde

【移植步骤】

  1. 安装stm32cubeide,官方有详细的教程,此处不细说。
  2. 安装好后,打开stm32cubeide,新建stm32工程,目标开发板选择stm32f746G-Discovery。按照黙认的选项生成工程。工程中默认运行的OS为freeRTos。
  3. 在github下载一个stm32f746-discoer的开源源码,下载为: git clone --recursive
    链接已隐藏,如需查看请登录或者注册
  4. 下载之后我们把下图所示的lvgl、hal_stm_lvgl、Uilitites目录下的STM32F746G-Discovery、Components复制到工程的指定目录下。
  5. 复制lvgl.conf.h到工程目录下。
  6. 编译后按照提示添加文件引用的目录,这里不一一记录。
  7. 添加Lwip,在配置界面,我们开打LWIP,禁用DHCP,同时按开发环境配置好网卡。
  8. 选择网络的PHY芯片,我们版载的是LAN8742:
  9. 在freertos中添加两个任务,任务1为lvgl,任务2为lwip,同是创建一个队列,用于两个任务的通信:
  10. 在任务1中我们在lvgl中添加一个按键与一个标签,代码如下:
lv_obj_t *label;

void lvgl_lable_test(){
    /* 创建�??????个标�?????? */
    label = lv_label_create(lv_scr_act());
    if (NULL != label)
    {
        // lv_obj_set_x(label, 90);                         // 设置控件的X坐标
        // lv_obj_set_y(label, 100);                        // 设置控件的Y坐标
        // lv_obj_set_size(label, 60, 20);                  // 设置控件大小
        lv_label_set_text(label, "Counter");                // 初始显示 0
        // lv_obj_center(label);                            // 居中显示
        lv_obj_align(label, LV_ALIGN_CENTER, 0, -50);       // 居中显示后,向上偏移50
    }
}

/**
 * [url=home.php?mod=space&uid=159083]@brief[/url] 按钮事件回调函数
 */
static void btn_event_callback(lv_event_t* event)
{
    static uint32_t counter = 1;

    lv_obj_t* btn = lv_event_get_target(event);                 //获取事件对象
    if (btn != NULL)
    {
        lv_label_set_text_fmt(label, "%d", counter);            //设置显示内容
        lv_obj_align(label, LV_ALIGN_CENTER, 0, -50);           // 居中显示后,向上偏移50
        if(osMessagePut(myQueue01Handle, counter, 100) != osOK)
        {
        	printf("send error\r\n");
        }
        counter++;
    }
}

/**
 * @brief 创建按钮
 */
void lvgl_button_test(){
    /* 在当前界面中创建�??????个按�?????? */
    lv_obj_t* btn = lv_btn_create(lv_scr_act());                                        // 创建Button对象
    if (btn != NULL)
    {
        lv_obj_set_size(btn, 80, 20);                                                   // 设置对象宽度和高�??????
        // lv_obj_set_pos(btn, 90, 200);                                                // 设置按钮的X和Y坐标
        lv_obj_add_event_cb(btn, btn_event_callback, LV_EVENT_CLICKED, NULL);           // 给对象添加CLICK事件和事件处理回调函�??????
        lv_obj_align(btn, LV_ALIGN_CENTER, 0, 50);                                      // 居中显示后,向下偏移50

        lv_obj_t* btn_label = lv_label_create(btn);                                     // 基于Button对象创建Label对象
        if (btn_label != NULL)
        {
            lv_label_set_text(btn_label, "button");                                     // 设置显示内容
            lv_obj_center(btn_label);                                                   // 对象居中显示
        }
    }
}

void StartTask1(void const * argument)
{
  /* init code for USB_HOST */
  MX_USB_HOST_Init();

  /* init code for LWIP */
//  MX_LWIP_Init();
  /* USER CODE BEGIN StartTask1 */
  lv_init();

	tft_init();
	touchpad_init();
	lvgl_lable_test();
	lvgl_button_test();
//	client_socket_init();
  /* Infinite loop */
  for(;;)
  {
	  lv_task_handler();
	  osDelay(10);
  }
  /* USER CODE END StartTask1 */
}
  1. 任务2为创建lwip的任务,主要是连接到TCP服务器上,等待按键发送信息,如果接收到的队列消息就把消息发往TCP服务器中。
    void StartTaskLwip(void const * argument)
    {
      /* USER CODE BEGIN StartTaskLwip */
    	osEvent event;
    	MX_LWIP_Init();
    	int sock;
    	  struct sockaddr_in address;
    	  uint8_t send_buf[64]= {0};
    	  /* create a TCP socket */
    	  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    	  {
    	      printf("Socket error\n");
    	    return;
    	  }
    
    	  address.sin_family = AF_INET;
    	  address.sin_port = htons(PORT);
    	  address.sin_addr.s_addr = inet_addr(IP_ADDR);
    	  memset(&(address.sin_zero), 0, sizeof(address.sin_zero));
    
    	  if (connect(sock,(struct sockaddr *)&address,sizeof(struct sockaddr)) == -1)
    	  {
    	      printf("Connect failed!\n");
    	      closesocket(sock);
    	   }
    	  else
    	  {
    	      printf("Connect to iperf server successful!\n");
    	  }
    	  while (1)
    	  {
    		  event = osMessageGet(myQueue01Handle, 100);
    		  if(event.status == osEventMessage)
    		  {
    			  sprintf(send_buf,"get messege %d\r\n",event.value.v);
    			  if (write(sock,send_buf,sizeof(send_buf)) < 0)
    			   break;
    			  memset(send_buf,0,sizeof(send_buf));
    		  }
    
    	      vTaskDelay(10);
    	  }
    	  closesocket(sock);
      /* USER CODE END StartTaskLwip */
    }

     

  2. 同时我们要需要在lwipopts.h中,打开LWIP_NETCONN和LWIP_SOCKET这2个宏,如下:

到些,我们移植工作就结束。

【实验效果】

我们在触摸屏上按下button按键,在TCP服务端上收到开发板发出和信息:

【经验心得】

Stm32cubeIDE 经过官方的升级,现在变得越来越好用。而且官方给开发板官好了驱动,让开发者上手特别的快。FreeRTos相比RTT,好要用的得很多,看来国产的RTT还需要有很长的路要走,生态还需要继续加强。

最新回复

RTT在他自带的软件生态还是不错的,RT Thread Studio。ST主要用的确实是FreeRTOS   详情 回复 发表于 2023-10-26 19:21
点赞 关注
 
 

回复
举报

282

帖子

7

TA的资源

一粒金砂(高级)

沙发
 

大佬这stm32的工具软件用的太熟练了,牛掰

点评

多谢大佬的肯定,我还得继续努力,争取分享更多的作品!  详情 回复 发表于 2023-10-26 09:43
 
 
 

回复

7003

帖子

11

TA的资源

版主

板凳
 
sipower 发表于 2023-10-26 09:23 大佬这stm32的工具软件用的太熟练了,牛掰

多谢大佬的肯定,我还得继续努力,争取分享更多的作品!

 
 
 

回复

7205

帖子

2

TA的资源

版主

4
 

RTT在他自带的软件生态还是不错的,RT Thread Studio。ST主要用的确实是FreeRTOS

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表