реклама на сайте
подробности

 
 
17 страниц V  « < 9 10 11 12 13 > »   
Reply to this topicStart new topic
> Система, управляемая событиями и SST(super-simple tasker), Выделено из "ООП. Классы и динамические объекты"
brag
сообщение Sep 14 2016, 11:46
Сообщение #151


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Вот эта статья http://embeddedgurus.com/state-space/categ...en-programming/ и картинка с нее

меня заразила в свое время переходом с традиционной блокирующей модели к event-driven. По мере отвыкания от блокинга количество тредов стало гораздо меньше, иногда и вовсе один. Со временем появились active-objectы, тк одного треда было не достаточно. И так я плавно двигался от блокирующей модели к неблокирующей. А когда увидел, что блокировок вовсе не осталось, вспомнил, что когда-то читал про некий SST, которому не уделил должного внимания из за привычки к блокингу, и начал с ним эксперименты, что в итоге привело к полному отказу от традиционной RTOS. Таким образом я потерял тайм-кванты, которые и так ни разу не пригодились, разве что в качестве костылей, которых SST-стиль не требует вовсе. Но получил взамен очень много, главное - избавился от кучи багов, накладных расходов и кучи ручной работы.
Код по мере опыта ставал меньше и проще, горбатые конструкции, которые перекочевали из блокирующего стиля были заменены на красивые чисто асинхронные(пример горбатой и нормальной очереди я уже приводил в этой теме).
Go to the top of the page
 
+Quote Post
amaora
сообщение Sep 14 2016, 12:55
Сообщение #152


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Попробую нарисовать задачу, словами:

1. Основная часть работы в устройстве делается на прерываниях с высоким приоритетом, с этом вопросов нет, здесь никакая ОС не нужна.
2. Вспомогательная задача обработки текстовых команд приходящих по USART или CAN. Она может вызывать множество разных функций, большинство из которых вызывает printf. Который далее вызывает отправку в драйвер интерфейса (USART или CAN). В этом месте можно заблокироваться, данных выводится много а памяти под буфер мало.
3. Вспомогательная задача низкого приоритета, чисто вычислительная и очень тяжелая (считается ~10 с). Ее не нужно успевать считать в заданное время, достаточно как можно скорее. Из-за нее не должна остановится обработка текстовых команд.

Вопрос, как нужно будет написать код функции printf при использовании SST?
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 14:02
Сообщение #153


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Задача отлично ложится на SST. Понадобится неблокирующий printf, о его реализации позже.
CODE

enum{
TASK2_PRIORITY = 2, // higher
TASK3_PRIORITY = 1, // lower
}

// Собственно задача 2.
class Task2{
public:
Task2();
void operator()(uint8_t ch){
parse(ch);
} // можно обрабатывать не только по одному байту, но и сразу все, что есть в очереди, это лишь пример

private:
// это функция обработки, реализуем ее позже
void parse(uint8_t ch);
};

// Определяем очередь uart
struct UartQueue:
// размер нашей очереди - 32 байта. Он зависит от скорости работы порта и времени отработки остальных прерываний.
// Зачастую 16-32 байта вполне достаточно, но можем увеличить, все равно отказавшись от RTOS у нас появилось много памяти
public UmFifo_spsc_pop<uint8_t,Task2,TASK2_PRIORITY,32>
{
UartQueue():
UmFifo_spsc_pop(Task2())
{}
};

// Создаем очередь
// Данные в эту очередь можно пихать прямо из прерывания UART, в том числе через DMA
UartQueue uart_queue;
// Готово, теперь при поступлении данных Uart(или CAN) в очередь автоматически запустится
// обработчик Task2::operator() для их обработки.


// Низкоприоритетная задача
// Допустим, мы ее запускаем, когда у нас есть данные для обработки. Работает она 10 секунд и выходит
void run_task3(const Data* data){
SST::postMessage([data](){
// тут делаем очень тяжелую работу

}, TASK3_PRIORITY);
}

С этим думаю все понятно. Сейчас расскажу про printf.

Теперь printf.
Признаюсь, у меня пока нет реализации последовательного printf, я просто накидываю аргументы в очередь, память под которую получил за счет отказа от RTOS, от многостековости sm.gif
Нам нужно превратить линейную запись в цепочку вложенных лямбд.
Тут хорошо бы применить Promise https://promisesaplus.com/ , но я еще не дорос до их нормальной реализации на C++.
Поэтому паттерн будет пока такой:
Код
class Printf{
    Printf();

