1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-07-23 15:08:19 +00:00

fix(core): add timeout to nrf uart communication

[no changelog]
This commit is contained in:
tychovrahe 2025-06-26 11:10:25 +02:00 committed by TychoVrahe
parent d21bdb7f12
commit ac5fa0a5d8
7 changed files with 72 additions and 25 deletions

View File

@ -162,8 +162,9 @@ void nrf_reboot(void);
*
* @param data Pointer to the data buffer
* @param len Length of the data buffer
* @param timeout_ms Timeout in milliseconds for the operation
*/
void nrf_send_uart_data(const uint8_t *data, uint32_t len);
bool nrf_send_uart_data(const uint8_t *data, uint32_t len, uint32_t timeout_ms);
/**
* @brief Check if an nRF device firmware update is required by comparing SHA256

View File

@ -27,6 +27,7 @@
#include "../nrf_internal.h"
#include "rust_smp.h"
#include "sys/systick.h"
extern nrf_driver_t g_nrf_driver;
@ -147,23 +148,52 @@ void USART3_IRQHandler(void) {
IRQ_LOG_EXIT();
}
void nrf_send_uart_data(const uint8_t *data, uint32_t len) {
bool nrf_send_uart_data(const uint8_t *data, uint32_t len,
uint32_t timeout_ms) {
nrf_driver_t *drv = &g_nrf_driver;
if (drv->initialized) {
while (drv->dfu_tx_pending) {
irq_key_t key = irq_lock();
irq_unlock(key);
}
drv->dfu_tx_pending = true;
HAL_UART_Transmit_IT(&drv->urt, data, len);
while (drv->dfu_tx_pending) {
irq_key_t key = irq_lock();
irq_unlock(key);
}
if (!drv->initialized) {
return false;
}
uint32_t deadline = ticks_timeout(timeout_ms);
bool result = false;
irq_key_t key = irq_lock();
while (drv->dfu_tx_pending && !ticks_expired(deadline)) {
// Wait for previous transmission to complete
irq_unlock(key);
key = irq_lock();
}
if (drv->dfu_tx_pending) {
// If we are still pending, it means we timed out
goto cleanup;
}
drv->dfu_tx_pending = true;
HAL_UART_Transmit_IT(&drv->urt, data, len);
while (drv->dfu_tx_pending && !ticks_expired(deadline)) {
// Wait for transmission to complete
irq_unlock(key);
key = irq_lock();
}
if (drv->dfu_tx_pending) {
// If we are still pending, it means we timed out
drv->dfu_tx_pending = false;
HAL_UART_Abort_IT(&drv->urt);
goto cleanup;
}
result = true;
cleanup:
irq_unlock(key);
return result;
}
void nrf_set_dfu_mode(bool set) {

View File

@ -26,7 +26,11 @@ pub fn send(text: &str) -> bool {
data[..SMP_HEADER_SIZE].copy_from_slice(&header);
data[SMP_HEADER_SIZE..SMP_HEADER_SIZE + data_len].copy_from_slice(&cbor_data[..data_len]);
send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
let res = send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
if res.is_err() {
return false;
}
let mut resp_buffer = [0u8; 64];
if wait_for_response(MsgType::Echo, &mut resp_buffer, Duration::from_millis(100)).is_ok() {

View File

@ -144,7 +144,7 @@ pub fn encode_request(data: &[u8], out: &mut [u8]) {
out[len + MSG_HEADER_SIZE + 1] = (crc & 0xFF) as u8;
}
pub fn send_request(data: &mut [u8], buffer: &mut [u8]) {
pub fn send_request(data: &mut [u8], buffer: &mut [u8]) -> Result<(), SmpError> {
encode_request(data, buffer);
let total = data.len() + MSG_HEADER_SIZE + MSG_FOOTER_SIZE;
@ -175,10 +175,16 @@ pub fn send_request(data: &mut [u8], buffer: &mut [u8]) {
buf[total_len] = b'\n';
// 4) send it out
send_data(&buf[..total_len + FRAME_FOOTER_SIZE]);
let sent = send_data(&buf[..total_len + FRAME_FOOTER_SIZE], 10);
if !sent {
return Err(SmpError::Timeout);
}
init_frame = false;
}
Ok(())
}
/// A simple writer that copies into a `&mut [u8]` and counts bytes written.

View File

@ -23,5 +23,5 @@ pub fn send() {
data[..SMP_HEADER_SIZE].copy_from_slice(&header);
data[SMP_HEADER_SIZE..SMP_HEADER_SIZE + data_len].copy_from_slice(&cbor_data[..data_len]);
send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
let _ = send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
}

View File

@ -44,7 +44,11 @@ pub fn upload_image(image_data: &[u8], image_hash: &[u8]) -> bool {
data[..SMP_HEADER_SIZE].copy_from_slice(&header);
data[SMP_HEADER_SIZE..SMP_HEADER_SIZE + data_len].copy_from_slice(&cbor_data[..data_len]);
send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
let res = send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
if res.is_err() {
return false;
}
let mut resp_buffer = [0u8; 64];
if wait_for_response(
@ -81,7 +85,11 @@ pub fn upload_image(image_data: &[u8], image_hash: &[u8]) -> bool {
data[..SMP_HEADER_SIZE].copy_from_slice(&header);
data[SMP_HEADER_SIZE..SMP_HEADER_SIZE + data_len].copy_from_slice(&cbor_data[..data_len]);
send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
let res = send_request(&mut data[..SMP_HEADER_SIZE + data_len], &mut buffer);
if res.is_err() {
return false;
}
let mut resp_buffer = [0u8; 64];
if wait_for_response(

View File

@ -1,7 +1,5 @@
use super::ffi;
pub fn send_data(data: &[u8]) {
unsafe {
ffi::nrf_send_uart_data(data.as_ptr(), data.len() as _);
}
pub fn send_data(data: &[u8], timeout: u32) -> bool {
unsafe { ffi::nrf_send_uart_data(data.as_ptr(), data.len() as _, timeout) }
}