На 8051 я выполнил двойную задачу с помощью простого стекового коммутатора. Я ожидаю, что то же самое можно сделать на PIC, при условии, что каждая задача использует только 16 уровней стека. Код будет примерно таким (предполагается, что _altSP находится в общем банке)
_InitTask2:
movff _STKPTR,_altSP
movlw 16
movwf _STKPTR,c
goto _Task2Start
_TaskSwitch:
movf _altSP,w,c
movff _STKPTR,_altSP
movwf _STKPTR,c
return
Основная задача должна вызвать _InitTask2, чтобы запустить вторую задачу. Вторая задача будет выполняться до тех пор, пока она не вызовет _TaskSwitch, после чего основная задача возобновит выполнение, следуя инструкции, которая называется _InitTask2. С этого момента каждый раз, когда задача вызывает _TaskSwitch, другая задача возобновляет выполнение с последнего места, которое называется _TaskSwitch.
Если вы используете этот подход, ваш компилятор должен быть проинформирован о том, что все регистры могут быть уничтожены вызовами _InitTask2 или _TaskSwitch. Также нужно будет сказать, что _Task2Start и вызываемые им функции должны быть выделены отдельно от переменной для основной задачи.
Я не уверен, что нужно сказать компилятору, чтобы он был доволен, но я скажу, что совместная двойная работа может заставить некоторые вещи работать очень хорошо.