This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to run AT command to control lte modem in work queue?

I did some evaluation on nrf9160dk recently. I try to run some at command to control lte modem, but some wired thing happen.

After I introduce at command in to one work in work queue, the work will never run again. I write a simple code here to show this problem,.

It is based on nrf v1.1.0. The purpose of this code is switching radio link on and off every 10 second. The switch work handler has at commands to do the job as blowing, but the switch work will stop after run once. 

switch work handler:

void my_switch_work_handler(struct k_work *work)
{
  if(switch_count%2==0){
	  printk("Turn off radio link\n");
	  at_cmd_write("AT+CFUN=4", NULL, 0, NULL);
  }
  else{
	  printk("Turn on radio link\n");
	  at_cmd_write("AT+CFUN=1", NULL, 0, NULL);
  }
  switch_count++;
}

Debug output:

2020-02-05T22:46:05.233Z DEBUG modem << ***** Booting Zephyr OS build v2.0.99-ncs1 *****\x0D\x0A
2020-02-05T22:46:05.240Z DEBUG modem << start\x0D\x0A
2020-02-05T22:46:05.303Z DEBUG modem << Turn on radio link\x0D\x0A
2020-02-05T22:46:06.284Z DEBUG modem << Enter my_sample_timer_handler\x0D
2020-02-05T22:46:06.349Z DEBUG modem << Submit my_switch_work\x0D\x0A
2020-02-05T22:46:06.407Z DEBUG modem << Turn off radio link\x0D\x0A
2020-02-05T22:46:16.285Z DEBUG modem << Enter my_sample_timer_handler\x0D\x0A
2020-02-05T22:46:16.351Z DEBUG modem << Submit my_switch_work\x0D\x0A
2020-02-05T22:46:26.284Z DEBUG modem << Enter my_sample_timer_handler\x0D
2020-02-05T22:46:26.287Z DEBUG modem << Submit my_switch_work\x0D\x0A
2020-02-05T22:46:36.283Z DEBUG modem << Enter my_sample_timer_handler\x0D
2020-02-05T22:46:36.346Z DEBUG modem << Submit my_switch_work\x0D\x0A
2020-02-05T22:46:46.284Z DEBUG modem << Enter my_sample_timer_handler\x0D\x0A

hello_nbiot.zip

  • Hi Charlie, 

    I think you might be running into a deadlock situation here with the AT command module.

    It uses the system work queue to dispatch callbacks, and has limited buffers. CFUN commands may take several seconds to return OK or ERROR, and in the mean time many other responses may come from the modem, filling up the receive buffers. When CFUN command finally returns, it has no available buffer, and will wait for that. But because the command is run from the system work queue and is blocking, no buffer will ever become available due to the fact that the already allocated buffers are not free'd before their callbacks are run on the very same queue. So we have a deadlock. 

    Generally, work on the system work queue should be execute fast and not block. Try sending the commands from a separate thread or create a dedicated work queue, that should hopefully work out better.

    Side note: Not all networks appreciate frequent attach and detach requests. 

    Best regards, 

    Jan Tore 

Related