    Printf& operator,(const PrintfArgument& arg); // этой штукой я заряжаю аргументы в очередь,
// но мы хотим супер-экономии памяти, по этому будем делать по-другому
private:
    bool first; // понадобится позже, для определения первый аргумен(формат) или последующие
};

#define printf(args...) (Printf(), ##args)

В итоге мы сможем писать обычные printf-ы, но с callback-ом в конце:
Код
printf("%d %X\n", 123, 456, [](){
    // все, принтф отработал, можем делать что-то другое
});

Осталось реализовать наш operator, PrintfArgument и конструктор Printf.
продолжение следует.
Go to the top of the page
 
+Quote Post
amaora
сообщение Sep 14 2016, 14:10
Сообщение #154


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



А где самое главное, что будет вместо блокирующего putc в функциях печати чисел и строк?

По верхнему уровню, где вызывается printf. Что делать, если уровень вложенности становится большим? Так будет если раньше в коде было вот такое:

Код
do_something();
wait_for_something();
printf("something ...");

do_something();
wait_for_something();
printf("something ...");

do_something();
wait_for_something();
printf("something ...");

...



Сообщение отредактировал amaora - Sep 14 2016, 14:23
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 14:21
Сообщение #155


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



В принципе тут без очереди все равно не обойдется - все равно где-то надо хранить аргументы printf. В блокинге мы их храним на стеке, а в нон-блокинге нужно хранить где-то в другом месте. Памяти займет это все равно меньше, чем резервировать стек.
Только в очереди будем хранить не сами печатаемые символы, а указатели на строки, числа итд, в общем аргументы функции, их у нас не много.
Тут как-раз рулит Раст, он не даст нам закинуть указатель на стековую строку, например, но мы делаем на плюсах, поэтому будем обходится тем, что есть.
В принципе такая реализация у меня есть. Приведу в удобоваримый вид и покажу.
Go to the top of the page
 
+Quote Post
amaora
сообщение Sep 14 2016, 14:33
Сообщение #156


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Ну допустим будем хранить аргументы printf. Проблемы языков C и C++ не рассматриваем.

Выводим первый аргумент, вызывает функцию печати float, и на выводе символа разделителя кончилось место в буфере. Надо выходить и сохранять это промежуточное состояние? Или запастись отдельным буфером для float гарантированно достаточной длины, и запоминать его?

Как-то стало ясно, ничего иного не ожидал, сам долго думал как обойтись без вытесняющей rtos.

Сообщение отредактировал amaora - Sep 14 2016, 14:34
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 14:47
Сообщение #157


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



И так вот. У нас появилась еще одна задача - printf. Назначим ей приоритет Printf_TASK_PRIORITY=3, тк она отрабатывает очень быстро, но можно и 2.
Код
class PrintfTaskQueue : public TaskQueue{
public:
    PrintfTaskQueue(): TaskQueue(Printf_TASK_PRIORITY){}
};

PrintfTaskQueue printf_queue;

Printf::Printf(){
    printf_queue.enqueueTask([this](){
        first = true;
    });
}

Printf& Printf::operator,(const PrintfArgument& arg){
    printf_queue.enqueueTask(arg);
    return *this;
}

Далее нам останется описать сам PrintfArgument, этим сейчас и займемся.

Цитата(amaora @ Sep 14 2016, 17:33) *
Ну допустим будем хранить аргументы printf. Проблемы языков C и C++ не рассматриваем.

Выводим первый аргумент, вызывает функцию печати float, и на выводе символа разделителя кончилось место в буфере. Надо выходить и сохранять это промежуточное состояние? Или запастись отдельным буфером для float гарантированно достаточной длины, и запоминать его?

Как-то стало ясно, ничего иного не ожидал, сам долго думал как обойтись без вытесняющей rtos.

Все эти флоаты у РТОС хранятся на стеке, а у нас будут в очереди. Места займут меньше, чем в стеке, это естественно.

Блокинг:
Код
do_something();
wait_for_something();
printf("something ...");

do_something();
wait_for_something();
printf("something ...");

do_something();
wait_for_something();
printf("something ...");

Тут либо надо использовать Promise, который реализовать на плюсах не просто, либо просто callback hell(куча вложенних лямбд)
Код
do_something([this](){
    printf("something ...",[this](){
        do_something([this](){
            printf("something ...", [this](){
                do_something([this](){
                    printf("something ...", on_finish);
                });
            });
        });
      });
});

