Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage with global allocator #110

Closed
hacknus opened this issue Jan 5, 2023 · 9 comments
Closed

Usage with global allocator #110

hacknus opened this issue Jan 5, 2023 · 9 comments

Comments

@hacknus
Copy link

hacknus commented Jan 5, 2023

I have been using this library on my STM32F405 and it has work flawlessly with interrupt polling:
The setup is as follows:

// Make USB serial device globally available
pub static G_USB_SERIAL: Mutex<RefCell<Option<SerialPort<UsbBus<USB>>>>> =
    Mutex::new(RefCell::new(None));

// Make USB device globally available
pub static G_USB_DEVICE: Mutex<RefCell<Option<UsbDevice<UsbBus<USB>>>>> =
    Mutex::new(RefCell::new(None));

#[entry]
fn main() -> ! {
  
  unsafe {
          static mut EP_MEMORY: [u32; 1024] = [0; 1024];
          static mut USB_BUS: Option<UsbBusAllocator<stm32f4xx_hal::otg_fs::UsbBusType>> = None;
          USB_BUS = Some(stm32f4xx_hal::otg_fs::UsbBusType::new(usb, &mut EP_MEMORY));
          let mut usb_bus = USB_BUS.as_ref().unwrap();
          let mut serial_port = SerialPort::new(&usb_bus);
          cortex_m::interrupt::free(|cs| {
              *G_USB_SERIAL.borrow(cs).borrow_mut() = Some(serial_port);
              *G_USB_DEVICE.borrow(cs).borrow_mut() = Some(
                  UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
                      .manufacturer("University of Bern")
                      .product("Emanuel")
                      .serial_number("007")
                      .device_class(usbd_serial::USB_CLASS_CDC)
                      .build(),
              );
          });
          cortex_m::peripheral::NVIC::unmask(Interrupt::OTG_FS);
          // Enable the external interrupt in the NVIC by passing the button interrupt number
          cortex_m::peripheral::NVIC::unmask(sw.interrupt());
      }
      loop {
           // do stuff
     }

}

However, now I am trying to use it with a FreeRTOS wrapper for rust which requires nightly build with a global allocator:

#[global_allocator]
static GLOBAL: FreeRtosAllocator = FreeRtosAllocator;

and now the USB setup fails, I assume the allocations conflict? Does anybody have an idea on how to mitigate this?

@Disasm
Copy link
Member

Disasm commented Jan 6, 2023

usb-device doesn't use allocator, so the problem is located somewhere else.

@hacknus
Copy link
Author

hacknus commented Jan 6, 2023

Ok, I found out that with the debugger, it hangs in this line:

while read_reg!(otg_global, regs.global(), GRSTCTL, AHBIDL) == 0 {}

line 365 in .cargo/registry/src/github.com-1ecc6299db9ec823/synopsys-usb-otg-0.3.1/src/bus.rs

full output of the debugger:

synopsys_usb_otg::bus::{impl#2}::enable::{closure#0}<stm32f4xx_hal::otg_fs::USB> (cs=<optimized out>)
    at /Users/linus/.cargo/registry/src/github.com-1ecc6299db9ec823/synopsys-usb-otg-0.3.1/src/bus.rs:365
365	            while read_reg!(otg_global, regs.global(), GRSTCTL, AHBIDL) == 0 {}
(gdb) 
halted: PC: 0x08002ace
halted: PC: 0x08002ac6
synopsys_usb_otg::ral::register::RWRegister<u32>::read<u32> (self=<optimized out>)
    at /Users/linus/.cargo/registry/src/github.com-1ecc6299db9ec823/synopsys-usb-otg-0.3.1/src/ral/register.rs:23
23	        unsafe { ::core::ptr::read_volatile(self.register.get()) }
(gdb) step
0x08002ac6 in core::ptr::read_volatile<u32> (src=<optimized out>) at /rustc/659e169d37990b9c730a59a96081f2ef7afbe8f1/library/core/src/ptr/mod.rs:1521
1521	/rustc/659e169d37990b9c730a59a96081f2ef7afbe8f1/library/core/src/ptr/mod.rs: No such file or directory.
(gdb) step
halted: PC: 0x08002aca
synopsys_usb_otg::bus::{impl#2}::enable::{closure#0}<stm32f4xx_hal::otg_fs::USB> (cs=<optimized out>)
    at /Users/linus/.cargo/registry/src/github.com-1ecc6299db9ec823/synopsys-usb-otg-0.3.1/src/bus.rs:365
365	            while read_reg!(otg_global, regs.global(), GRSTCTL, AHBIDL) == 0 {}
(gdb) 
halted: PC: 0x08002ace
halted: PC: 0x08002ac6

@Disasm
Copy link
Member

Disasm commented Jan 6, 2023

Please check that clocks are correct and 48MHz clock is supplied to the USB peripheral.

@hacknus
Copy link
Author

hacknus commented Jan 7, 2023

I agree, it looks like there is a clock issue..
I'm looking into this and I'll come back to you.
Thanks!

@hacknus
Copy link
Author

hacknus commented Jan 9, 2023

It appears that usb-device works when compiled with default rust, but it fails when compiled with nightly (no changes in the code, just added '+nightly' to the cargo build command). Should I open another issue for that? (FreeRTOS requires nightly because of the allocator, that's why I noticed it)

@Disasm
Copy link
Member

Disasm commented Jan 9, 2023

I think the best approach is to reduce the software to a minimal version which reveals the difference between stable and nightly and then file a bug to rust-lang.

@hacknus
Copy link
Author

hacknus commented Jan 9, 2023

Yes, I did that. I tried these examples; poll and interrupt and both work with rust stable but hang with nightly. rust-lang seems a bit overkill, it seems that the AHB clock is not ready/setup in nightly. I guess that is an issue in the stm32f4xx-hal?

@antonok-edm
Copy link

I ran into this as well.

Linking the related issue chain for reference, in case anyone else has the same issue: stm32-rs/stm32f4xx-hal#567

@Disasm
Copy link
Member

Disasm commented Jan 14, 2023

Fixed in stm32-rs/synopsys-usb-otg#34

@Disasm Disasm closed this as completed Jan 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants