Многопоточность с использованием C на PIC18 - PullRequest
7 голосов
/ 26 октября 2009

Как создать потоки, которые работают параллельно при программировании PIC18 , поскольку ОС не существует?

Ответы [ 13 ]

12 голосов
/ 26 октября 2009

Не используйте потоки, используйте цикл обработки событий.

PIC18 - это небольшой процессор, и стиль, основанный на цикле событий, означает, что вам не нужно хранить много глубоких стеков. Вам нужно написать свой код в терминах цикла событий, но это, вероятно, разумно.

Если у вас есть какие-то долго выполняющиеся задачи, используйте таймеры разных уровней приоритета прерываний, чтобы позволить циклам событий с более высоким приоритетом вытеснять циклы событий с более низким приоритетом и помещать соответствующие типы работы в соответствующую очередь событий.

9 голосов
/ 26 октября 2009

Вы можете попробовать Совместная многозадачность .

Для типов проблем, которые решает PIC, вам, вероятно, будет лучше, если вы попробуете другой дизайн, который использует прерывания или опрос вместо нескольких потоков.

6 голосов
/ 26 октября 2009

Вы можете установить RTOS (есть неофициальный порт ucOS , или вы можете проверить порт FreeRTOS PIC18 ).

В противном случае вы можете попробовать реализовать сопрограммы в C , используя setjmp и longjmp.

5 голосов
/ 26 октября 2009

Если ОС вообще не существует, вам (очевидно) придется заново создать необходимую функциональность самостоятельно.

Вероятно, самый простой способ - это установить прерывание таймера, работающее на некоторой подходящей частоте (возможно, зависит от вашей реальной тактовой частоты, но, возможно, в диапазоне 100-1000 Гц). В обработчике прерываний вам нужно проверить состояние текущего потока и решить, должен ли произойти переключение.

Хитрость заключается в том, чтобы при необходимости переключаться и возвращаться из обработчика прерываний в другой поток .

Конечно, заставить это работать, когда сами потоки могут использовать прерывания, не обязательно будет легко.

Вы также можете посмотреть на установку какого-нибудь ядра, возможно, Contiki .

Здесь является примером «протопотоков» для PIC18, выглядит как разумное количество кода. Не уверен насчет семантики.

Обновление : Это, вероятно, потребует от вас выполнения некоторого кода самого низкого уровня в ассемблере (я не уверен, что не работал в C на PIC, поэтому я не знаю точно, как большой контроль вы получаете). Вам потребуется контроль над регистрами счетчика программы, и это не концепции C.

2 голосов
/ 26 октября 2009

Возможно, вы захотите прочитать эту статью о программировании встроенных систем: Создание супер простого Tasker

2 голосов
/ 26 октября 2009

Имейте в виду, что на микроконтроллерах некоторые «потоки» также могут обрабатываться только каким-то определенным обработчиком прерываний и, таким образом, в любом случае запускаться «параллельно» вашему главному циклу событий.

например. если у вас есть внешнее событие, инициирующее преобразование АЦП, обработчик выполненного преобразования АЦП может принять это значение, выполнить несколько вычислений и затем установить несколько выходных битов для адаптации управляющего выхода в соответствии со значением АЦП. Все, что может происходить в обработчике прерываний и, следовательно, параллельно всему остальному.

В зависимости от того, что вам нужно делать параллельно, вы можете выбрать комбинацию из нескольких методов, чтобы заставить вещи работать параллельно, как и предполагалось.

1 голос
/ 08 мая 2012

Я хотел бы поделиться своим крошечным ядром на языке программирования C для управления задачами на микроконтроллере. Вы можете создать задачу с периодом, приостановить, возобновить и изменить период задачи в любое время. Это ядро ​​может удалить все задачи, чтобы создать другой секвенсор, как вы хотите. Функция TickGet поставляется ядром для управления всеми таймерами, как вы хотите. Вам нужно создать только одну функцию прерывания и заменить функцию Timer (), чтобы получить крошечное ядро ​​для вашего собственного приложения. Для возобновления работы этого ядра используется кольцевой связанный список, чтобы переключить задачу на задачу. Он охотно написан в общих чертах, чтобы помочь людям настраивать свои приложения. Нет приоритета между задачами, такими как циклическое планирование задач. И я написал этот исходный код в отношении руководящих принципов MISRA (автомобильная норма) Вы можете скачать его здесь

Я надеюсь помочь людям управлять задачами на микроконтроллере.

1 голос
/ 19 августа 2010

На 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 и вызываемые им функции должны быть выделены отдельно от переменной для основной задачи.

Я не уверен, что нужно сказать компилятору, чтобы он был доволен, но я скажу, что совместная двойная работа может заставить некоторые вещи работать очень хорошо.

1 голос
/ 26 октября 2009

Компилятор CCS включает RTOS. Я не использовал его, но из руководства по компиляции :

Операционная система реального времени CCS (RTOS) позволяет микроконтроллер PIC запускать регулярно запланированные задачи без необходимости прерываний. это достигается функцией (RTOS_RUN ()), который действует как диспетчер. Когда задача запланирована запустить, функция отправки дает управление процессором для этой задачи. Когда задание выполнено или больше не нужен процессор, управление процессором возвращено к функции отправки, которая затем даст управление процессором следующая задача, которая запланирована на выполнить в соответствующее время. это процесс называется кооперативным многозадачность.

Просто слово предупреждения - проверьте их форумы на информацию о конкретных функциях, которые вы ищете. Очевидно, CCS имеет привычку выпускать новые функции до того, как они будут полностью протестированы. Это одна из причин, почему я все еще использую старую версию (v3.249).

0 голосов
/ 25 мая 2014

Библиотека прототипов - это простой способ многозадачности, кросс-платформенный: http://dunkels.com/adam/pt/

Пример минимального планировщика для PT с синхронизацией задач, таймерами и пользовательскими данными: https://github.com/edartuz/c-ptx

...