AlexandrY 3 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба Всё понятно, "Пастернака не читал, но осуждаю". К вашему сведению, scmRTOS издавна поставляется с отличной документацией. ЗЫ. Вам хоть приплачивают за рекламу MQX? Или это вы добровольно? :) А вы сколько на scmRTOS зарабатываете? А что такое? Вау! Есть оказывается. Правда объемом со статью на гиктаймсе. Неудивительно что не заметил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yes 7 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба К линуксу никакого отношения не имеет. Если не думать что родство с линуксом определяется по наличию функций read и write в структурах драйверов. Путаница с линуксом может возникнуть от того, что в MQX есть стек межзадачного взаимодействия портированный в частности и на линукс. Поэтому MQX очень легко связать с линуксом в мультикристальных SoC-ах POSIX это не линукс. Линукс - это полноценная ось, в которой не только posix, но и куча всякого разного. то есть то, что сейчас модно называть экосистемой (+ куча народа, который знает эту экосистему). опять же синтетический таргет - то есть перенос кода с ПК. насколько я понимаю, в том же MQX TCP-шный стек уже за деньги? то есть, я хотел сказать, что если i.mx6, то смысл ставить на него переключалку задач имеет только для каких-то специфических приложений Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба Правда объемом со статью на гиктаймсе. Неудивительно что не заметил. Покажите статью на гиктаймсе объёмом в 140 страниц А4? Раньше думал, вы хоть смотрели доку, раз такие смелые выводы делаете. Оказывается, вам это не надо - вам фантазии для этого достаточно. При этом открывшемся обстоятельстве остальные ваши выводы на любые темы вы обесценили сами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба Покажите статью на гиктаймсе объёмом в 140 страниц А4? Раньше думал, вы хоть смотрели доку, раз такие смелые выводы делаете. Оказывается, вам это не надо - вам фантазии для этого достаточно. При этом открывшемся обстоятельстве остальные ваши выводы на любые темы вы обесценили сами. Ой извиняюсь. Не заметил кнопку "More Pages". :laughing: Да и на кой читать всю эту доку. Грамматические ошибки исправлять? Или рецензировать? Со многим согласен, но многое ужасно запутано. Скажем слово 'порт' в разных смыслах без понятного контекста. Или слово 'объект', ну просто не перевариваемое. Причем тоже где-то 'объект', где-то 'элемент', где-то 'совокупность', где-то 'часть'. Нет строгости соблюдения терминологии. У неопытного крыша съедет. Нет, это я бы не рекомендовал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба Да и на кой читать всю эту доку. Грамматические ошибки исправлять? Найдите хотя бы одну? Скажем слово 'порт' в разных смыслах без понятного контекста. Или слово 'объект', ну просто не перевариваемое. Причем тоже где-то 'объект', где-то 'элемент', где-то 'совокупность', где-то 'часть'. Нет строгости соблюдения терминологии. "Порт" употребляется в обычном смысле для ПО и в контексте RTOS, тут всё однозначно. "Объект" употребляется преимущественно в контексте используемого ЯП С++, что тоже даёт однозначность. В остальном обычный русский язык, с терминологией обращение аккуратное. В начале даже приведён список используемых терминов и сокращений, дабы свести к минимуму непонятности. У неопытного крыша съедет. Похоже, это и наблюдаем. Нет, это я бы не рекомендовал. Как обычно в своём репертуаре: не читал, но не рекомендую. Не знакомы с вопросом - проходите мимо, не нужно шум поднимать по теме, о которой вы ничего не знаете, т.к. не дали себе труда хотя бы бегло ознакомиться с ней. Офтопить прекращаю. Замечу напоследок, что изучать новую тему как правило всегда легче на небольших и неперегруженных примерах и особенно когда имеется подробная документация. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба ... и полистать чужие реализации (замечательная статья про TNeo). А вы в своих проектах используете Тнео? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 7 июня, 2016 Опубликовано 7 июня, 2016 · Жалоба Не знакомы с вопросом - проходите мимо, не нужно шум поднимать по теме, о которой вы ничего не знаете, т.к. не дали себе труда хотя бы бегло ознакомиться с ней. Не получается у него. Человек такой... Пользуясь случаем, хочу сказать "спасибо" за книжку к scmRTOS. Подробно, понятно и с душой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spectr 0 8 июня, 2016 Опубликовано 8 июня, 2016 · Жалоба Еще вопросы. Значит, написал вот такой код: 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 байтам? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 8 июня, 2016 Опубликовано 8 июня, 2016 · Жалоба 3. Не очень понятна запись tasks[tasks_used]->stk_ptr = (uint32_t*) ((uintptr_t) stk_ptr & 0xFFFFFFF8);. Для чего нужно выравнивание по 8 байтам? Там же в комментарии написано, прямо перед этой строчкой. Кстати, правильнее выравнивать стек вот так, чтобы это работало с любым размером контекста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spectr 0 8 июня, 2016 Опубликовано 8 июня, 2016 · Жалоба Там же в комментарии написано, прямо перед этой строчкой. Там написано, что "Архитектура требует выравнивание по 8 байт". А у меня вопрос - почему? Открыл я этот документ, там написано так же непонятно: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 8 июня, 2016 Опубликовано 8 июня, 2016 · Жалоба Там написано, что "Архитектура требует выравнивание по 8 байт". А у меня вопрос - почему? Открыл я этот документ, там написано так же непонятно: Потому что функция printf, например, при распечатке чисел с плавающей запятой всегда их берет с выравниванием по 8 байт, как тип double. Не сделаете выравнивание стека по 8 и получите в задачах неправильную работу функции printf. Говорю же читайте описание от микриума на uC/OS, это первоисточник. Откуда думаете scmRTOS появилась? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spectr 0 8 июня, 2016 Опубликовано 8 июня, 2016 · Жалоба Говорю же читайте описание от микриума на 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); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spectr 0 10 июня, 2016 Опубликовано 10 июня, 2016 · Жалоба Вопрос по прерыванию PendSV_Handler. В нем выполняется переключение с одной задачи на другую, но мне непонятно кто его должен вызывать. Планировщик? Если планировщик, то зачем вызывать отдельное прерывание, когда переключение на другую задачу можно и без ухода в прерывание сделать. Я нигде не увидел чтобы PendSV в явном виде где-то вызывалось... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 10 июня, 2016 Опубликовано 10 июня, 2016 · Жалоба Если планировщик, то зачем вызывать отдельное прерывание, когда переключение на другую задачу можно и без ухода в прерывание сделать. Я нигде не увидел чтобы PendSV в явном виде где-то вызывалось... В прерывании повышаются привилегии. Странно почему вы не видите, во всех вызовах стоят _set_pend_sv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spectr 0 10 июня, 2016 Опубликовано 10 июня, 2016 · Жалоба Правильно ли я понимаю, что PendSV используется так: Ему выставляется нижайший приоритет. Если в данный момент есть что делать - делаем (ну, цикл какой или работа с периферией). Если делать нечего или мы сидим в прерывании и нам нельзя там долго находиться, то что-то делаем по-быстрому и взводим флажок-запрос на PendSV. Как только все остальные работающие в данный момент прерывания завершатся, проц, видя флажок-запрос, автоматом уходит в PendSV, т.к. теперь ему теперь совсем нечем заняться и можно спокойно уйти на обработку самого низкоприоритетного PendSV. В планировщике, если есть живые задачи, также взводится этот флаг, чтобы по наступлению таймаута процессор ушел в PendSV и таким образом выполнил переключение. Либо в коде самой задачи, в ее самом конце (когда она завершила свою работу согласно алгоритму), делается принудительная установка флажка-запроса на PendSV. Все так? Странно почему вы не видите, во всех вызовах стоят _set_pend_sv Спасибо, рассмотрел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться