main: Add checks before sock send/recv are called

This commit is contained in:
linuswck 2024-04-29 17:57:45 +08:00
parent b8241d1f27
commit 70fed23c51
2 changed files with 57 additions and 40 deletions

View File

@ -140,8 +140,6 @@ fn main() -> ! {
laser.load_settings_from_summary(laser_settings);
}
State::MainLoop => {
let mut eth_is_pending = false;
laser.poll_and_update_output_current();
if thermostat.poll_adc() {
@ -155,12 +153,16 @@ fn main() -> ! {
net::net::for_each(|mut socket, id| {
if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
if active_report[id] {
if net::net::eth_can_sock_send(socket) {
net::cmd_handler::send_status_report(
eth_data_buffer,
&mut laser,
&mut thermostat,
&mut socket,
);
} else {
debug!("Socket {:?} is not ready to send status report", id)
}
}
} else {
active_report[id] = false;
@ -169,13 +171,10 @@ fn main() -> ! {
thermostat.start_tec_readings_conversion();
}
cortex_m::interrupt::free(|cs| {
eth_is_pending = net::net::is_pending(cs);
net::net::clear_pending(cs);
});
if eth_is_pending {
net::net::for_each(|mut socket, id| {
if net::net::eth_is_socket_active(socket) && net::net::eth_is_socket_connected(socket) {
if net::net::eth_can_sock_recv(socket) && net::net::eth_can_sock_send(socket) {
let bytes = net::net::eth_recv(eth_data_buffer, socket);
if bytes != 0 {
info!("Ts: {:?}", sys_timer::now());
@ -192,9 +191,11 @@ fn main() -> ! {
&mut active_report[id],
);
}
} else {
debug!("Socket {:?} is not ready to process command", id);
}
}
})
};
}
State::SaveLdThermostatSettings => {
// State Transition

View File

@ -1,7 +1,5 @@
use core::{cell::RefCell,
mem::{self, MaybeUninit}};
use core::mem::{self, MaybeUninit};
use cortex_m::interrupt::{CriticalSection, Mutex};
use log::{debug, info};
use serde::{Deserialize, Serialize};
use smoltcp::{iface::{self, Interface, SocketHandle, SocketSet, SocketStorage},
@ -36,10 +34,6 @@ impl Default for IpSettings {
}
}
/// Interrupt pending flag: set by the `ETH` interrupt handler, should
/// be cleared before polling the interface.
static NET_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
pub struct ServerHandle {
socket_handles: [SocketHandle; NUM_OF_SOCKETS],
socket_set: SocketSet<'static>,
@ -230,10 +224,16 @@ impl ServerHandle {
pub fn send(&mut self, buffer: &mut [u8], num_bytes: usize, socket_handles: SocketHandle) {
let socket = self.socket_set.get_mut::<Socket>(socket_handles);
if num_bytes > 0 {
socket.send_slice(&buffer[..num_bytes]).ok();
match socket.send_slice(&buffer[..num_bytes]) {
Ok(_) => {
self.poll_iface();
info!("Sent {} bytes.", num_bytes);
}
Err(err) => {
info!("Bytes cannot be sent. Error: {:?}", err)
}
};
}
}
pub fn is_socket_connected(&mut self, socket_handles: SocketHandle) -> bool {
@ -258,6 +258,14 @@ impl ServerHandle {
let socket = self.socket_set.get_mut::<Socket>(socket_handles);
socket.abort();
}
pub fn can_send(&mut self, socket_handles: SocketHandle) -> bool {
self.socket_set.get_mut::<Socket>(socket_handles).can_send()
}
pub fn can_recv(&mut self, socket_handles: SocketHandle) -> bool {
self.socket_set.get_mut::<Socket>(socket_handles).can_recv()
}
}
use ieee802_3_miim::{phy::{lan87xxa::{LAN8720A, LAN8742A},
@ -357,6 +365,26 @@ impl<M: Miim> EthernetPhy<M> {
}
}
pub fn eth_can_sock_send(socket_handles: SocketHandle) -> bool {
unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE {
server_handle.can_send(socket_handles)
} else {
panic!("eth_check_if_sock_can_send is called before init");
}
}
}
pub fn eth_can_sock_recv(socket_handles: SocketHandle) -> bool {
unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE {
server_handle.can_recv(socket_handles)
} else {
panic!("eth_check_if_sock_can_recv is called before init");
}
}
}
pub fn eth_poll_link_status_and_update_link_speed() -> bool {
unsafe {
if let Some(ref mut server_handle) = SERVER_HANDLE {
@ -457,22 +485,10 @@ pub fn for_each<F: FnMut(SocketHandle, usize)>(mut callback: F) {
#[interrupt]
fn ETH() {
let interrupt_reason = stm32_eth::eth_interrupt_handler();
cortex_m::interrupt::free(|cs| {
cortex_m::interrupt::free(|_| {
if interrupt_reason.rx {
*NET_PENDING.borrow(cs).borrow_mut() = true;
eth_poll_iface();
}
});
debug!("Ethernet Interrupt{:?}", interrupt_reason);
}
/// Has an interrupt occurred since last call to `clear_pending()`?
pub fn is_pending(cs: &CriticalSection) -> bool {
*NET_PENDING.borrow(cs).borrow()
}
/// Clear the interrupt pending flag before polling the interface for
/// data.
pub fn clear_pending(cs: &CriticalSection) {
*NET_PENDING.borrow(cs).borrow_mut() = false;
}