๋๋ผ์ด๋ฒ
์ด์ ๋๋ผ์ด๋ฒ์์ ์๋ก์ด Registers
๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค.
/// PL011 UART์ฉ ๋๋ผ์ด๋ฒ #[derive(Debug)] pub struct Uart { registers: *mut Registers, } impl Uart { /// ์ง์ ๋ ๊ธฐ๋ณธ ์ฃผ์์ PL011 ๊ธฐ๊ธฐ์ ๋ํ UART ๋๋ผ์ด๋ฒ์ ์ ์ธ์คํด์ค๋ฅผ /// ์์ฑํฉ๋๋ค. /// /// # ์์ /// /// ์ง์ ๋ ๊ธฐ๋ณธ ์ฃผ์๋ PL011 ๊ธฐ๊ธฐ์ /// MMIO ์ ์ด ๋ ์ง์คํฐ 8๊ฐ๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ฉฐ, /// ์ด๋ ํ๋ก์ธ์ค์ ์ฃผ์ ๊ณต๊ฐ์ ๊ธฐ๊ธฐ ๋ฉ๋ชจ๋ฆฌ๋ก /// ๋งคํ๋์ด์ผ ํ๋ฉฐ ๋ค๋ฅธ ๋ณ์นญ์ ์์ด์ผ ํฉ๋๋ค. pub unsafe fn new(base_address: *mut u32) -> Self { Self { registers: base_address as *mut Registers } } /// UART์ ๋จ์ผ ๋ฐ์ดํธ๋ฅผ ์๋๋ค. pub fn write_byte(&self, byte: u8) { // TX ๋ฒํผ์ ๊ณต๊ฐ์ด ํ๋ณด๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. while self.read_flag_register().contains(Flags::TXFF) {} // self.registers๊ฐ ์ ์ ํ๊ฒ ๋งคํ๋ PL011 ๊ธฐ๊ธฐ์ ์ ์ด ๋ ์ง์คํฐ๋ฅผ // ๊ฐ๋ฆฌํค๊ณ ์์ผ๋ฏ๋ก ์์ ํฉ๋๋ค. unsafe { // TX ๋ฒํผ์ ์๋๋ค. addr_of_mut!((*self.registers).dr).write_volatile(byte.into()); } // UART๊ฐ ๋ ์ด์ ์ฌ์ฉ ์ค์ด ์๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. while self.read_flag_register().contains(Flags::BUSY) {} } /// Reads and returns a pending byte, or `None` if nothing has been /// received. pub fn read_byte(&self) -> Option<u8> { if self.read_flag_register().contains(Flags::RXFE) { None } else { let data = unsafe { addr_of!((*self.registers).dr).read_volatile() }; // TODO: ๋นํธ 8~11์์ ์ค๋ฅ ์ํ๋ฅผ ํ์ธํฉ๋๋ค. Some(data as u8) } } fn read_flag_register(&self) -> Flags { // self.registers๊ฐ ์ ์ ํ๊ฒ ๋งคํ๋ PL011 ๊ธฐ๊ธฐ์ ์ ์ด ๋ ์ง์คํฐ๋ฅผ // ๊ฐ๋ฆฌํค๊ณ ์์ผ๋ฏ๋ก ์์ ํฉ๋๋ค. unsafe { addr_of!((*self.registers).fr).read_volatile() } } }
addr_of!
/addr_of_mut!
๋ฅผ ์ฌ์ฉํ์ฌ ์ค๊ฐ ์ฐธ์กฐ๋ฅผ ๋ง๋ค์ง ์๊ณ ๊ฐ๋ณ ํ๋ ํฌ์ธํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋ถ์์ ํ ์ ์์ต๋๋ค.