Basic: Synchronization¶
1 功能概述¶
一个简单的应用程序,演示了内核的基本功能。两个线程(A和B)轮流向控制台打印问候消息,并使用睡眠请求和信号量来控制消息的生成速率。这说明了内核调度,通信,而且时间安排是正确的。
2 环境要求¶
board: pan1080a_afld_evb
uart: 显示串口log
3 编译和烧录¶
项目位置:zephyr\samples_panchip\basic\synchronization
目前可使用ZAL工具或quick build脚本进行编译和下载。
脚本位置:quick_build_samples\synchronization.bat
打开脚本后默认会编译项目,编译完成时,可输入字符进行后续下载等操作:
Input the keyword to continue:
'b' build 编译项目
'r' make clean and rebuild 重新编译项目
'f' flash download 下载
'e' erase chip 擦除芯片
'o' open project by VS Code 打开 `VS Code`,可查看源码,执行编译下载等
others exit 退出
wait input:
4 演示说明¶
下载后,串口工具中看到程序成功运行,两个线程threadA
与threadB
交替打印Log信息
threadA: Hello World!
threadB: Hello World!
threadA: Hello World!
threadB: Hello World!
threadA: Hello World!
threadB: Hello World!
threadA: Hello World!
threadB: Hello World!
threadA: Hello World!
threadB: Hello World!
5 开发说明¶
建立两个线程
k_thread_create(&threadA_data, threadA_stack_area,
K_THREAD_STACK_SIZEOF(threadA_stack_area),
threadA, NULL, NULL, NULL,
PRIORITY, 0, K_FOREVER);
k_thread_name_set(&threadA_data, "thread_a");
k_thread_create(&threadB_data, threadB_stack_area,
K_THREAD_STACK_SIZEOF(threadB_stack_area),
threadB, NULL, NULL, NULL,
PRIORITY, 0, K_FOREVER);
k_thread_name_set(&threadB_data, "thread_b");
轮询调度线程信号量
/*
* @param my_name thread identification string
* @param my_sem thread's own semaphore
* @param other_sem other thread's semaphore
*/
void helloLoop(const char *my_name,
struct k_sem *my_sem, struct k_sem *other_sem)
{
const char *tname;
uint8_t cpu;
struct k_thread *current_thread;
while (1) {
/* take my semaphore */
k_sem_take(my_sem, K_FOREVER);
current_thread = k_current_get();
tname = k_thread_name_get(current_thread);
/* say "hello" */
if (tname == NULL) {
printk("%s: Hello World from cpu %d on %s!\n",
my_name, cpu, CONFIG_BOARD);
} else {
printk("%s: Hello World from cpu %d on %s!\n",
tname, cpu, CONFIG_BOARD);
}
/* wait a while, then let other thread have a turn */
k_busy_wait(100000);
k_msleep(SLEEPTIME);
k_sem_give(other_sem);
}
}