Re: MCUMGR - sends responses to wrong port
Bug #26939 filed…. Let me know if there is any other info I can provide.
From: Cufi, Carles <Carles.Cufi@...>
Sent: Friday, July 17, 2020 4:49 AM
To: Lawrence King <lawrence.king@...>; zephyr-devel@...; Zephyr-users@...
Subject: RE: MCUMGR - sends responses to wrong port
Right, I think I understand what you mean. This is almost certainly a bug in the SMP shell transport, but just to make sure, please:
I tried your suggestion, unfortunately it doesn’t help. Every dts that uses mcumgr, also has the console on the same port, there is no existing board that routes the mcumgr to a different place than the console. Hence you would never have seen this issue.
The function smp_shell_tx_raw() in subsys/mgmt/smp_shell.c is hard coded to always send the response via k_str_out(). k_str_out() is part of lib/os/printk and calls __char_out(). The function __char_out() is hooked into printk with the function __printk_hook_install() very early in the kernel boot phases and all the places that the hook is installed always installs it to the console.
The shell can be run on any port, not just the console, and we can add mcumgr to the shell. When the shell is running on a different port it is correctly passing the received data to smp_shell, its just that smp_shell sends the reply out to the console, and not to the port the shell is running on.
When smp_uart.c is ready to transmit a packet it calls mcumgr_serial_tx_pkt(), which then breaks the packet into frames and calls mcumgr_serial_tx_frame(). In turn mcumgr_serial_tx_frame() breaks the frame into bytes and calls mcumgr_serial_tx_small(). mcumgr_serial_tx_small() then base64 encodes the bytes and calls the mcumgr_serial_tx_cb to send 4 chars. Up to this point is all looking like it should. A pointer (cb) to the tx callback was passed all along this chain, so it should be possible to route the reply packet to the correct port.
Unfortunately when smp_shell_tx_pkt() called mcumgr_serial_tx_pkt() it passed a pointer to the function smp_shell_tx_raw() as the transmit callback. smp_shell_tx_raw is hard coded to send to the console, not the port the shell is running on. When smp_shell_init() was called it was passed a device pointer which is the device that the packets are coming in on, and going out on. But smp_shell_init() threw away this information when it called zephyr_smp_transport_init(). Uart_mcumgr does a little better than smp_shell, it also throws away the device information, but instead of being hard coded to the console, it outputs data to CONFIG_UART_MCUMGR_ON_DEV_NAME.
Try instead using the .dts in your board, or add an overlay, and change this line:
zephyr,uart-mcumgr = &uart0;
I am trying to setup mcumgr to allow code download over a serial port and use the shell. In this case I have 2 serial ports in play.
The first serial port is where printk() sends messages. I also have a simple command parser on the port that interprets single letter commands. This printk and my command parser work as expected.
The second serial port is running a shell. Commands like ‘help’ and ‘fs ls’ work as expected, output appears on the second port. However when I attempt to send a file or image update using mcumgr to the second serial port, it doesn’t work. The initial packet arrives on the serial port, smp_shell recognizes the packet, formulates a response, and then sends the response to the first serial port, not the second serial port as it should. LOG messages also come out on the second port as expected.
I chased the problem as far as I can. In smp_shell.c the function smp_shell_tx_raw() always sends the packet via k_str_out(). It should be sending the packet back by shell_print(). Unfortunately the function smp_shell_tx_raw doesn’t have access to the handle for the shell.
I did try setting CONFIG_UART_MCUMGR_ON_DEV_NAME but k_str_out() ignores this setting….
Any suggestions on how to fix this? Or am I doing something wrong?
Connected Transport Market Unit
CONFIDENTIAL: This e-mail and any attachments are confidential and intended solely for the use of the individual(s) to whom it is addressed. It can contain proprietary confidential information and be subject to legal privilege and/or subject to a non-disclosure Agreement. Unauthorized use, disclosure or copying is strictly prohibited. If you are not the/an addressee and are in possession of this e-mail, please delete the message and notify us immediately. Please consider the environment before printing this e-mail. Thank you.