Перейти к содержанию
    

Всё понятно, "Пастернака не читал, но осуждаю". К вашему сведению, scmRTOS издавна поставляется с отличной документацией.

 

ЗЫ. Вам хоть приплачивают за рекламу MQX? Или это вы добровольно? :)

 

А вы сколько на scmRTOS зарабатываете? :biggrin:

 

 

Вау! Есть оказывается.

 

Правда объемом со статью на гиктаймсе.

Неудивительно что не заметил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К линуксу никакого отношения не имеет. Если не думать что родство с линуксом определяется по наличию функций read и write в структурах драйверов.

 

Путаница с линуксом может возникнуть от того, что в MQX есть стек межзадачного взаимодействия портированный в частности и на линукс.

Поэтому MQX очень легко связать с линуксом в мультикристальных SoC-ах

 

POSIX это не линукс. Линукс - это полноценная ось, в которой не только posix, но и куча всякого разного. то есть то, что сейчас модно называть экосистемой (+ куча народа, который знает эту экосистему). опять же синтетический таргет - то есть перенос кода с ПК.

насколько я понимаю, в том же MQX TCP-шный стек уже за деньги?

 

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

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правда объемом со статью на гиктаймсе.

Неудивительно что не заметил.

Покажите статью на гиктаймсе объёмом в 140 страниц А4?

 

Раньше думал, вы хоть смотрели доку, раз такие смелые выводы делаете. Оказывается, вам это не надо - вам фантазии для этого достаточно. При этом открывшемся обстоятельстве остальные ваши выводы на любые темы вы обесценили сами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покажите статью на гиктаймсе объёмом в 140 страниц А4?

 

Раньше думал, вы хоть смотрели доку, раз такие смелые выводы делаете. Оказывается, вам это не надо - вам фантазии для этого достаточно. При этом открывшемся обстоятельстве остальные ваши выводы на любые темы вы обесценили сами.

 

Ой извиняюсь.

Не заметил кнопку "More Pages". :laughing:

 

Да и на кой читать всю эту доку. Грамматические ошибки исправлять? Или рецензировать?

Со многим согласен, но многое ужасно запутано.

Скажем слово 'порт' в разных смыслах без понятного контекста.

Или слово 'объект', ну просто не перевариваемое. Причем тоже где-то 'объект', где-то 'элемент', где-то 'совокупность', где-то 'часть'. Нет строгости соблюдения терминологии.

У неопытного крыша съедет.

 

Нет, это я бы не рекомендовал.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да и на кой читать всю эту доку. Грамматические ошибки исправлять?

Найдите хотя бы одну?

 

Скажем слово 'порт' в разных смыслах без понятного контекста.

Или слово 'объект', ну просто не перевариваемое. Причем тоже где-то 'объект', где-то 'элемент', где-то 'совокупность', где-то 'часть'. Нет строгости соблюдения терминологии.

"Порт" употребляется в обычном смысле для ПО и в контексте RTOS, тут всё однозначно. "Объект" употребляется преимущественно в контексте используемого ЯП С++, что тоже даёт однозначность. В остальном обычный русский язык, с терминологией обращение аккуратное. В начале даже приведён список используемых терминов и сокращений, дабы свести к минимуму непонятности.

 

У неопытного крыша съедет.

Похоже, это и наблюдаем.

 

Нет, это я бы не рекомендовал.

Как обычно в своём репертуаре: не читал, но не рекомендую. Не знакомы с вопросом - проходите мимо, не нужно шум поднимать по теме, о которой вы ничего не знаете, т.к. не дали себе труда хотя бы бегло ознакомиться с ней.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... и полистать чужие реализации (замечательная статья про TNeo).

А вы в своих проектах используете Тнео?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Не получается у него. Человек такой...

 

Пользуясь случаем, хочу сказать "спасибо" за книжку к scmRTOS. Подробно, понятно и с душой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще вопросы.

 

Значит, написал вот такой код:

main.c:

#define TASK_STK_SIZE 2048
uint32_t task1_stk[TASK_STK_SIZE];

void task1(void* x)
{
    while(1)
    {
        led_toggle(led);
        //printf("@ task1\n");
    }
}

int main(void)
{
    configure_clocks();
    led = led_create(GPIOE, 6);
    
    os_add_task("task1", task1, (void*) 0x555, task1_stk, TASK_STK_SIZE);
    os_start();
    
    while(1);
}

 

scheduler.c:

typedef struct task_descriptor
{
    uint32_t* stk_ptr;
    uint16_t stk_size;
    task_handler handler;
    void* args;
    task_state state;
    char* name;
} task_descriptor;

static uint8_t tasks_used = 0;
static task_descriptor* tasks[MAX_TASKS];

__asm void _run_process(uint32_t* stk_ptr)
{
    LDR     R4, [R0, #(4*14)]
    ADD     R0, R0, #(4*16)
    MSR     PSP, R0
    MOV     R0, #2
    MSR     CONTROL, R0
    
    CPSIE   I
    BX      R4
}


void os_add_task(char* name, task_handler task, void *args, uint32_t* stk_ptr, uint32_t stk_size)
{
    tasks[tasks_used]->name = name;
    tasks[tasks_used]->handler = task;
    tasks[tasks_used]->args = args;
    tasks[tasks_used]->stk_size = stk_size;
    tasks[tasks_used]->state = RUN;
    
    tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) stk_ptr & 0xFFFFFFF8);
    *(--tasks[tasks_used]->stk_ptr) = 0x01000000L;
    *(--tasks[tasks_used]->stk_ptr) = (uint32_t)(task);
    tasks[tasks_used]->stk_ptr -= 14;
    
    //init_stack(task, &stk_ptr[stk_size-1]);
    
    if(tasks_used < MAX_TASKS) tasks_used++;
    printf("# created task: %s\n", name);
}