либо разделять на отдельные функции, а состояние хранить в классе(вместо стека) - из за слабости языка С++.
Я пока использую hell, или разделение цепей вложенных вызовов на фанкции, чтобы код не разростался вправо. Возможно в будущем удастся реализовать compile-time промисы.
Togda буде что-то типа этого:
Код
Promise(
    do_something_nonblocking()).then(
    printf_nonblocking("something...")).then(
    do_something_else_nonblocking()).then(finish);

Для удобной работы нужна компиляторная языковая поддержка, компиляторы только недавно начали двигаться в асинхронный стиль, новшества С++ 11 хоть как-то помогают работать, но это еще очень слабая поддержка. Возможно у Rust она будет мощнее https://github.com/alexcrichton/futures-rs .
В то время, как блокирующий стиль давно поддерживается всеми, в том числе и железом. Над асинком еще нужно попотеть, чтобы он стал удобным, но, как говорится, Москва тоже не сразу строилась. В динамических языках поддержка уже довольно мощная, а в статических пока очень слабая либо вообще отсутствует.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 14 2016, 18:33
Сообщение #158


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



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

Подитожим немного. Sizeof объектов уже растет для сохранения состояния, это мы выяснили. Очереди памяти требуют это мы тоже выяснили. Изобретать надо всё своё, в том числе принтф. А из-за небольшого прикольчика с разным кол-вом и типами аргументов тут придется задуматься... Классно. Продолжаем. Попкорна еще много ))

Вам не кажется, что у вас дело дошло до того, что вы реализуете всё на SST только ради того, чтобы реализовать что-нибудь на SST?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 14 2016, 19:00
Сообщение #159


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(sigmaN @ Sep 14 2016, 23:33) *
Понеслааась.

Зря вы так ополчились на brag-а. Он говорит весьма интересные вещи. Постарайтесь их вычленить из странных высказываний про JS и Rust:)
Что касаемо обсуждаемой задачи с printf - сравните 2 варианта:
  1. N задач висят в ожидании освобождения устройства печати
  2. N задач поочерёдно быстренько запулили свои сообщения в очередь и завершились.

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

Я почему этой темой заинтересовался. Просто стал обращать внимание, что у меня в проектах с использованием RTOS процессы используют в основном два сценария:
  1. подождал флага - быстро обработал
  2. нечто вроде Active Object (это я сейчас прочитал, что такая техника называется Active Object, до этого не знал, что она так называется).

Судя по описанию, такие проекты очень хорошо должны лечь на SST. Жду примера с мигалкой светодиодом, чтоб пощупатьsm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 14 2016, 19:13
Сообщение #160


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну я давно говорил, что в реальном мире оба подхода живы и это не просто так.
Моя придирчивость это противовес фанатичному переписыванию всего и вся, как предлагает нам пропагандист SST )))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 19:42
Сообщение #161


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



sizeof растет, но памяти в целом надо меньше, раз в 8, когда потоков много. А когда парочка - раза в 2 меньше.
printf и так давно свой и не потому что SST, а потому что он типобезопасный, в отличии от стандартного сишного. Сначала у меня был блокирующий, а потом стал неблокирующий printf.

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

Главное, чтобы запросов на печать в секунду было меньше, чем успевает пропустить сам порт, в который печатаем. Но если не успеет - не беда, просто переполнится очередь и часть данных потеряется.
В блокинге все равно хуже - будут тормоза всей системы, тк все компоненты системы, которые хотят принтф-ить будет ожидать заваленный порт какой-то одной, хуже того, низкоприоритетной задачей. В SST такой инверсии приоритетов нет(см картинку выше) .

Такой простой принтф пишется за пол дня, не думаю, что это много. Остальной код приведу(класса PrintfArgument), просто сейчас нет времени выдрать и привести в удобоваримый вид. Но многие, уже наверное догадались что там - создание обработчика события и добавление его в очередь.

Цитата
Судя по описанию, такие проекты очень хорошо должны лечь на SST. Жду примера с мигалкой светодиодом, чтоб пощупатьsm.gif

Да, ложится, как влитое, правда к стилю придется привыкнуть ну и местами может быть callback-hell (пирамидка), хотя много где в продакшн-коде он тоже есть, так что это не страшно.

Демо-проект будет. Какая платформа предпочтительнее? ПК или какой-то МК? Может демо-плата какая-то стандартная? Помогите определится..

