当前文档版本为v0.3.0,您可以访问 开发中 的文档以获取最近可能的更新。

Basic: Synchronization

1 功能概述

一个简单的应用程序,演示了内核的基本功能。两个线程(A和B)轮流向控制台打印问候消息,并使用睡眠请求和信号量来控制消息的生成速率。这说明了内核调度,通信,而且时间安排是正确的。

2 环境要求

  • board: pan1080a_afld_evb

  • uart: 显示串口log

3 编译和烧录

项目位置:zephyr\samples_panchip\basic\synchronization

统一的配置、编译、下载工具正在开发中,当前可以使用脚本进行编译和下载。

脚本位置: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 演示说明

下载后,串口工具中看到程序成功运行,两个线程threadAthreadB交替打印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);
	}
}