void os_start(void)
{
    printf("# starting OS...\n");
    _run_process(tasks[0]->stk_ptr);
}

 

 

Инициализацию стека задачи и ассемблерный код пока взял из scmrtos (спасибо за наводку!).

 

Мои вопросы вот в чем:

1. Правильно ли я понимаю: стек задачи - это просто область памяти (в моем случае task1_stk), конец которой заполняется таким образом, чтобы получить в ней значения регистров процессора как при переключении контекста (среди прочего там сидит и указатель на задачу). А далее асмовым (как правило) кодом из этого куска памяти значения тупо переписываются в регистры, после чего все как бы указывает на нужную нам задачу.

 

2. Приведенный выше код вроде как работает - в задачу task1 входит и крутится в ней. Но если раскомментировать printf в задаче task1, то проц уходит в MemFault (MemManage_Handler) сразу же в самой первой команде printf'а (судя по дизассемблеру). Почему так?

 

3. Не очень понятна запись tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) stk_ptr & 0xFFFFFFF8);. Для чего нужно выравнивание по 8 байтам?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3. Не очень понятна запись tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) stk_ptr & 0xFFFFFFF8);. Для чего нужно выравнивание по 8 байтам?

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там же в комментарии написано, прямо перед этой строчкой.

Там написано, что "Архитектура требует выравнивание по 8 байт". А у меня вопрос - почему? Открыл я этот документ, там написано так же непонятно:

image.jpg

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там написано, что "Архитектура требует выравнивание по 8 байт". А у меня вопрос - почему? Открыл я этот документ, там написано так же непонятно:

 

Потому что функция printf, например, при распечатке чисел с плавающей запятой всегда их берет с выравниванием по 8 байт, как тип double.

 

Не сделаете выравнивание стека по 8 и получите в задачах неправильную работу функции printf.

 

Говорю же читайте описание от микриума на uC/OS, это первоисточник.

Откуда думаете scmRTOS появилась? :biggrin:

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Говорю же читайте описание от микриума на uC/OS, это первоисточник.

Действительно, в микриуме формирование стека расписано гораздо понятнее:

CPU_STK  *OSTaskStkInit (OS_TASK_PTR    p_task,
                         void          *p_arg,
                         CPU_STK       *p_stk_base,
                         CPU_STK       *p_stk_limit,
                         CPU_STK_SIZE   stk_size,
                         OS_OPT         opt)
{
    CPU_STK    *p_stk;


    (void)opt;                                                  /* Prevent compiler warning                               */

    p_stk = &p_stk_base[stk_size];                              /* Load stack pointer                                     */
                                                                /* Align the stack to 8-bytes.                            */
    p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8);
                                                                /* Registers stacked as if auto-saved on exception        */
    *--p_stk = (CPU_STK)0x01000000u;                            /* xPSR                                                   */
    *--p_stk = (CPU_STK)p_task;                                 /* Entry Point                                            */
    *--p_stk = (CPU_STK)OS_TaskReturn;                          /* R14 (LR)                                               */
    *--p_stk = (CPU_STK)0x12121212u;                            /* R12                                                    */
    *--p_stk = (CPU_STK)0x03030303u;                            /* R3                                                     */
    *--p_stk = (CPU_STK)0x02020202u;                            /* R2                                                     */
    *--p_stk = (CPU_STK)p_stk_limit;                            /* R1                                                     */
    *--p_stk = (CPU_STK)p_arg;                                  /* R0 : argument                                          */
                                                                /* Remaining registers saved on process stack             */
    *--p_stk = (CPU_STK)0x11111111u;                            /* R11                                                    */
    *--p_stk = (CPU_STK)0x10101010u;                            /* R10                                                    */
    *--p_stk = (CPU_STK)0x09090909u;                            /* R9                                                     */
    *--p_stk = (CPU_STK)0x08080808u;                            /* R8                                                     */
    *--p_stk = (CPU_STK)0x07070707u;                            /* R7                                                     */
    *--p_stk = (CPU_STK)0x06060606u;                            /* R6                                                     */
    *--p_stk = (CPU_STK)0x05050505u;                            /* R5                                                     */
    *--p_stk = (CPU_STK)0x04040404u;                            /* R4                                                     */

    return (p_stk);
}

 

И, что интересно, с таким кодом инициализации стека printf из задачи - заработал :blink:

UPD: собственно говоря, printf заработал и с кодом от scmRTOS. Ошибка была в строке

    tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) stk_ptr & 0xFFFFFFF8);

 

Я неправильно брал вершину стека. Надо так:

    tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) &stk_ptr[stk_size] & 0xFFFFFFF8);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос по прерыванию PendSV_Handler.

 

В нем выполняется переключение с одной задачи на другую, но мне непонятно кто его должен вызывать. Планировщик?

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

 

Я нигде не увидел чтобы PendSV в явном виде где-то вызывалось...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Я нигде не увидел чтобы PendSV в явном виде где-то вызывалось...

 

В прерывании повышаются привилегии.

 

Странно почему вы не видите, во всех вызовах стоят _set_pend_sv

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Правильно ли я понимаю, что PendSV используется так:

 

Ему выставляется нижайший приоритет.

Если в данный момент есть что делать - делаем (ну, цикл какой или работа с периферией).

Если делать нечего или мы сидим в прерывании и нам нельзя там долго находиться, то что-то делаем по-быстрому и взводим флажок-запрос на PendSV.

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

 

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

Либо в коде самой задачи, в ее самом конце (когда она завершила свою работу согласно алгоритму), делается принудительная установка флажка-запроса на PendSV.

 

Все так?

 

Странно почему вы не видите, во всех вызовах стоят _set_pend_sv

Спасибо, рассмотрел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...