|
|
  |
Вышла TNKernel 2.7 |
|
|
|
Jul 9 2013, 11:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
благодарю, но хочу высказать свои хотелки, в целях повышения юзабельности 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 и каждый творит что хочет. Но если посчитаете перечисленные хотелки приемлимыми и адекватными, то не плохо чтобы это все появилось в оффициальной версии
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Jul 25 2013, 10:21
|
Участник

Группа: Свой
Сообщений: 69
Регистрация: 22-10-04
Пользователь №: 956

|
Спасибо! немножко дополнений... Код 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
|
|
|
|
|
Jul 15 2014, 16:47
|
Группа: Новичок
Сообщений: 4
Регистрация: 9-09-13
Пользователь №: 78 231

|
Добрый день! Сразу же прошу прощения если мой ламерский вопрос не в тему. Встала задача запустить 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". Как быть?
|
|
|
|
|
Sep 17 2014, 21:42
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Всем привет. Сразу перейду к делу, после чего изложу лирику, если она кому-то интересна. Итак: в 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; Не знаю, заинтересует ли кого-то этот мой проект, но на всякий случай я написал. Спасибо за внимание.
Сообщение отредактировал dimonomid - Sep 17 2014, 21:45
|
|
|
|
|
Sep 18 2014, 10:17
|
Участник

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835

|
Цитата(Valentine Loginov @ Sep 18 2014, 12:16)  Очень интересно, спасибо! А то сейчас на 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Вот таким образом. Уже много раз эти тесты сразу указывали мне, когда я где-то что-то ломал
|
|
|
|
|
Oct 27 2015, 16:18
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
прикрутил к 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 ); } } }
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Oct 30 2015, 09:49
|

Профессионал
    
Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143

|
Цитата(Intel4004 @ Oct 30 2015, 03:40)  А порт для Cortex-M0(M0+) существует? где-то на просторах электроникса лежит tn_port_cm0 ( но не нашел ) но вот давненько выкладывал готовый проект, можете оттуда выдрать
--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
|
|
|
|
|
Oct 30 2015, 14:09
|

Участник

Группа: Участник
Сообщений: 48
Регистрация: 7-09-07
Из: Наб.Челны
Пользователь №: 30 364

|
Цитата(megajohn @ Oct 30 2015, 12:49)  где-то на просторах электроникса лежит tn_port_cm0 ( но не нашел ) но вот давненько выкладывал готовый проект, можете оттуда выдрать Спасибо, выдрал.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|