Edition 3 Post 3 Embedded Graphics part and logger not working
0xC0ba1t opened this issue · comments
0xC0ba1t commented
Hey, i understand edition 3 is in development, everything works except the part after the embedded-graphics part, it the following errors (after adding embedded-graphics in dependency, as it wasn't recognizing the crate and some other things):
error: expected one of `::`, `;`, or `as`, found `-`
--> dopamine\src\framebuffer.rs:2:13
|
2 | use embedded-graphics;
| ^ expected one of `::`, `;`, or `as`
error[E0432]: unresolved import `framebuffer::Position`
--> dopamine\src\main.rs:8:5
|
8 | use framebuffer::Position;
| ^^^^^^^^^^^^^^^^^^^^^ no `Position` in `framebuffer`
error[E0423]: expected value, found module `framebuffer`
--> dopamine\src\main.rs:40:29
|
40 | let frame_buffer_info = framebuffer.info().clone();
| ^^^^^^^^^^^- help: use the path separator to refer to an item: `::`
error[E0277]: `OnceCell<LockedLogger>` cannot be shared between threads safely
--> dopamine\src\main.rs:12:27
|
12 | pub(crate) static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
| ^^^^^^^^^^^^^^^^^^^^^^ `OnceCell<LockedLogger>` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `OnceCell<LockedLogger>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead
= note: shared static variables must have a type that implements `Sync`
error[E0599]: no function or associated item named `uninit` found for struct `OnceCell` in the current scope
--> dopamine\src\main.rs:12:62
|
12 | pub(crate) static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
| ^^^^^^ function or associated item not found in `OnceCell<_>`
|
note: if you're trying to build a new `OnceCell<_>`, consider using `OnceCell::<T>::new` which returns `OnceCell<T>`
--> C:\Users\REMOVED\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library/core/src/cell/once.rs:44:5
|
44 | pub const fn new() -> OnceCell<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Some errors have detailed explanations: E0277, E0423, E0432, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `dopamine` (bin "dopamine") due to 5 previous errors
Thanks alot!, Hope to see edition 3 soon!
xuanplus commented
I read it, too. Here's my code, hope it helps you.
use embedded_graphics::mono_font::{ascii::FONT_9X18_BOLD, MonoTextStyle};
use embedded_graphics::pixelcolor::{Rgb888, RgbColor};
use embedded_graphics::prelude::{DrawTarget, Drawable, OriginDimensions, Pixel, Point, Size};
use embedded_graphics::text::Text;
use lazy_static::lazy_static;
use spin::Mutex;
use core::fmt;
const FONT_WIDTH: i32 = 9;
const FONT_HEIGHT: i32 = 18;
const XMAX: i32 = 1280;
const YMAX: i32 = 720;
pub struct Display {
framebuffer: *mut u8,
}
impl Display {
pub fn new() -> Self {
let mut display = Self {
framebuffer: 0x18000000000 as *mut u8,
};
display.clear();
display
}
pub fn clear(&mut self) {
for i in 0..720 {
for j in 0..1280 {
self.draw_pixel(j, i, Rgb888::BLACK)
}
}
}
pub fn draw_pixel(&mut self, x: i32, y: i32, color: Rgb888) {
if x < 1280 && y < 720 && x >= 0 && y >= 0 {
let index = ((1280 * y + x) * 3) as isize;
unsafe {
*self.framebuffer.offset(index) = color.b();
*self.framebuffer.offset(index + 1) = color.g();
*self.framebuffer.offset(index + 2) = color.r();
}
}
}
}
impl DrawTarget for Display {
type Color = Rgb888;
type Error = core::convert::Infallible;
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for Pixel(coord, color) in pixels.into_iter() {
self.draw_pixel(coord.x, coord.y, color);
}
Ok(())
}
}
impl OriginDimensions for Display {
fn size(&self) -> Size {
Size::new(1280, 720)
}
}
pub struct Writer {
display: Display,
pos: Point,
}
impl Writer {
pub fn new(display: Display) -> Self {
Self {
display: display,
pos: Point { x: 1, y: 12 },
}
}
fn scroll(&mut self) {
for i in 0..898560 {
let a = i * 3;
let b = (i + 23040) * 3;
unsafe {
*self.display.framebuffer.offset(a) = *self.display.framebuffer.offset(b);
*self.display.framebuffer.offset(a + 1) = *self.display.framebuffer.offset(b + 1);
*self.display.framebuffer.offset(a + 2) = *self.display.framebuffer.offset(b + 2);
}
}
for i in 898561..921600 {
unsafe {
*self.display.framebuffer.offset(i * 3) = 0;
*self.display.framebuffer.offset(i * 3 + 1) = 0;
*self.display.framebuffer.offset(i * 3 + 2) = 0;
}
}
}
fn new_line(&mut self) {
self.pos.y += FONT_HEIGHT;
self.pos.x = 1;
if self.pos.y > YMAX {
self.pos.y -= FONT_HEIGHT;
self.scroll();
}
}
pub fn write_char(&mut self, c: &str) {
if c == "\n" || self.pos.x + FONT_WIDTH > XMAX {
self.new_line();
if c == "\n" {
return;
}
}
let style = MonoTextStyle::new(&FONT_9X18_BOLD, Rgb888::WHITE);
Text::new(c, self.pos, style)
.draw(&mut self.display)
.unwrap();
self.pos.x += FONT_WIDTH;
}
pub fn write_str(&mut self, s: &str) {
self.pos.x -= FONT_WIDTH;
for i in s.split("") {
self.write_char(i);
}
self.pos.x -= FONT_WIDTH;
}
}
unsafe impl Send for Writer {}
unsafe impl Sync for Writer {}
impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write_str(s);
Ok(())
}
}
lazy_static! {
pub static ref WRITER: Mutex<Writer> = Mutex::new(Writer::new(Display::new()));
}
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::framebuffer::_print(format_args!($($arg)*)));
}
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
}
#[doc(hidden)]
pub fn _print(args: fmt::Arguments) {
use core::fmt::Write;
WRITER.lock().write_fmt(args).unwrap();
}
There may be some bugs, or cumbersome implementations, but I don't have a good way to do it for the time being, the level is limited. At least it works :)
xuanplus commented
oh, today I rewrite it. I think it is better than better.
// framebuffer.rs
use core::fmt;
use core::{convert::TryInto, fmt::Error};
use lazy_static::lazy_static;
use noto_sans_mono_bitmap::{
get_raster, get_raster_width, FontWeight, RasterHeight, RasterizedChar,
};
use spin::mutex::Mutex;
#[derive(Debug)]
pub struct RGB {
r: u8,
g: u8,
b: u8,
}
impl RGB {
pub fn new(s: u8) -> Self {
Self { r: s, g: s, b: s }
}
}
#[derive(Debug, Clone, Copy)]
pub struct Position {
x: isize,
y: isize,
}
impl TryInto<(isize, isize)> for Position {
type Error = core::convert::Infallible;
fn try_into(self) -> Result<(isize, isize), Self::Error> {
Ok((self.x, self.y))
}
}
#[derive(Debug)]
pub struct Pixel {
color: RGB,
pos: Position,
}
pub struct FrameWriter {
framebuffer: *mut u8,
}
impl FrameWriter {
pub fn new() -> Self {
Self {
framebuffer: 0x18000000000 as *mut u8,
}
}
pub fn draw(&mut self, pixel: Pixel) {
if let Ok((x @ 0..1280, y @ 0..720)) = pixel.pos.try_into() {
let index = (x + y * 1280) * 3;
unsafe {
*self.framebuffer.offset(index) = pixel.color.b;
*self.framebuffer.offset(index + 1) = pixel.color.g;
*self.framebuffer.offset(index + 2) = pixel.color.r;
}
}
}
pub fn clear(&mut self) {
for i in 0..720 {
for j in 0..1280 {
self.draw(Pixel {
color: RGB { r: 0, g: 0, b: 0 },
pos: Position { x: j, y: i },
})
}
}
}
pub fn get(&mut self, pos: Position) -> Result<Pixel, Error> {
if let Ok((x @ 0..1280, y @ 0..720)) = pos.try_into() {
let index = (x + y * 1280) * 3;
unsafe {
let pixel = Pixel {
color: RGB {
b: *self.framebuffer.offset(index),
g: *self.framebuffer.offset(index + 1),
r: *self.framebuffer.offset(index + 2),
},
pos: Position { ..pos },
};
Ok(pixel)
}
} else {
Err(Error)
}
}
}
pub struct Writer {
framewriter: FrameWriter,
pos: Position,
width: isize,
}
impl Writer {
pub fn new(framewriter: FrameWriter) -> Self {
let mut writer = Self {
framewriter: framewriter,
pos: Position { x: 0, y: 0 },
width: get_raster_width(FontWeight::Regular, RasterHeight::Size16) as isize,
};
writer.framewriter.clear();
writer
}
fn get_raster(&mut self, c: char) -> RasterizedChar {
get_raster(c, FontWeight::Regular, RasterHeight::Size16).expect("unsupported char")
}
fn write_char(&mut self, c: char) {
match c {
'\n' => {
self.new_line();
},
'\r' => {
self.carriage_return()
},
c => {
if self.pos.x + self.width >= 1280 {
self.new_line();
}
for (row_i, row) in self.get_raster(c).raster().iter().enumerate() {
for (col_i, intensity) in row.iter().enumerate() {
self.framewriter.draw(Pixel {
color: RGB::new(*intensity),
pos: Position {
x: self.pos.x + col_i as isize,
y: self.pos.y + row_i as isize,
},
})
}
}
self.pos.x += self.width;
}
}
}
fn write_str(&mut self, s: &str) {
for c in s.chars() {
self.write_char(c);
}
}
fn new_line(&mut self) {
self.pos.y += RasterHeight::Size16 as isize;
self.carriage_return();
if self.pos.y >= 720 {
self.scroll();
}
}
fn carriage_return(&mut self) {
self.pos.x = 0;
}
fn scroll(&mut self) {
self.pos.y -= RasterHeight::Size16 as isize;
for i in 0..720 {
for j in 0..1280 {
let pixel = self.framewriter.get(Position { x: j, y: i }).unwrap();
self.framewriter.draw(Pixel {
color: pixel.color,
pos: Position {
x: pixel.pos.x,
y: pixel.pos.y - RasterHeight::Size16 as isize,
},
})
}
}
for i in 704..720 {
for j in 0..1280 {
self.framewriter.draw(Pixel {
color: RGB { r: 0, g: 0, b: 0 },
pos: Position { x: j, y: i },
})
}
}
}
}
# Cargo.toml
[[bin]]
name = "kernel"
test = false
bench = false
[dependencies]
bootloader_api = "0.11.5"
noto-sans-mono-bitmap = "0.2.0"
spin = "0.9.8"
uart_16550 = "0.3.0"
[dependencies.lazy_static]
version = "1.4.0"
features = ["spin_no_std"]