在PIC18上使用C的multithreading

在编写PIC18时 ,如何创建并行运行的线程,因为没有操作系统?

不要使用线程,使用事件循环。

PIC18是一个小型处理器,基于事件循环的风格意味着您不必保留许多深层堆栈。 您需要根据事件循环编写代码,但这可能是合理的。

如果您确实有一些长时间运行的任务,请使用不同的中断优先级,以允许更高优先级的事件循环抢占较低优先级的事件循环,并将适当类型的工作放入适当的事件队列中。

您可以尝试合作多任务处理 。

对于PIC解决的问题类型,如果您尝试使用中断或轮询而不是multithreading的其他设计,您可能会更好。

你可以在那里放一个RTOS(有一个非官方的ucOS端口 ,或者你可以查看FreeRTOS的PIC18端口 )。

否则,您可以尝试使用setjmplongjmp 在C中实现协同程序 。

如果根本没有操作系统,你(显然)必须自己重新创建必要的function。

最简单的方法可能是安装以某个合适频率运行的定时器中断(可能取决于您的实际时钟速度,但可能在100-1000 Hz范围内)。 在中断处理程序中,您需要检查当前线程的状态,并确定是否应该进行切换。

然后诀窍是在必要时进行切换,并从中断处理程序返回到另一个线程

当然,当线程本身可能使用中断时,让它工作并不一定容易。

您还可以考虑安装一些内核,也许是Contiki 。

以下是PIC18的“protothreads”示例,看起来像是一个合理数量的代码。 但是不确定语义。

更新 :这可能需要你在汇编程序中执行一些最低级别的代码(我不确定,在PIC上没有使用C,所以我不确切知道你得到了多少控制权)。 您需要控制程序计数器的寄存器,而不是C概念。

请注意,在微控制器上,某些“线程”也可以由一些特定的中断处理程序处理,因此无论如何都要与主事件循环“并行”运行。

例如,如果您有一个外部事件触发ADC转换,您的ADC转换完成处理程序可以获取该值,进行一些计算,然后设置一些输出位以根据ADC值调整控制输出。 所有这些都可能发生在中断处理程序中,因此与其他所有内容并行。

根据您需要并行执行的操作,您可以选择多种技术的组合,以使内容按预期并行工作。

您可能希望从嵌入式系统编程中阅读本文: 构建一个超级简单的Tasker

CCS编译器包括RTOS。 我没有使用它,但是从编译器手册中 :

CCS实时操作系统(RTOS)允许PIC微控制器在不需要中断的情况下运行定期计划的任务。 这是通过充当调度程序的函数(RTOS_RUN())来完成的。 当计划运行任务时,调度function将处理器的控制权交给该任务。 当任务完成执行或不再需要处理器时,处理器的控制权返回到调度function,然后调度function将处理器控制到计划在适当时间执行的下一个任务。 该过程称为协作多任务。

只需提醒一句 – 请查看他们的论坛,了解您正在寻找的具体function。 显然,CCS习惯于在完全测试之前发布新function。 这是我仍在使用旧版本(v3.249)的一个原因。

在8051上,我使用简单的堆栈切换器完成了双任务。 我希望可以在PIC上完成相同的工作,前提是每个任务只使用16级堆栈。 代码将是这样的(假设_altSP在公共银行)

 _InitTask2:
     movff _STKPTR,_altSP
     movlw 16
     movwf _STKPTR,c
    转到_Task2Start

 _TaskSwitch:
     movf _altSP,w,c
     movff _STKPTR,_altSP
     movwf _STKPTR,c
    返回

主要任务应该调用_InitTask2来启动第二个任务。 第二个任务将一直运行,直到它调用_TaskSwitch,然后主要任务将在调用_InitTask2的指令后继续执行。 从那时起,每当一个任务调用_TaskSwitch时,另一个任务将从它最后一个名为_TaskSwitch的地方恢复执行。

如果使用此方法,则必须通知您的编译器可能会通过调用_InitTask2或_TaskSwitch来破坏所有寄存器。 还必须告诉它_Task2Start和它调用的函数必须从主任务中分配单独的变量空间。

我不确定你需要告诉编译器让它快乐,但我会说合作双任务可以让一些事情很好地工作。

我想用C编程语言分享我的微内核来管理微控制器上的任务。 您可以随时创建具有句点,暂停,恢复和更改任务周期的任务。 此内核可以删除所有任务以根据需要创建另一个顺控程序。 内核提供TickGet函数以根据需要管理所有计时器。 您必须只创建一个中断函数并替换函数Timer()以获取您自己应用程序的微内核。 恢复此内核基于循环链表,以切换任务任务。 它愿意以一般方式编写,以帮助人们定制他们拥有的应用程序。 任务之间没有优先级,如循环任务调度。 我在MISRA指南(汽车规范)上写了这个源代码你可以在这里下载

我希望能帮助人们管理微控制器上的任务。

这样做就是这样,一个任务循环,以及任务的优先级,以及我喜欢将长时间运行的函数分解成片的简单编码。

http://www.mculabs.com/drivers/qtask.html

我同意ndim – 您可以将每个中断处理程序视为类似“线程”的东西。 有时,您需要执行的所有任务都可以由外部和内部事件触发的中断处理程序处理 – “主循环”是一个无效的空闲循环。

我不知道哪些评论者认为PIC18有“无操作系统”的想法。 PIC18有很多特定于PIC的multithreading库和“多任务操作系统内核”,其中许多是免费和开源的。 请参见PICList:“PIC单片机特定的多任务处理方法” 。

我正在这样做(严格来说,固定调用堆栈深度处的协作式多任务处理)。

它可以工作,但是Hitec-c编译器对我不利 – 它重用了它认为从不同时运行的函数的临时变量的内存位置。 基本上线程互相腐败。 如果我找到解决方法,我将使用示例代码更新此答案。

Protothreads库是多任务,跨平台的简单方法: http ://dunkels.com/adam/pt/

具有任务同步,计时器和用户数据的PT的最小调度程序示例: https : //github.com/edartuz/c-ptx