Цитата
Моя придирчивость это противовес фанатичному переписыванию всего и вся, как предлагает нам пропагандист SST )))

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

Например я недавно функцию sqrt сам написал(извлечение квадратного корня), но она не простая, она шаблонная и понимает как обычные int, так и большие числа (big-integer), до 65536 бит длиной, в том числе и комплексные sm.gif И сделал это не ради того, чтобы сделать, а задолбался от использования кривых и глючных библиотек и постоянного контроля типов.
А рядом с ней есть еще специализировання для float/double, которая завернута на стандартную. Вызвал sqrt для любого типа и готово, да и работает моя реализация быстрее этих кривых сишных поделок, местами раза в 2-4.

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

Повторюсь еще раз - блокинг-код тут не работает, если в предполагаемой либе нет async-io, значит на sst она работать не будет. Тут чисто асинхронный стиль в духе NodeJS и др.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Sep 14 2016, 20:11
Сообщение #162


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(AHTOXA @ Sep 14 2016, 22:00) *
[*] N задач поочерёдно быстренько запулили свои сообщения в очередь и завершились.
Думаю, что второй вариант гораздо выигрышнее и по памяти и по быстродействию. К тому же есть отличные, типобезопасные реализации printf на плюсах, которые будет проще сделать неблокирующимися, чем штатный printf.


А не смущает ли то, что ради этой фишки с printf-ом вам надо все! задачи в своей системе сделать без циклов.
Т.е. все задачи должны вызываться как функции и возвращать управление за конечное время.

А известно ли уважаемому brag-у что у нас в отрасли встраиваемых систем многие пакеты идут в виде скомпилированных либ с уже реализованными там циклическими задачами.

Но я на 100% уверен что, brag не перепишет и обычные открытые стеки TCP или USB где всегда есть циклическая задача на прием.
Эт я еще не упоминаю циклические задачи серверов, сессий, всяких драйверов и т.д.

Что интересно, стек то не сильно экономится в этом АКОП-е.
Общий-то он общий, но за то надо думать как поместить в него все стеки задач и прерываний во всех мыслимых комбинациях.
Из-за этого будет сделан наверняка огромный запас, процентально больший чем запас в стеках обычных задач RTOS.

Хуже того, если в RTOS стек то можно еще и просто посчитать и прецизионно выделить, то в AKOП-е это уже практически нереализуемо, когда более десятка разнообразных задач.

Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 20:44
Сообщение #163


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
Но я на 100% уверен что, brag не перепишет и обычные открытые стеки TCP или USB где всегда есть циклическая задача на прием.
Эт я еще не упоминаю циклические задачи серверов, сессий, всяких драйверов и т.д.

Это написани давно, циклов там нет. Например в USB данные ловятся в обработчике прерываний без всяких ожиданий, и в конце стека(например CDC) отправляются в очередь пользователю.
Например вот функция чтения с CDC.
Код
uint32_t UsbCdc::read(uint32_t *data32, uint32_t len8, const delegate<void(int)>& rdXfrc){
  // must never happen
    if(!isReady())return Error::NOT_READY;
    if(isReadBusy())return Error::BUSY;

    this->rdXfrc = rdXfrc;

        // добавление задачи в очередь конкретного endpoint
//  По окончанию чтения(фактически это просто прерывание) будет вызвана rdXfrc
    Usb::getInst()->core()->epOutXfr(USB_CDC_EP_OUT,data32,len8, this);
    return 0;
}

Аналогичное и в коде MSC(mass storage) и других классах. Работает изумительно и без тормозов, на RTOS была производительность ниже из за накладных расходов на циклы и переключение контекста.
Код да, не публичный, но какие-то части его публиковать имею право.

Задач в сложном проекте не десяток, их там несколько десятков, а то и сотня.
Стек да, с одной стороны считается еще труднее, чем в RTOS, а с другой - время жизни задач очень короткое, вся рекурсия идет все равно через очереди.
Я как обычно делаю: Выбираю самую тяжелую по стеку задачу для каждого уровня приоритета (не вручную ессно, этим занимается софт), потом эти числа суммирую и накидываю сверху процентов 20 запаса.
Смысл в чем - если задача в данном приоритете начала работу - она не может быть прервана другой задачей этого же приоритета или более низкого. Получается, в худшем случаи, если все самые тяжелые задачи каждого приоритета вытеснят одна другую по цепочке - это наихудший случай, на практике маловероятен.

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

