![]() Then in the handler you can use CONTAINER_OF() to access the data in the structure. How do you know which button was pressed? One approach is to place your work item inside of a struct along with the data you want to pass (button number, etc.). The challenge here is how to get data to the worker since we can’t pass any parameters. If your application is freezing up when using the system workqueue, check to see if you’ve run our of stack space and set CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE accordingly. You also have the option of declaring your own workqueues which will need its own stack (remember… it’s a thread with extra features). The example above uses the system workqueue. ![]() All this handler does is queue up a button action function that will be run by the scheduler, sometime after the interrupt service routine ends. You want to spend as little time as possible in the button interrupt function. This code snippet demonstrates using a work queue when a button is pressed. You don’t actually give the handler any information, you just tell your work queue you want to add your handler to the list of pending work. The work queue expects a specific type of function usually referred to as a “work handler”. Many of the sensor readings we do in our demos are handled through work queues. Just set it and forget it–the Zephyr scheduler will run take care of popping work out of the queue and running it until the queue is empty. So you’re telling the work queue “run this function, then run this other function, then run this other…” you get the idea. ![]() The “work” you submit to a work queue is a function. This is a perfect place for something that you want to run once and return from, but don’t want to do it inside of an interrupt service routine. Each item you add will be executed in the order you submitted it, like a “to-do list” for your processor. The work queue has a built-in buffer to store pending work (functions you want to run). It also requires less setup and management than threads. Zephyr Work QueuesĪ Zephyr workqueue is a thread with extra features bolted on. Just be careful that you don’t have multiple threads trying to access the same resource at the same time (protect those resources with a mutex). Elsewhere in the program, we call k_thread_suspend ( animate_ping_tid ) and k_thread_resume ( animate_ping_tid ) to stop and start the animation. Because the loop sleeps in between frames, control is given back to the scheduler or other tasks. When it begins running, the LEDs will update every 100 milliseconds. The example shown here runs an animation when an IoT device is trying to connect to a network. ![]() This is pretty easy, just call any of the k_sleep() functions or k_yield(). It is up to you to yield processor control back to the scheduler so that it may run other threads. Your thread should have a while(1) and can call other functions just like you would in your main loop. I like to think of threads as tasks that need keep running, things that don’t return like a discrete function would. The main thread of the program deals with flow of the things happening on the device, and it can suspend/resume the animation thread as necessary. Instead of trying to get the loop in the main thread to update the lights on a tight schedule, we use a thread to run the animations. Each thread operates independently, with Zephyr’s built-in scheduler deciding when to run each thread.įor example, the Golioth Blue Demo run animations on the LEDs to indicate what mode the device was in. But Zephyr allows you to create multiple threads. The while(1) loop that runs inside of the main function of your application is a thread. Zephyr ThreadsĪ thread is a set of commands to be executed by the CPU. We’ll also discuss how to use message queues to pass around data between running processes. In this post, we’ll discuss the difference between Zephyr threads and work queues and show you why you might want to use one versus the other. The trick with an RTOS is to design your applications so that they utilize the real-time-ness and you don’t miss reacting to real-time events like receiving data from a network, taking sensor readings, or reacting to user input. To be fair, you’re not doing things at the same time the RTOS shares processing time across all of the tasks, with a priority system for the more important ones. ZephyrRTOS is built to let you do multiple things at the same time using a single (or limited number) of processing cores. This blog originally ran on the Golioth website. Written by Mike Szczys, Zephyr Ambassador and Developer Relations Engineer at Golioth
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |