【DigiKey“智造万物,快乐不停”创意大赛】 移植FreeRTOS + LVGL +Lwip实现TCPclient
[复制链接]
【前言】
在前面我用rtthread studio+lvgl实现了基本的demo,但是在移植lwip上面出现问题,因此改为freertos+lvgl+lwip来搭建开发环境。
【开发环境】
Win11 + STM32CubeIde
【移植步骤】
- 安装stm32cubeide,官方有详细的教程,此处不细说。
- 安装好后,打开stm32cubeide,新建stm32工程,目标开发板选择stm32f746G-Discovery。按照黙认的选项生成工程。工程中默认运行的OS为freeRTos。
- 在github下载一个stm32f746-discoer的开源源码,下载为: git clone --recursive
- 下载之后我们把下图所示的lvgl、hal_stm_lvgl、Uilitites目录下的STM32F746G-Discovery、Components复制到工程的指定目录下。
- 复制lvgl.conf.h到工程目录下。
- 编译后按照提示添加文件引用的目录,这里不一一记录。
- 添加Lwip,在配置界面,我们开打LWIP,禁用DHCP,同时按开发环境配置好网卡。
- 选择网络的PHY芯片,我们版载的是LAN8742:
- 在freertos中添加两个任务,任务1为lvgl,任务2为lwip,同是创建一个队列,用于两个任务的通信:
- 在任务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 */
}
- 任务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 */
}
- 同时我们要需要在lwipopts.h中,打开LWIP_NETCONN和LWIP_SOCKET这2个宏,如下:
到些,我们移植工作就结束。
【实验效果】
我们在触摸屏上按下button按键,在TCP服务端上收到开发板发出和信息:
【经验心得】
Stm32cubeIDE 经过官方的升级,现在变得越来越好用。而且官方给开发板官好了驱动,让开发者上手特别的快。FreeRTos相比RTT,好要用的得很多,看来国产的RTT还需要有很长的路要走,生态还需要继续加强。
|