Потом ОЗУ заполняется данными сверху, а стеком снизу. Нет необходимости вообще что-то выделять. Если есть MPU - данные защищаю им, если стек туда долезет - будет глюк, но он залогируется MPU. РТОС по любому больше расходует памяти, тк у SST стек плотный, а у РТОС каждый стек имеет пустоты, и это без учета того, что есть еще TCB и всякие другие конструкции(те же семафоры тоже память занимают), которых в SST нет. В SST есть очереди, но и в РТОС-коде они тоже обычно есть. Без них - это полный ад.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 14 2016, 20:54
Сообщение #164


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(brag @ Sep 15 2016, 00:42) *
Демо-проект будет. Какая платформа предпочтительнее? ПК или какой-то МК? Может демо-плата какая-то стандартная? Помогите определится..

Так вы же написали, что проект будет под PC. Думаю, что это наиболее приемлемый вариант для всех.

Цитата(AlexandrY @ Sep 15 2016, 01:11) *
А не смущает ли то, что ради этой фишки с printf-ом вам надо все! задачи в своей системе сделать без циклов.
Т.е. все задачи должны вызываться как функции и возвращать управление за конечное время.

Я ведь написал, что у меня сейчас практически так и есть.
Что касаемо либ без исходников, и прочих непреодолимых препятствий - наверное можно сделать гибридный проект. Несколько процессов останутся как есть, а те процессы, которые можно сделать неблокирующимися, свернём в один процесс, и их будет крутить SST.
(Но это будет временное решение, ненадолго, просто до того момента, когда brag перепишет все либы в неблокирующем стилеsm.gif))


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
brag
сообщение Sep 14 2016, 21:13
Сообщение #165


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046



Цитата
Так вы же написали, что проект будет под PC. Думаю, что это наиболее приемлемый вариант для всех.

Ок, так и сделаем. Кто захочет - запросто под МК можно будет присобачить, без правки кода. Заглушки только поменять на работу с железом

Цитата
Несколько процессов останутся как есть, а те процессы, которые можно сделать неблокирующимися, свернём в один процесс, и их будет крутить SST.

Трудно совместить SST-планировщик с готовой РТОС, хотя, думаю можно(от камня сильно зависит и от самой РТОС). Но можно просто актив-object-ов наклепать - будет асинхронный стиль, как у SST, но можно будет пользоваться и блокинг-тредами - для либ, которые не поддерживают асинк. Цена - много памяти под стеки. Общаться между всем этим только через очереди - никаких shared-переменных и мютексов.

Цитата
(Но это будет временное решение, ненадолго, просто до того момента, когда brag перепишет все либы в неблокирующем стилеsm.gif))

И получит права на их публикацию sm.gif Да куча сейчас либ на самом деле асинхронных или просто независимых от РТОС/блокинга, хотя согласен, есть далеко не все.

Для кортекс вряд ли просто так присобачишь SST к РТОС. В виду его архитектуры пришлось использовать PendSV и SVC, да еще и с трюками. Обычно эти исключения уже заняты РТОС, а рекурсивные прерывания в Кортексе просто так не сделаешь.
Код
__attribute__((naked)) void ePendSV(){
    asm volatile(
        // "push {r0,r4-r11, lr} \n" // not necessary, callee saved
        // create new stack frame for scheduler
        "mov  r2, %0    \n" // PSR
        "movw r1, #:lower16:SST_sync_scheduler  \n" // PC
        "movt r1, #:upper16:SST_sync_scheduler  \n"
        "movw r0, #:lower16:async_scheduler_return  \n" // LR
        "movt r0, #:upper16:async_scheduler_return  \n"
        "push {r0, r1, r2} \n" // push {lr, pc, xPSR}
        "sub sp, #5*4       \n" // push {r0,r1,r2,r3,r12} - undefined values
        // return from exception to scheduler
        "bx lr    \n"
    : :"i"(xPSR_RESET_VALUE));
}

// return to preemtded task through SVC
extern "C" __attribute__((naked)) void async_scheduler_return(){
    asm volatile("svc #0");
}

__attribute__((naked)) void eSVCall(){
    asm volatile(
        // kill current stack frame
        "add sp, #8*4 \n"
        // "pop {r4-r11, lr} \n" // not necessary
        // perform an EXC_RETURN (unstacking)
        "bx lr \n"
    );
}
Go to the top of the page
 
+Quote Post

17 страниц V  « < 9 10 11 12 13 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 12:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01513 секунд с 7
ELECTRONIX ©2004-2016