用于处理中断数据的设计模式(Design Pattern for handling interrupt data)

编程入门 行业动态 更新时间:2024-10-24 22:18:33
用于处理中断数据的设计模式(Design Pattern for handling interrupt data)

我正在开发一个用C实现的固件应用程序,我想知道这种问题的优秀设计模式是什么:

在主循环中,当我使用UART通信从设备接收数据时,我将获得中断 我会发送一个AT命令并等待来自设备的回复,如果设备回复OK,我将发送下一个AT命令,直到所有命令完成 如果设备回复NOK(不正常),我将再次重新发送命令

我考虑过STATE机器,但我仍然认为实现并不优雅,因为我在等待主循环中的响应,转移到另一个状态。

我应该实施哪种设计模式?

I am developing a firmware application implemented in C, and I want to know what is a good design pattern for this kind of problem:

In main loop, I will get interrupt when I received data from a device using UART communication I would send a AT command and wait for the reply from the device, if the device reply OK, I will send the next AT command until all the commands finish If the device reply NOK (not ok), I will resend the command again

I have considered STATE machine, but I still think the implementation is not elegant, because I was waiting for the response in the main loop, to transit to another state.

Which design pattern should I implement?

最满意答案

这听起来像一个简单的客户端 - 服务器(消费者 - 生产者)模型问题。

简答:监控设计模式。

答案很长......

当你说“我会得到中断”时,你是说会触发硬件中断,还是会发生执行变更? 在硬件中断的情况下,这将是特定于平台的。 即使像键盘硬件中断例程这样简单的事情也需要花费一些精力才能实现 。

如果是另一种情况,你可以只有一个主/经理线程,一个工作线程,并且:

让主循环只使用互斥锁和自旋锁 ,等待工作线程报告数据就绪,而工作线程阻塞等待I / O存储在互斥锁保护的缓冲区中。

而不是自旋锁,使用condvar ( 条件变量 ),所以你不会燃烧CPU并且不必要地浪费周期。

/* * Solution to Producer Consumer Problem * Using Ptheads, a mutex and condition variables * From Tanenbaum, Modern Operating Systems, 3rd Ed. */ /* In this version the buffer is a single number. The producer is putting numbers into the shared buffer (in this case sequentially) And the consumer is taking them out. If the buffer contains zero, that indicates that the buffer is empty. Any other value is valid. */ #include <stdio.h> #include <pthread.h> #define MAX 10000000000 /* Numbers to produce */ pthread_mutex_t the_mutex; pthread_cond_t condc, condp; int buffer = 0; void* producer(void *ptr) { int i; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (buffer != 0) /* If there is something in the buffer then wait */ pthread_cond_wait(&condp, &the_mutex); buffer = i; pthread_cond_signal(&condc); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } void* consumer(void *ptr) { int i; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (buffer == 0) /* If there is nothing in the buffer then wait */ pthread_cond_wait(&condc, &the_mutex); buffer = 0; pthread_cond_signal(&condp); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } int main(int argc, char **argv) { pthread_t pro, con; // Initialize the mutex and condition variables /* What's the NULL for ??? */ pthread_mutex_init(&the_mutex, NULL); pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */ pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */ // Create the threads pthread_create(&con, NULL, consumer, NULL); pthread_create(&pro, NULL, producer, NULL); // Wait for the threads to finish // Otherwise main might run to the end // and kill the entire process when it exits. pthread_join(&con, NULL); pthread_join(&pro, NULL); // Cleanup -- would happen automatically at end of program pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */ pthread_cond_destroy(&condc); /* Free up consumer condition variable */ pthread_cond_destroy(&condp); /* Free up producer condition variable */ }

This sounds like a simple client-server (consumer-producer) model problem.

Short Answer: Monitor design pattern.

Long answer...

When you say "I will get interrupt", do you mean that a hardware interrupt will trigger, or a change in execution will occur? In the case of a hardware interrupt, that will be platform specific. Even something as simple as a keyboard hardware interrupt routine takes a bit of effort to implement.

If it's the other case, you could just have a main/manager thread, a worker thread, and either:

Have the main loop just use mutexes and spin-lock, waiting for the worker thread to report data is ready, while the worker thread blocks waiting for I/O to store in a mutex-protected buffer.

Rather than spin-lock, use a condvar (condition variable), so you're not burning up the CPU and wasting cycles needlessly.

/* * Solution to Producer Consumer Problem * Using Ptheads, a mutex and condition variables * From Tanenbaum, Modern Operating Systems, 3rd Ed. */ /* In this version the buffer is a single number. The producer is putting numbers into the shared buffer (in this case sequentially) And the consumer is taking them out. If the buffer contains zero, that indicates that the buffer is empty. Any other value is valid. */ #include <stdio.h> #include <pthread.h> #define MAX 10000000000 /* Numbers to produce */ pthread_mutex_t the_mutex; pthread_cond_t condc, condp; int buffer = 0; void* producer(void *ptr) { int i; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (buffer != 0) /* If there is something in the buffer then wait */ pthread_cond_wait(&condp, &the_mutex); buffer = i; pthread_cond_signal(&condc); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } void* consumer(void *ptr) { int i; for (i = 1; i <= MAX; i++) { pthread_mutex_lock(&the_mutex); /* protect buffer */ while (buffer == 0) /* If there is nothing in the buffer then wait */ pthread_cond_wait(&condc, &the_mutex); buffer = 0; pthread_cond_signal(&condp); /* wake up consumer */ pthread_mutex_unlock(&the_mutex); /* release the buffer */ } pthread_exit(0); } int main(int argc, char **argv) { pthread_t pro, con; // Initialize the mutex and condition variables /* What's the NULL for ??? */ pthread_mutex_init(&the_mutex, NULL); pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */ pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */ // Create the threads pthread_create(&con, NULL, consumer, NULL); pthread_create(&pro, NULL, producer, NULL); // Wait for the threads to finish // Otherwise main might run to the end // and kill the entire process when it exits. pthread_join(&con, NULL); pthread_join(&pro, NULL); // Cleanup -- would happen automatically at end of program pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */ pthread_cond_destroy(&condc); /* Free up consumer condition variable */ pthread_cond_destroy(&condp); /* Free up producer condition variable */ }

更多推荐

本文发布于:2023-08-02 17:12:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1378745.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   数据   Design   Pattern   interrupt

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!