yuri_t 0 6 июля, 2013 Опубликовано 6 июля, 2013 · Жалоба Эта версия посвящена ,в основном, устранению накопившихся багов. Огромное спасибо всем участникам проекта TNKernel !!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 9 июля, 2013 Опубликовано 9 июля, 2013 · Жалоба благодарю, но хочу высказать свои хотелки, в целях повышения юзабельности 1. добавить контроль стека в tn_port_cm3_iar.s. Хотя бы закоменченным блоком. Кому надо разкоментят на этапе отладки. 2. вынести TN_CHECK_PARAM, TN_MEAS_PERFORMANCE, USE_MUTEXES, USE_EVENTS из tn.h в tn_config.h. Как это реализовано в прочих ОС 3. добавить mailbox. Повышает функциональность за счет увеличенного трансфера данных между задачами 4. сделать TN_FILL_STACK_VAL оффициальным 0xDEADBEEF 5. в tn_event_wait сделать p_flags_pattern необязательным 6. в TN_TCB опциональные поля под дефайнами USE_MUTEXES и USE_EVENTS перенести в хвост структуры. Это для унификации пункта 1 и будущих асмовских проверок P.S. это я всё у себя реализовал. И понимаю что TNKernel is free и каждый творит что хочет. Но если посчитаете перечисленные хотелки приемлимыми и адекватными, то не плохо чтобы это все появилось в оффициальной версии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Grape 0 25 июля, 2013 Опубликовано 25 июля, 2013 · Жалоба Спасибо! немножко дополнений... diff -urN 2.7/TNKernel/tn.c 2.7_mod/TNKernel/tn.c --- 2.7/TNKernel/tn.c 2013-07-01 10:29:34.000000000 +0400 +++ 2.7_mod/TNKernel/tn.c 2013-07-16 12:42:45.687500000 +0400 @@ -238,12 +238,12 @@ TN_CHECK_NON_INT_CONTEXT - tn_disable_interrupt(); - if(priority <= 0 || priority >= TN_NUM_PRIORITY-1 || value < 0 || value > MAX_TIME_SLICE) return TERR_WRONG_PARAM; + tn_disable_interrupt(); + tn_tslice_ticks[priority] = value; tn_enable_interrupt(); diff -urN 2.7/TNKernel/tn_event.c 2.7_mod/TNKernel/tn_event.c --- 2.7/TNKernel/tn_event.c 2013-07-01 10:30:42.000000000 +0400 +++ 2.7_mod/TNKernel/tn_event.c 2013-07-16 12:43:43.015625000 +0400 @@ -349,10 +349,12 @@ { TN_INTSAVE_DATA +#if TN_CHECK_PARAM if(evf == NULL || pattern == TN_INVALID_VAL) return TERR_WRONG_PARAM; if(evf->id_event != TN_ID_EVENT) return TERR_NOEXS; +#endif TN_CHECK_NON_INT_CONTEXT diff -urN 2.7/TNKernel/tn_mutex.c 2.7_mod/TNKernel/tn_mutex.c --- 2.7/TNKernel/tn_mutex.c 2013-07-01 10:31:54.000000000 +0400 +++ 2.7_mod/TNKernel/tn_mutex.c 2013-07-16 12:44:39.609375000 +0400 @@ -93,7 +93,7 @@ TN_CHECK_NON_INT_CONTEXT - if(tn_curr_run_task != mutex->holder) + if(mutex->holder && (tn_curr_run_task != mutex->holder)) return TERR_ILUSE; //-- Remove all tasks(if any) from mutex's wait queue Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 7 августа, 2013 Опубликовано 7 августа, 2013 · Жалоба небольшие рекомендации от меня: не использовать printf и прочие тяжелые функции в tn_app_init, так как исполнение этой функции выполняется в контексе сервисной задачи tn_timer_task, у которой стек не большой и по дефолту 64 слова. В результате выхода за пределы стека, портится список tn_ready_list (который как раз находится перед tn_timer_task_stack ) в итоге, получаете удивительные но нерадостные сюрпризы от операционки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 3 октября, 2013 Опубликовано 3 октября, 2013 · Жалоба a вce-тaки пoлeзнaя фичa peaлизoвaнa idle_user_cb вepcии 2.5 для PIC24. Может сделать стандартым для всех портов ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба 9. в фyнкциях tn_event_clear и tn_task_create проверка параметров без условной компиляции 10. при компиляции без TN_CHECK_PARAM поля id_task, id_mutex и прочие id излишны, и только зря "поедают" RAM 11. не плохо бы разместить поля id_task, id_mutex и прочие в режиме TN_CHECK_PARAM разместить в начале структур, чтобы проще выявлять виновников портящих память Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Almaz_emb 0 15 июля, 2014 Опубликовано 15 июля, 2014 · Жалоба Добрый день! Сразу же прошу прощения если мой ламерский вопрос не в тему. Встала задача запустить TNKernel на STM32F401VC. Порядок действий: Скачал порт для Cortex M4 на офф сайте: http://www.tnkernel.com/tn_port_CortexM4.html Из скачанного архива перенес папку "TNKernel" в свой проект. Добавил в проект все исходники, прописал пути к заголовочным файлам, выставил необходимые макроопределения. Теперь пытаюсь написать простейшую программу: #include <tn.h> #define TASK_1_PRIORITY 5 #define TASK_1_STK_SIZE 128 unsigned int task_1_stack[TASK_1_STK_SIZE]; TN_TCB task_1; void task_1_func(void * par); void tn_app_init(void) { } int main( void ) { tn_start_system(); while(1) { } } И тут я получаю сообщения об ошибках: compiling main.c... C:\Keil_v5\ARM\PACK\ARM\CMSIS\4.1.0\CMSIS\Include\core_cmFunc.h(181): error: #247: function "__get_PRIMASK" has already been defined __STATIC_INLINE uint32_t __get_PRIMASK(void) C:\Keil_v5\ARM\PACK\ARM\CMSIS\4.1.0\CMSIS\Include\core_cmFunc.h(194): error: #247: function "__set_PRIMASK" has already been defined __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) src\main.c: 0 warnings, 2 errors ".\output\stm32.axf" - 2 Error(s), 0 Warning(s). Функции __get_PRIMASK() и __set_PRIMASK() в файле "tn_port_cmf4.h" совпадают с одноименными функциями из файла "core_cmFunc.h". Как быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
A. Fig Lee 0 15 июля, 2014 Опубликовано 15 июля, 2014 · Жалоба Кстати, а есть сравнение TNkernel с Coocox? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimonomid 0 17 сентября, 2014 Опубликовано 17 сентября, 2014 (изменено) · Жалоба Всем привет. Сразу перейду к делу, после чего изложу лирику, если она кому-то интересна. Итак: в TNKernel все еще есть достаточно неприятные баги, и в течении последнего месяца я интенсивно переписываю TNKernel, исправляя найденные ошибки. Ошибки обнаруживаются с помощью подробных unit-тестов (которые я тоже аккуратно пишу), благодаря чему стабильность системы реально повышается, а вероятность добавления впоследствии новых ошибок снижается. Судя по найденным багам, оригинальная TNKernel тестировалась только "вручную", без формализованных тестов, что печально. Текущий список найденных и исправленных багов: * если в tn_sys_tclice_ticks() переданы неверные параметры, то возвращается TERR_WRONG_PARAM и прерывания остаются запрещенными * есть три задачи: две низкоприоритетные с одинаковым приоритетом task_low1 и task_low2; и одна высокоприоритетная task_high. Теперь: task_low1 блокирует мютекс М1 (с алгоритмом повышения наследования приоритета), потом task_low2 пытается тоже его заблокировать и уходит в ожидание, потом task_high тоже пытается его заблокировать и тоже уходит в ожидание -> приоритет task_low1 повышается до приоритета task_high. Теперь task_low1 разблокирует мютекс, следующая задача в очереди - task_low2, она его блокирует, и ее приоритет должен быть повышен до приоритета task_high (т.к. она все еще его ждет), но этого не происходит: высокоприоритетная task_high продолжает ждать задачу task_low2, приоритет которой низкий. * низкоприоритетная задача task_low блокирует мютекс М1 (с алгоритмом повышения наследования приоритета), высокоприоритетная задача task_high тоже пытается его заблокировать и уходит в ожидание -> приоритет task_low повышается до приоритета task_high; теперь task_high выходит из ожидания по таймауту -> приоритет task_low остается повышенным. То же самое происходит, если task_high была остановлена с помощью tn_task_terminate. * tn_mutex_delete() - если мютекс не заблокирован, то возвращается TERR_ILUSE. То есть, чтобы удалить мютекс, нужно сначала его заблокировать. Это неправильно. Проект размещен на bitbucket: ссылка. Как получилось, что я вообще занялся этим: сначала я долгое время пользовался портом Alex.B для PIC32, не особо вникая в то, как работает это ядро; потом в какой-то момент меня очень расстроил тот факт, что в нормальном режиме работы контекст может быть сохранен в стек задачи два и более раз. Плюс к этому, мне уже давно надоели проблемы, связанные с тем, что для прерываний используется стек задачи, которую оно прервало (вместо отдельного стека для прерываний) - на это тратится куча RAM, которой и так вечно не хватает, и я начал искать другой порт. Нашел: это порт от Anders Montonen, в котором для прерываний используется отдельный стек, поддерживаются вложенные прерывания и shadow register set. Но в этом порте отсутствовали некоторые вкусности, которые есть в порте Alex.B: как минимум, там не было удобных Сишных макросов для определения прерываний, и еще сам TNKernel должен быть собран в составе проекта, без возможности выделить его в отдельную либу. Таким образом, я решил допилить его для себя. Anders Montonen хочет оставить свой порт настолько близко к апстриму, насколько возможно, поэтому мне оставалось только форкнуть его. Далее, чем больше я вникал в TNKernel, тем меньше мне нравился ее код. Подробно см. на страничке моего проекта Why refactor?, все переписывать сюда не буду, изложу кратко: очень много дублирования кода, нет централизованных методов чтобы делать многие вещи, таким образом, одно и то же реализовано в куче мест просто копи-пастом (именно это является причиной изложенных выше багов с мютексами). Почти в каждой функции есть много точек выхода, почти перед каждым оператором return - разрешение прерываний. Это нарушение очень хорошего правила: "одна точка входа - одна точка выхода". Если бы это правило соблюдалось, то ошибка в tn_sys_tclice_ticks() никогда не появилась бы. Должен сказать, что в своих "текущих" проектах я иногда позволяю себе вольности (хоть и знаю, что могу навлечь на себя беду), и далеко не всегда у меня получается код, который мне очень нравится. Но ядро - особый проект; и я хочу чтобы код ядра был как можно более близок к идеальному. Поэтому я решил заняться этим, хотя это отнимает сейчас все мое свободное время: работы очень много. В данный момент большинство кода уже переписано таким образом, чтобы код дублировался как можно меньше. Если есть два похожих сервиса (например, tn_fmem_release() и tn_fmem_irelease()), то основная работа производится в одном месте, а вышеуказанные сервисы являются только обертками, совершающими соответствующие вступительные и заключительные действия. И так во всем остальном. Больше всего путаницы с мютексами и их алгоритмами управления приоритетами задач; tn_mutex.c и tn_tasks.c переписаны, наверное, процентов на 70%. Насчет тестов: на данный момент написаны очень подробные тесты для мютексов, чуть менее подробные тесты для управления задачами. Остальное - в скором (надеюсь) будущем. О некоторых проблемах (например, про баг в tn_sys_tclice_ticks и про путаницу с макросом MAKE_ALIG) я писал Юрию на почту, он ничего не ответил: видимо, потерял интерес. Некоторые детали API были изменены, т.к. они мне не нравятся; конкретно об изменениях тут: Differences from original TNKernel. Скорее всего, впоследствии API будет еще изменяться (т.к. я еще не все поправил, что мне не нравится), но по возможности оставлю слой совместимости с оригинальным TNKernel. Вообще, изменений уже очень много (например, нет timer task - подробнее об этом по ссылке выше, хотя на API это не влияет), и будет еще больше, так что совместимость с оригинальной TNKernel будет, конечно, не абсолютная. Чтобы не вводить в заблуждение, возможно, придется выбрать новое название. Возможно, это будет TNeoKernel - и безусловная причастность к TNKernel указана (Юрий, большое спасибо вам за этот проект), и добавлена частичка Neo, которая указывает на некую новизну =) В настоящий момент существует только порт для PIC32; Не знаю, заинтересует ли кого-то этот мой проект, но на всякий случай я написал. Спасибо за внимание. Изменено 17 сентября, 2014 пользователем dimonomid Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
becopt 0 18 сентября, 2014 Опубликовано 18 сентября, 2014 · Жалоба Очень интересно, спасибо! А то сейчас на pic'ах грустно с качественными ОСРВ, а в своё время tn_kernel очень нравился :) Хотелось бы узнать: есть ли возможность посмотреть проекты с unit-test'ами? Тесты очень часто помогают понять логику API больше, чем документация. Да и вообще интересно на какой платформе тестируется: x86, pic-mips или совместно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimonomid 0 18 сентября, 2014 Опубликовано 18 сентября, 2014 · Жалоба Очень интересно, спасибо! А то сейчас на pic'ах грустно с качественными ОСРВ, а в своё время tn_kernel очень нравился :) Хотелось бы узнать: есть ли возможность посмотреть проекты с unit-test'ами? Тесты очень часто помогают понять логику API больше, чем документация. Да и вообще интересно на какой платформе тестируется: x86, pic-mips или совместно? Спасибо за интерес =) Проект с юнит-тестами пока один, гоняю в железе на своем PIC32MX440F512H (камень, использующийся в текущем проекте на моей работе), вывожу лог в UART. Конечно я покажу его, но сразу предупрежу: его код пока не такой вылизанный: к сожалению, мое open-source время ограничено и на все не хватает, но когда я смогу найти время и причесать его, то размещу ссылку на странице самого ядра. Как в целом работают тесты: есть задача с самым высоким приоритетом (типа test_director), она создает себе рабочие задачи(A, B, C, ...), создает объекты (например, мютексы: M1, M2, ...), говорит задачам что делать, и проверяет, что после этого получилось. Вкратце, код тестов выглядят примерно так: TNT_TEST_COMMENT("A locks M1"); TNT_ITEM__SEND_CMD_MUTEX(TNT_TASK__A, MUTEX_LOCK, TNT_MUTEX__1); TNT_ITEM__WAIT_AND_CHECK_DIFF( TNT_CHECK__MUTEX(TNT_MUTEX__1, HOLDER, TNT_TASK__A); TNT_CHECK__MUTEX(TNT_MUTEX__1, LOCK_CNT, 1); TNT_CHECK__TASK(TNT_TASK__A, LAST_RETVAL, TERR_NO_ERR); ); TNT_TEST_COMMENT("B tries to lock M1 -> B blocks, A has priority of B"); TNT_ITEM__SEND_CMD_MUTEX(TNT_TASK__B, MUTEX_LOCK, TNT_MUTEX__1); TNT_ITEM__WAIT_AND_CHECK_DIFF( TNT_CHECK__TASK(TNT_TASK__B, LAST_RETVAL, TWORKER_MAN__LAST_RETVAL__UNKNOWN); TNT_CHECK__TASK(TNT_TASK__B, WAIT_REASON, TSK_WAIT_REASON_MUTEX_I); TNT_CHECK__TASK(TNT_TASK__A, PRIORITY, priority_task_b); ); TNT_TEST_COMMENT("A deletes M1"); TNT_ITEM__SEND_CMD_MUTEX(TNT_TASK__A, MUTEX_DELETE, TNT_MUTEX__1); TNT_ITEM__WAIT_AND_CHECK_DIFF( TNT_CHECK__MUTEX(TNT_MUTEX__1, HOLDER, TNT_TASK__NONE); TNT_CHECK__MUTEX(TNT_MUTEX__1, LOCK_CNT, 0); TNT_CHECK__MUTEX(TNT_MUTEX__1, EXISTS, 0); TNT_CHECK__TASK(TNT_TASK__A, LAST_RETVAL, TERR_NO_ERR); TNT_CHECK__TASK(TNT_TASK__A, PRIORITY, TNT_BASE_PRIORITY); TNT_CHECK__TASK(TNT_TASK__B, LAST_RETVAL, TERR_DLT); TNT_CHECK__TASK(TNT_TASK__B, WAIT_REASON, TSK_WAIT_REASON_DQUE_WRECEIVE); ); Здесь мы сначала выводим в лог дословный коммент "A locks M1", потом отправляем команду задаче A, чтобы она заблокировала мютекс 1. После чего ждем некоторое время, и проверяем: владелез мютекса 1 должна быть задача А, кол-во блокировок должно быть 1, последнее возвращенное значение - TERR_NO_ERR. Ну и так далее, код тестов должен быть понятен без лишних комментариев (я надеюсь). В лог при этом выводится следующее: [18.09 14:04:03] [I]: tnt_item_proceed():0910: ----- Command to task A: lock mutex M1 (0xa0006f14) [18.09 14:04:03] [I]: tnt_item_proceed():0937: Wait 80 ticks [18.09 14:04:03] [I]: _task_worker():0199: [Task A]: locking mutex (0xa0006f14).. [18.09 14:04:03] [I]: _task_worker():0206: [Task A]: mutex (0xa0006f14) locked [18.09 14:04:03] [I]: _task_worker():0160: [Task A]: waiting for command.. [18.09 14:04:03] [I]: tnt_item_proceed():0955: Checking: [18.09 14:04:03] [I]: * Task A: priority=6 (as expected), wait_reason=DQUE_WRECEIVE (as expected), last_retval=TERR_NO_ERR (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Task B: priority=5 (as expected), wait_reason=DQUE_WRECEIVE (as expected), last_retval=NOT-YET-RECEIVED (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Mutex M1: holder=A (as expected), lock_cnt=1 (as expected), exists=yes (as expected) [18.09 14:04:03] //-- B tries to lock M1 -> B blocks, A has priority of B (line 90 in ../source/appl/appl_tntest/appl_tntest_mutex.c) [18.09 14:04:03] [I]: tnt_item_proceed():0910: ----- Command to task B: lock mutex M1 (0xa0006f14) [18.09 14:04:03] [I]: tnt_item_proceed():0937: Wait 80 ticks [18.09 14:04:03] [I]: _task_worker():0199: [Task B]: locking mutex (0xa0006f14).. [18.09 14:04:03] [I]: tnt_item_proceed():0955: Checking: [18.09 14:04:03] [I]: * Task A: priority=5 (as expected), wait_reason=DQUE_WRECEIVE (as expected), last_retval=TERR_NO_ERR (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Task B: priority=5 (as expected), wait_reason=MUTEX_I (as expected), last_retval=NOT-YET-RECEIVED (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Mutex M1: holder=A (as expected), lock_cnt=1 (as expected), exists=yes (as expected) [18.09 14:04:03] //-- A deletes M1 (line 99 in ../source/appl/appl_tntest/appl_tntest_mutex.c) [18.09 14:04:03] [I]: tnt_item_proceed():0910: ----- Command to task A: delete mutex M1 (0xa0006f14) [18.09 14:04:03] [I]: tnt_item_proceed():0937: Wait 80 ticks [18.09 14:04:03] [I]: _task_worker():0227: [Task A]: deleting mutex (0xa0006f14).. [18.09 14:04:03] [I]: _task_worker():0208: [Task B]: mutex (0xa0006f14) locking failed with err=-10 [18.09 14:04:03] [I]: _task_worker():0160: [Task B]: waiting for command.. [18.09 14:04:03] [I]: _task_worker():0234: [Task A]: mutex (0xa0006f14) deleted [18.09 14:04:03] [I]: _task_worker():0160: [Task A]: waiting for command.. [18.09 14:04:03] [I]: tnt_item_proceed():0955: Checking: [18.09 14:04:03] [I]: * Task A: priority=6 (as expected), wait_reason=DQUE_WRECEIVE (as expected), last_retval=TERR_NO_ERR (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Task B: priority=5 (as expected), wait_reason=DQUE_WRECEIVE (as expected), last_retval=TERR_DLT (as expected), state=WAIT (as expected) [18.09 14:04:03] [I]: * Mutex M1: holder=NONE (as expected), lock_cnt=0 (as expected), exists=no (as expected) Если что-то пойдет не так, то будет не "as expected", а подробности, что именно ожидалось и что получилось, и тесты останавливаются. Репозиторий можно получить так (будет скачан "environment" репозиторий с несколькими подрепами, одна из подреп - собственно, сам проект с тестами, остальные - либы, их немного) : hg clone http://hg.dfrank.ru/rtos_check/_env rtos_check Файл со всеми тестами мютексов: hg.dfrank.ru/rtos_check/project_common/files/tip/fw_tmp_bk16/appl/source/appl/appl_tntest/appl_tntest_mutex.c Файл со всеми тестами задач (пока их немного) : hg.dfrank.ru/rtos_check/project_common/files/tip/fw_tmp_bk16/appl/source/appl/appl_tntest/appl_tntest_tasks.c Лог всех тестов: http://vpaste.net/gsfGv Вот таким образом. Уже много раз эти тесты сразу указывали мне, когда я где-то что-то ломал :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 27 октября, 2015 Опубликовано 27 октября, 2015 · Жалоба прикрутил к TnKernel систему runtime контроля стеков задач, и текущего состояния задач. Кому интересно делюсь пример 19:40:53 priorty stkuse% cpu 19:40:53 tskname state bse/cur cur/max use% ProgCntr pwait_que mut... 19:40:53 tn_tmr wait slep 0/ 0 28/ 35 0 0x0000ECCE 0x00000000 19:40:53 tn_idle runnable 31/ 31 38/ 38 99 0x0001CB8E 0x00000000 19:40:53 init dormant 2/ 2 8/ 60 0 0x0001452D 0x00000000 19:40:53 dprintf runnable 18/ 18 37/ 55 0 0x0000DDC4 0x00000000 19:40:53 sdc wait queR 5/ 5 9/ 29 0 0x0000DDC4 0x1000C674 19:40:53 algo wait slep 16/ 16 8/ 42 0 0x00005A84 0x00000000 19:40:53 sysobs runnable 8/ 8 17/ 69 0 0x00005A84 0x00000000 19:40:53 led runnable 19/ 19 23/ 23 0 0x00005A84 0x00000000 19:40:53 calldir runnable 11/ 11 17/ 42 0 0x00005A84 0x00000000 19:40:53 sysmon runnable 1/ 1 32/ 35 0 0x0001FC2F 0x00000000 19:40:53 v2sd wait queR 20/ 20 20/ 26 0 0x0000DDC4 0x1000C5F4 19:40:53 collect wait queR 21/ 21 8/ 25 0 0x0000ACF0 0x1000C304 19:40:53 sys wait slep 15/ 15 44/ 86 0 0x00005A84 0x00000000 19:40:53 mdm runnable 7/ 7 13/ 64 0 0x0000DDC4 0x00000000 19:40:53 srvconn wait evnt 17/ 17 23/ 43 0 0x0000877A 0x100019C0 19:40:53 sys wait slep 15/ 15 44/ 81 0 0x00005A84 0x00000000 19:40:53 ftp wait queR 14/ 14 15/ 45 0 0x0000DDC4 0x1000C374 19:40:53 mdm wait queR 7/ 7 13/ 62 0 0x0000DDC4 0x10003594 19:40:53 ssp_tx wait queR 4/ 4 26/ 33 0 0x0000DDC4 0x100088A8 19:40:53 ssp_rx wait evnt 3/ 3 25/ 48 0 0x0000877A 0x10008C10 19:40:53 ssp_tx wait queR 4/ 4 26/ 34 0 0x0000DDC4 0x100081F4 19:40:53 ssp_rx wait evnt 3/ 3 24/ 48 0 0x0000877A 0x1000855C реализация //------------------------------------------------------------------------------ char const* tn_tsk_state_and_wait_rsn2str( int task_state, int task_wait_reason ) { switch( task_state ) { default: return "?????????"; case TSK_STATE_RUNNABLE: return "runnable "; case TSK_STATE_SUSPEND: return "suspend "; case TSK_STATE_WAITSUSP: return "wait sspd"; case TSK_STATE_DORMANT: return "dormant "; case TSK_STATE_WAIT: switch( task_wait_reason ) { case TSK_WAIT_REASON_SLEEP: return "wait slep"; case TSK_WAIT_REASON_SEM: return "wait sem "; case TSK_WAIT_REASON_EVENT: return "wait evnt"; case TSK_WAIT_REASON_DQUE_WSEND: return "wait queS"; case TSK_WAIT_REASON_DQUE_WRECEIVE: return "wait queR"; case TSK_WAIT_REASON_MUTEX_C: return "wait mtxc"; case TSK_WAIT_REASON_MUTEX_C_BLK: return "wait mtxb"; case TSK_WAIT_REASON_MUTEX_I: return "wait mtxi"; case TSK_WAIT_REASON_MUTEX_H: return "wait mtxh"; case TSK_WAIT_REASON_RENDEZVOUS: return "wait rnvs"; case TSK_WAIT_REASON_WFIXMEM: return "wait wfim"; default: return "wait ????"; } } } //------------------------------------------------------------------------------ void tcb2stack_usage( TN_TCB* tcb, unsigned int* curr_prcn_p, unsigned int* max_prcn_p ) { unsigned int* stk_head = tcb->stk_start - tcb->stk_size + 1; unsigned int* stk_p = stk_head; for(; *stk_p == TN_FILL_STACK_VAL; stk_p++ ) { if( stk_p == tcb->stk_start ) break; } unsigned int curr_prcn = 100 - ( tcb->task_stk - stk_head ) * 100 / tcb->stk_size; unsigned int max_prcn = 100 - ( stk_p - stk_head ) * 100 / tcb->stk_size; *curr_prcn_p = curr_prcn; *max_prcn_p = max_prcn; } //------------------------------------------------------------------------------ void task_sysmon_func( void * par ) { #ifndef DEBUG #define SYSMON_PERIOD ( 60 * 1000 ) #else #define SYSMON_PERIOD ( 15 * 1000 ) #endif while( 1 ) { SLEEP( SYSMON_PERIOD ); dprintf( " " " " "priorty " "stkuse%% " "cpu " ); dprintf( " tskname " "state " "bse/cur " "cur/max " "use%% " "ProgCntr " "pwait_que " "mutex_que " "ev_pattern" ); // 11111111 " "???? ???? " "000/000 " "000/000 " "000 " "0x01234567 " "0x01234567 " "0x01234567 " "0x01234567" for( CDLL_QUEUE* p = &tn_create_queue; p->next != &tn_create_queue; p = p->next ) { TN_TCB* tcb = (TN_TCB*)( (u8*)p->next - offsetof( TN_TCB, create_queue ) ); unsigned int curr_prcn, max_prcn; tcb2stack_usage( tcb, &curr_prcn, &max_prcn ); unsigned int curr_cpu = tcb->on_time_count * 100 / SYSMON_PERIOD; tcb->on_time_count = 0; Stn_stack_port_cm3* regs_stk = (Stn_stack_port_cm3*)tcb->task_stk; dprintf( "% 8s " "%s " "% 3d/% 3d " "% 3d/% 3d " "% 3d " "0x%08X " "0x%08X " , tcb->name, tn_tsk_state_and_wait_rsn2str( tcb->task_state, tcb->task_wait_reason ), tcb->base_priority, tcb->priority, curr_prcn, max_prcn, curr_cpu, regs_stk->psr, tcb->pwait_queue, tcb->mutex_queue, tcb->ewait_pattern ); } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intel4004 2 29 октября, 2015 Опубликовано 29 октября, 2015 · Жалоба А порт для Cortex-M0(M0+) существует? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
megajohn 3 30 октября, 2015 Опубликовано 30 октября, 2015 · Жалоба А порт для Cortex-M0(M0+) существует? где-то на просторах электроникса лежит tn_port_cm0 ( но не нашел ) но вот давненько выкладывал готовый проект, можете оттуда выдрать Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intel4004 2 30 октября, 2015 Опубликовано 30 октября, 2015 · Жалоба где-то на просторах электроникса лежит tn_port_cm0 ( но не нашел ) но вот давненько выкладывал готовый проект, можете оттуда выдрать Спасибо, выдрал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться