From b1f91420c6e6d0fee99847c71018e3fda74841dd Mon Sep 17 00:00:00 2001 From: creatoy Date: Wed, 7 Aug 2024 00:23:06 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E6=A8=A1=E5=9D=97=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E4=BD=BF=E7=94=A8=20module=5Fplatform=5Fdriver=20?= =?UTF-8?q?=E5=AE=8F=E6=B3=A8=E5=86=8C=20=E6=9B=B4=E6=96=B0=E4=BA=86?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E8=B7=9F=E8=B8=AA=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...57\345\242\203\351\205\215\347\275\256.md" | 4 +- ...33\345\272\246\350\267\237\350\270\252.md" | 17 +++- drivers/i2c/busses/i2c_bcm2835_rust.rs | 92 ++++++++----------- 3 files changed, 51 insertions(+), 62 deletions(-) rename "\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" => "docs/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" (97%) rename "\350\277\233\345\272\246\350\267\237\350\270\252.md" => "docs/\350\277\233\345\272\246\350\267\237\350\270\252.md" (50%) diff --git "a/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" "b/docs/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" similarity index 97% rename from "\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" rename to "docs/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" index f6c2b78b53edff..1078afe661a03e 100644 --- "a/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" +++ "b/docs/\345\205\263\344\272\216\347\216\257\345\242\203\351\205\215\347\275\256.md" @@ -2,7 +2,7 @@ [环境搭建教程](https://readthedocs-demo1.readthedocs.io/zh-cn/latest/R4L.html) -> NOTE: 我这里使用的编辑器是 VSCode,并安装了 rust-analyzer 和 clangd 插件。系统中还需要安装 clangd 和 python3 +> NOTE: 我这里使用的编辑器是 VSCode,并安装了 rust-analyzer 和 clangd 插件。系统中还需要安装 lldb、clangd 和 python3 ## 关于代码提示 @@ -86,10 +86,12 @@ CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y ``` 4. 修改 QEMU 启动脚本 boot.sh,在 qemu-system-aarch64 下面添加一行 `$@ \` 以接受外部传入的参数 + ```sh ... qemu-system-aarch64 \ $@ \ ... ``` + 5. 运行 boot.sh -S -s 启动 QEMU,QEMU 将等待 LLDB 连接。此时从 VSCode 中启动 LLDB 调试器,就可以进行调试了。 \ No newline at end of file diff --git "a/\350\277\233\345\272\246\350\267\237\350\270\252.md" "b/docs/\350\277\233\345\272\246\350\267\237\350\270\252.md" similarity index 50% rename from "\350\277\233\345\272\246\350\267\237\350\270\252.md" rename to "docs/\350\277\233\345\272\246\350\267\237\350\270\252.md" index 903e72388468b5..e31ba5fcebae55 100644 --- "a/\350\277\233\345\272\246\350\267\237\350\270\252.md" +++ "b/docs/\350\277\233\345\272\246\350\267\237\350\270\252.md" @@ -12,8 +12,15 @@ ### 接下来可做的工作 -1. 使用 module_platform_driver 宏来注册 i2c 驱动模块(现在使用的是 module 宏,但根据老师的建议应该使用前者),并让 i2c 驱动模块能运行起来(不需要真正实现功能,只需要在关键函数中打印一些信息即可) -2. 完成 i2c_algorithm 在 rust 下的实现,可以参考 ClkOps 和 UartPortOps 的实现 -3. 完成 i2c_adapter 在 rust 下的实现 -4. 完成 i2c_msg 在 rust 下的实现 -5. 完成 bcm2835_i2c_probe 函数的实现(依赖前几项工作) +1. [ ] 使用 module_platform_driver 宏来注册 i2c 驱动模块(现在使用的是 module 宏,但根据老师的建议应该使用前者),并让 i2c 驱动模块能运行起来(不需要真正实现功能,只需要在关键函数中打印一些信息即可) + - [x] 测试模块的加载和卸载,并测试其运行结果 (已在 QEMU 和树莓派中测试,可正常进行模块的probe和remove) + - [ ] 使用真实的 i2c 设备进行测试 +2. [ ] 完成 i2c_algorithm 在 rust 下的实现,可以参考 ClkOps 和 UartPortOps 的实现 + - [ ] 完成代码编写并通过编译测试 +3. [ ] 完成 i2c_adapter 在 rust 下的实现 + - [ ] 完成代码编写并通过编译测试 +4. [ ] 完成 i2c_msg 在 rust 下的实现 + - [ ] 完成代码编写并通过编译测试 +5. [ ] 完成 bcm2835_i2c_probe 函数的实现(依赖前几项工作) + - [ ] 完成代码编写并通过编译测试 + - [ ] 使用真实的 i2c 设备进行功能测试 diff --git a/drivers/i2c/busses/i2c_bcm2835_rust.rs b/drivers/i2c/busses/i2c_bcm2835_rust.rs index 53125240155505..a13268c2852e5a 100644 --- a/drivers/i2c/busses/i2c_bcm2835_rust.rs +++ b/drivers/i2c/busses/i2c_bcm2835_rust.rs @@ -9,7 +9,7 @@ use kernel::{ clk::Clk, clk_provider::{ClkHw, ClkInitData, ClkOps}, completion::Completion, - device::{Device, RawDevice}, + device::{self, Device, RawDevice}, driver::DeviceRemoval, error::to_result, i2c::{self, I2cAdapter, I2cAdapterQuirks, I2cMsg, I2C_M_NOSTART, I2C_M_RD}, @@ -19,6 +19,7 @@ use kernel::{ platform, prelude::*, str::CString, + sync::Arc, {c_str, container_of, define_of_id_table, module_platform_driver}, }; @@ -111,31 +112,6 @@ struct Bcm2835I2cDev { debug_num_msgs: u32, } -struct Bcm2835I2cDevice { - _drv: Pin>>, -} - -module! { - type: Bcm2835I2cDevice, - name:"i2c_bcm2835_rust", - author:" <>", - description:"BCM2835 I2C driver (written in rust)", - license:"GPL", - alias: ["platform:i2c_bcm2835"], - params: { - debug: u32 { - default: 0, - permissions: 0o644, - description: "1=err, 2=isr, 3=xfer", - }, - clk_out_ms: u32 { - default: 35, - permissions: 0o644, - description: "clock-stretch timeout (mS)", - }, - }, -} - fn to_clk_bcm2835_i2c(hw_ptr: &ClkHw) -> &mut ClkBcm2835I2c { unsafe { &mut *(container_of!(hw_ptr, ClkBcm2835I2c, hw) as *mut ClkBcm2835I2c) } } @@ -519,13 +495,29 @@ fn bcm2835_i2c_func(adap: I2cAdapter) -> u32 { struct Bcm2835I2cAlgo; -struct Bcm2835I2cData; +struct Bcm2835I2cData {} struct Bcm2835I2cDriver; -impl DeviceRemoval for Bcm2835I2cData { - fn device_remove(&self) { - // TODO: remove i2c device data - } +module_platform_driver! { + type: Bcm2835I2cDriver, + name:"i2c_bcm2835_rust", + author:" <>", + description:"BCM2835 I2C bus driver (written in rust)", + license:"GPL", + initcall: "arch", + alias: ["platform:i2c-bcm2835"], + params: { + debug: u32 { + default: 0, + permissions: 0o644, + description: "1=err, 2=isr, 3=xfer", + }, + clk_out_ms: u32 { + default: 35, + permissions: 0o644, + description: "clock-stretch timeout (mS)", + }, + }, } kernel::module_of_id_table!(BCM2835_I2C_MOD_TABLE, BCM2835_I2C_ID_TABLE); @@ -535,46 +527,34 @@ kernel::define_of_id_table! {BCM2835_I2C_ID_TABLE, (), [ (DeviceId::Compatible(b"brcm,bcm2835-i2c"), None), ]} +type DeviceData = device::Data<(), (), Bcm2835I2cData>; + impl platform::Driver for Bcm2835I2cDriver { + kernel::driver_of_id_table!(BCM2835_I2C_ID_TABLE); + + type Data = Arc; + fn probe( pdev: &mut platform::Device, id_info: core::prelude::v1::Option<&Self::IdInfo>, ) -> Result { - // let pdev = dev. + pr_info!("BCM2835 i2c bus device ({}) driver probe.\n", pdev.name()); + // TODO: initialize and probe i2c driver /*let i2c_dev = unsafe { let dev = &mut *(pdev.raw_device().dev) as &mut Device; dev.kzall };*/ // TODO: initialize i2c_dev - Ok(()) + + let dev_data = + kernel::new_device_data!((), (), Bcm2835I2cData {}, "BCM2835_I2C device data")?; + Ok(dev_data.into()) } fn remove(_data: &Self::Data) -> Result { + pr_info!("BCM2835 i2c bus device driver remove.\n"); // TODO: remove i2c driver Ok(()) } - - // TODO: complete the table - // define_of_id_table! {(), [ - // (of::DeviceId::Compatible(b"brcm,bcm2711-i2c"), None), - // (of::DeviceId::Compatible(b"brcm,bcm2835-i2c"), None), - // ]} -} - -impl kernel::Module for Bcm2835I2cDevice { - fn init(module: &'static ThisModule) -> Result { - pr_info!("BCM2835 i2c bus device driver (init)\n"); - - let _drv = - platform::Registration::::new_pinned(c_str!("i2c-bcm2835"), module)?; - - Ok(Bcm2835I2cDevice { _drv }) - } -} - -impl Drop for Bcm2835I2cDevice { - fn drop(&mut self) { - pr_info!("BCM2835 i2c bus device driver (exit)\n"); - } }