#include <pthread.h>
#include <string.h>
#include <unistd.h> // for usleep
#include "serial_main.h"
#include "lvgl/lvgl.h"
#include "serial_thread.h"
#if 1
pthread_t thread_id; // 线程ID
pthread_t update_thread_id; // 线程ID
pthread_mutex_t mutex; // 互斥锁,用于保护全局数据访问
extern pthread_mutex_t mutex_1; // 互斥锁,用于保护全局数据访问
//char received_data[MAX_DATA_LENGTH]; // 全局变量,存储接收到的数据
extern lv_obj_t *textarea; // 声明一个外部变量, LVGL文本框对象指针
extern lv_obj_t * dropdown123;
char * new_data = NULL; // 用于存储新选项的指针
char * data = NULL;
#if 1
// 线程函数,用于接收串口数据并更新LVGL文本框
void *thread_function(void *arg) {
while (1) {
//serial_recv(); // 调用串口接收函数
//data = get_received_data();
pthread_mutex_lock(&mutex); // 加锁,保护全局数据访问
if (data != NULL && strlen(data) > 0) {
//new_data = strdup(data); // 分配内存并复制数据
lv_textarea_add_text(textarea, data); // 更新LVGL文本框内容
memset(data, 0, sizeof(data)); //用于将一块内存区域的内容设置为指定的值
//new_data = data;
}
pthread_mutex_unlock(&mutex); // 解锁
usleep(1000); // 添加适当的延迟以防止CPU占用过高
}
return NULL;
}
#endif
#if 1
// 线程函数,用于将接收到的数据设置为下拉列表的选项
void * update_dropdown_thread(void *arg) {
//char options[] = "ABC\n123\nA2C\0"; // 模拟生成选项文本
int i=0;
while (1) {
i++;
pthread_mutex_lock(&mutex_1); // 加锁,保护全局数据访问
char *options[100] = {0};
//sprintf(options, "ABC\n123\n%d\0", i);
sprintf(options, "%s\n%d\0", data, i);
free(new_data); // 使用完毕后释放内存
new_data = strdup(options); // 复制选项文本
LV_LOG_USER("update_dropdown_thread: Generating new options.");
/*if (dropdown123 == NULL)
LV_LOG_USER("下拉列表为空");
else
LV_LOG_USER("下拉列表不为空");*/
if (dropdown123 != NULL && new_data != NULL) {
lv_dropdown_clear_options(dropdown123);// 在更新下拉列表之前先清除旧选项
lv_dropdown_set_options_static(dropdown123, new_data); // 将接收到的数据设置为选项
//new_data = NULL; // 清空新选项指针
LV_LOG_USER("update_dropdown_thread: 下拉列表更新成功");
}
//free(new_data); // 使用完毕后释放内存
pthread_mutex_unlock(&mutex_1); // 解锁
usleep(50*1000); // 添加适当的延迟以防止CPU占用过高
}
return NULL;
}
#endif
// 初始化函数,用于创建线程和初始化其他必要资源
void initialize_serial_thread() {
pthread_mutex_init(&mutex, NULL); // 初始化互斥锁
#if 1
// 创建线程
if (pthread_create(&thread_id, NULL, thread_function, NULL) != 0) /*pthread_create用于创建一个新的线程, 函数返回一个整数值,如果成功创建线程,则返回0;如果失败,则返回一个非零值*/
{
perror("Failed to create thread");
// 处理线程创建失败的情况
// 可以选择退出程序或者采取其他错误处理措施
}
#endif
#if 1
if (pthread_create(&update_thread_id, NULL, update_dropdown_thread, NULL) != 0) /*pthread_create用于创建一个新的线程, 函数返回一个整数值,如果成功创建线程,则返回0;如果失败,则返回一个非零值*/
{
perror("Failed to create thread");
// 处理线程创建失败的情况
// 可以选择退出程序或者采取其他错误处理措施
}
#endif
}
#endif
之前更新下拉列表文本的线程会出现卡死的情况,我把线程分开分别排查,现在解决这个问题,只开任何一个线程屏幕都不会出现卡死的情况,现在是两个线程都打开,烧录到触摸屏上,在串口接收数据后下拉列表文本并没有获取到串口发送的数据,并且屏幕还卡死了,这是接收串口数据线程代码哪里出现了问题,另外第二个线程需要将串口的数据用来更新下拉列表的选项,他们的互斥锁是否需要相同
pthread_mutex_t mutex_1;
int main(int argc, char **argv)
{
(void)argc;
(void)argv;
lv_init();
hal_init();
// 初始化互斥锁
pthread_mutex_init(&mutex_1, NULL);
create_layout();
/* 初始化并创建串口接收线程 */
initialize_serial_thread();
while (1)
{
pthread_mutex_lock(&mutex_1); // 加锁,保护全局数据访问
lv_timer_handler();
pthread_mutex_unlock(&mutex_1); // 解锁
usleep(5 * 1000); //5ms
}
return 0;
}
```这是mian.c文件中添加了更新下拉列表数据相同的互斥锁