Jump to content

    
Sign in to follow this  
hound

TNKernel & STM32

Recommended Posts

Добрый вечер, начал работать с 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);

 

Но на сколько это оправданно?

Заранее благодарен за ответ.

Share this post


Link to post
Share on other sites
Но на сколько это оправданно?

 

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

 

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);
}

 

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

Share this post


Link to post
Share on other sites

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

Спасибо за разъяснение.

 

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

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 сек.) чтобы другие задачи могли выполняться.

Использовать очередь с блокировкой задачи не совсем вариант, т.к нам нужно время от времени проверять состояние устройства.

Или же можно реорганизовать работу данного таска?

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this