zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
10.12k stars 6.21k forks source link

cellular_modem : modem_chat_run_script and simple single AT sending and receiving possible? #65264

Closed MY201314MY closed 7 months ago

MY201314MY commented 8 months ago

Describe the bug

the example cellular_modem can run very well in my platform.(Of course I modified my device tree)

I'm not sure if this is a bug. But in fact, I don't want to run AT commands asynchronously. More often, I pay attention to the running results of AT, so I changed it as follow(_modem_chat_run_script_async(&data->chat, config->init_chatscript); to _modem_chat_run_script(&data->chat, config->init_chatscript);), but it seems that the AT command cannot be send after the change. Are there any steps I'm missing?I'm using STM32F4 Discovery(STM32F407VGT6)

To Reproduce Steps to reproduce the behavior:

  1. copy cellular_modem example
  2. west build -b stm32f4_disco -p
  3. west flash
  4. watch image image

After debugging, I found that although _k_work_submit(&chat->script_runwork); was called, the corresponding callback *_static void modem_chat_script_run_handler(struct k_work item)_** could never be called.

Although _gsm_ppp.c_ has been abandoned, I think it's AT sending, receiving and parsing is more convenient and concise than the current chat script method. In many cases in my projects, I only need to send one AT command, and the parameters of the AT command can be changed dynamically. Yes, I hope to just adapt the original AT transceiver function to the new modem cellular, but I am not sure whether this is possible.Of course I want to use the new _modemcmux and _modempipe.


/**
 * @brief  send AT command to interface w/ a TX lock
 *
 * @param  iface: interface to use
 * @param  handler: command handler to use
 * @param  handler_cmds: commands to attach
 * @param  handler_cmds_len: size of commands array
 * @param  buf: NULL terminated send buffer
 * @param  sem: wait for response semaphore
 * @param  timeout: timeout of command
 *
 * @retval 0 if ok, < 0 if error.
 */
static inline int modem_cmd_send(struct modem_iface *iface,
                 struct modem_cmd_handler *handler,
                 const struct modem_cmd *handler_cmds,
                 size_t handler_cmds_len, const uint8_t *buf,
                 struct k_sem *sem, k_timeout_t timeout)
{
    return modem_cmd_send_ext(iface, handler, handler_cmds,
                  handler_cmds_len, buf, sem, timeout, 0);
}```
github-actions[bot] commented 8 months ago

Hi @MY201314MY! We appreciate you submitting your first issue for our open-source project. 🌟

Even though I'm a bot, I can assure you that the whole community is genuinely grateful for your time and effort. 🤖💙

bjarki-andreasen commented 8 months ago

Hi, the entire modem subsystem, including the modem_cellular driver is asynchronous. All modules and the driver itself are run using a single thread, the system workqueue thread, using work items.

If you block the work queue, by using a non async function, it will deadlock. The change you are making here is blocking the work queue, which then blocks all other modem modules, so it will never complete.

You can rewrite the driver to be sync, by for example creating a dedicated work queue for it, but this requires more resources :)

To see an example of how the modem modules are used sync, see https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/gnss/gnss_quectel_lcx6g.c