hound 0 15 февраля, 2015 Опубликовано 15 февраля, 2015 · Жалоба Добрый вечер, начал работать с TNKernel использую версию 2.7. Есть один вопрос: нужно определенную функцию выполнять через некоторое время системных тиков, сейчас реализовал через задачи подобным образом: #define REBOOT_START 0x00 #define REBOOT_UP 0x01 #define REBOOT_END 0x02 void func_reset(void *par) { uint8_t status = REBOOT_START; uart-send_string("Start activate modem"); while (1) { switch(status_reboot) { case REBOOT_START: GPIOB->BSRR=GPIO_Pin_1; status = REBOOT_UP; tn_task_sleep(3000); break; case REBOOT_UP: GPIOB->BRR=GPIO_Pin_1; status = REBOOT_END; tn_task_sleep(1000); break; case REBOOT_END: send_cmd_device(POWER_UP); tn_task_exit(TN_EXIT_TASK); break; } } } Т.е. создаю задачу без ее запуска при создании, а потом уже в коде программы, там где нужно запустить/перезагрузить девайс я запускаю эту задачу tn_task_activate(&task_reset); Но на сколько это оправданно? Заранее благодарен за ответ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lexszero 0 16 февраля, 2015 Опубликовано 16 февраля, 2015 · Жалоба Но на сколько это оправданно? Код совершенно бессмысленный, стейт-машина не нужна. Почему просто не сделать синхронную функцию и звать ее откуда надо? Все равно пока девайс резетится, вы с ним ничего полезного не сделаете. void reset_device(void) { uart-send_string("Start activate modem"); GPIOB->BSRR = GPIO_Pin_1; tn_task_sleep(3000); GPIOB->BRR = GPIO_Pin_1; tn_task_sleep(1000); send_cmd_device(POWER_UP); } Гораздо проще же. А чтоб несколько потоков не подрались за девайс, обернуть все операции с ним в мютекс, а еще лучше сделать отдельный таск, который полностью будет заниматься управлением девайсом, а с внешним миром взаимодействовать через очереди или эвенты. Код писать уж не буду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hound 0 21 февраля, 2015 Опубликовано 21 февраля, 2015 · Жалоба Да, действительно очень и очень глупая ошибка...конечно же проще все делать в одном таске, чем городить новые. Спасибо за разъяснение. Но появился следующий вопрос. После того как мы подали на некоторое время сигнал на ножку девайса нам нужно его настроить и если он не отвечает то его снова перезагрузить подачей сигнала на ножку. Как я себе представляю данный код в таком случае: void task_device(void *par) { while (1) { dbg_send("Reboot device\r\n"); GPIOB->BSRR=GPIO_Pin_1; tn_task_sleep(3000); GPIOB->BRR=GPIO_Pin_1; tn_task_sleep(2000); if (check_device() == ACTION_FAIL) continue; if (change_setting() == ACTION_FAIL) continue; while (1) { rc = tn_queue_receive_polling(&queue_modem_send_data, (void **)&pos); if (rc == TERR_NO_ERR) { device_send_message(); } if (check_device() == ACTION_FAIL) break; tn_task_sleep(1000); } } } Если девайс нам не отвечает на команды, то мы просто перезапускаем цикл. А уже во внутреннем цикле идет дальнейшая работа с девайсом, проверяем есть ли сообщения в очереди, если нет, то проверяем не подвис ли девайс, если подвис, то выходит из внутреннего цикла, а во внешнем цикле все по новой - перезагрузка, настройка и т.п И задача засыпает на 1000 тиков (в данном случае на 1 сек.) чтобы другие задачи могли выполняться. Использовать очередь с блокировкой задачи не совсем вариант, т.к нам нужно время от времени проверять состояние устройства. Или же можно реорганизовать работу данного таска? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться