error[E0502]: cannot borrow `a` as mutable because it is also borrowed as immutable --> src/main.rs:5:5 | 4 | let x = &a[0]; | - immutable borrow occurs here 5 | a.clear(); // Vecのclear関数は可変参照をとる | ^^^^^^^^^ mutable borrow occurs here 6 | 7 | println!("{}", x); // xの指す先はすでに解放されている | - immutable borrow later used here
fnmain() { let list = Cons(2, &Cons(5, &Cons(3, &Nil))); let list2 = append(&list, 7); print_list(&list2); }
しかし、これは以下のようなコンパイルエラーになってしまいます。
1 2 3 4 5 6 7 8
error[E0515]: cannot return value referencing temporary value --> src/main.rs:22:13 | 22 | Cons(*x, &append(ls, val)) | ^^^^^^^^^^---------------^ ||| || temporary value created here | returns a value referencing data owned by the current function
また、nginxからエラーメッセージが出ていて、リクエストがでかすぎるせいで一時ファイルが大量に生成されていることに競技中に気がつきませんでした。 確かにToo many open fileのエラーはアプリ側のログで確認したのですが、ulimitの変更で誤魔化していました。 nginxからのエラーメッセージ見逃しは去年もあったのに、同じミスを繰り返してしまいました。
//set clock range in MAC MII address register let clock_range = ETH_MACMIIAR_CR_HCLK_DIV_16; self.eth_mac.macmiiar.modify(|_, w| unsafe { w.cr().bits(clock_range) });
self.get_phy() .reset() .set_autoneg();
// Configuration Register self.eth_mac.maccr.modify(|_, w| { // CRC stripping for Type frames w.cstf().set_bit() // Fast Ethernet speed .fes().set_bit() // Duplex mode .dm().set_bit() // Automatic pad/CRC stripping .apcs().set_bit() // Retry disable in half-duplex mode .rd().set_bit() // Receiver enable .re().set_bit() // Transmitter enable .te().set_bit() }); // frame filter register self.eth_mac.macffr.modify(|_, w| { // Receive All w.ra().set_bit() // Promiscuous mode .pm().set_bit() }); // Flow Control Register self.eth_mac.macfcr.modify(|_, w| { // Pause time w.pt().bits(0x100) }); // operation mode register self.eth_dma.dmaomr.modify(|_, w| { // Dropping of TCP/IP checksum error frames disable w.dtcefd().set_bit() // Receive store and forward .rsf().set_bit() // Disable flushing of received frames .dfrf().set_bit() // Transmit store and forward .tsf().set_bit() // Forward error frames .fef().set_bit() // Operate on second frame .osf().set_bit() }); // bus mode register self.eth_dma.dmabmr.modify(|_, w| unsafe { // Address-aligned beats w.aab().set_bit() // Fixed burst .fb().set_bit() // Rx DMA PBL .rdp().bits(32) // Programmable burst length .pbl().bits(32) // Rx Tx priority ratio 2:1 .pm().bits(0b01) // Use separate PBL .usp().set_bit() });
具体的なPHYモジュールのレジスタの説明はLANの仕様書の4.2章からたどることができます。 Basic Control Registerの15ビットをセットすることでソフトリセットをしたのち、12ビットと9ビットを立てることでAuto-Negotiationを有効にすることで、 ハードウェア側で勝手にパラメータ調整を任せることができます。 そのあと、PHY special control/status register(31)の12ビットが立っていれば、auto-negotiationが完了したことがわかります(が、stm32-ethでは確認していないようです。いいのかな?)。
use stm32f4xx_hal::{ gpio::GpioExt, stm32::Peripherals, serial::config::Config, serial::Serial, stm32::RCC, rcc::RccExt, time::{Bps, U32Ext}, }; use stm32_eth::{Eth, RingEntry}; use cortex_m_rt::entry; use core::fmt::{self, Write as FmtWrite}; externcrate panic_halt;
#[entry] unsafefnmain() -> ! { let p = Peripherals::take().unwrap();
// Setup pins and initialize clocks. let gpiod = p.GPIOD.split();
stm32_eth::setup(&p.RCC, &p.SYSCFG); let gpioa = p.GPIOA.split(); let gpiob = p.GPIOB.split(); let gpioc = p.GPIOC.split(); let gpiog = p.GPIOG.split(); stm32_eth::setup_pins( gpioa.pa1, gpioa.pa2, gpioa.pa7, gpiob.pb13, gpioc.pc1, gpioc.pc4, gpioc.pc5, gpiog.pg11, gpiog.pg13 ); // Allocate the ring buffers letmut rx_ring: [RingEntry<_>; 8] = Default::default(); letmut tx_ring: [RingEntry<_>; 2] = Default::default(); // Instantiate driver letmut eth = Eth::new( p.ETHERNET_MAC, p.ETHERNET_DMA, &mut rx_ring[..], &mut tx_ring[..] );
let rcc = p.RCC.constrain(); let clocks = rcc.cfgr.freeze(); let pd8 = gpiod.pd8.into_alternate_af7(); let pd9 = gpiod.pd9.into_alternate_af7(); let config = Config::default().baudrate(115_200u32.bps()); letmut serial = Serial::usart3(p.USART3, (pd8, pd9), config, clocks).unwrap(); let (mut tx, _) = serial.split();
loop { ifletOk(pkt) = eth.recv_next() { for p in pkt.iter() { tx.write_char(*p aschar).unwrap(); } } } }