공부/Embedded
[Zephyr] Workqueue
래울
2025. 1. 7. 00:40
Exercise 3 - Nordic Developer Academy
Workqueue creation and work item submission Since threads of higher priority have the ability to starve other low priority threads, it is good practice to offload all non-urgent execution in these threads into lower-priority threads. In this exercise, we w
academy.nordicsemi.com
https://docs.zephyrproject.org/apidoc/latest/group__workqueue__apis.html
Zephyr API Documentation: Work Queue APIs
int k_work_poll_submit_to_queue ( struct k_work_q * work_q, struct k_work_poll * work, struct k_poll_event * events, int num_events, k_timeout_t timeout ) isr-ok
docs.zephyrproject.org
#include <zephyr.h>
#include <sys/printk.h>
#include <kernel.h>
#include <kernel_structs.h>
#include <string.h>
#define THREAD0_STACKSIZE 512
#define THREAD1_STACKSIZE 512
#define WORQ_THREAD_STACK_SIZE 512
// 스레드 우선 순위 정의, workqueue를 가장 낮게 줌
#define THREAD0_PRIORITY 2
#define THREAD1_PRIORITY 3
#define WORKQ_PRIORITY 4
// workqueue가 쓸 스택 정의
static K_THREAD_STACK_DEFINE(my_stack_area, WORQ_THREAD_STACK_SIZE);
// workqueue 구조체 정의
static struct k_work_q offload_work_q = {0};
// 긴급하지 않은 작업
static inline void emulate_work()
{
for(volatile int count_out = 0; count_out < 150000; count_out ++);
}
// k_work와 이름을 가짐, workqueue로 이전할 work
struct work_info {
struct k_work work;
char name[25];
} my_work;
// 이전 함수
void offload_function(struct k_work *work_tem)
{
emulate_work();
}
//나중에 main thread로
void thread0(void)
{
uint64_t time_stamp;
int64_t delta_time;
//workqueue 시작
//work item를 초기화하고 핸들러 함수에 연결
k_work_queue_start(&offload_work_q, my_stack_area,
K_THREAD_STACK_SIZEOF(my_stack_area), WORKQ_PRIORITY,
NULL);
strcpy(my_work.name, "Thread0 emulate_work()");
k_work_init(&my_work.work, offload_function);
//thread0 loop
while (1) {
time_stamp = k_uptime_get();
//work를 workqueue로 넘겨서 처리
k_work_submit_to_queue(&offload_work_q, &my_work.work);
delta_time = k_uptime_delta(&time_stamp);
printk("thread0 yielding this round in %lld ms\n", delta_time);
k_msleep(20);
}
}
//thread1 진입 함수
void thread1(void)
{
uint64_t time_stamp;
int64_t delta_time;
//thread1 loop
while (1) {
time_stamp = k_uptime_get();
emulate_work();
delta_time = k_uptime_delta(&time_stamp);
printk("thread1 yielding this round in %lld ms\n", delta_time);
k_msleep(20);
}
}
K_THREAD_DEFINE(thread0_id, THREAD0_STACKSIZE, thread0, NULL, NULL, NULL,
THREAD0_PRIORITY, 0, 0);
K_THREAD_DEFINE(thread1_id, THREAD1_STACKSIZE, thread1, NULL, NULL, NULL,
THREAD1_PRIORITY, 0, 0);