关于rt-thread的外设驱动原理(例子spi)

一:有关SPI

rt中用户需要添加spi的注册和初始化文件如:drv_spi,里面需要做的是

static struct rt_spi_ops gd32_spi_ops =

{

    configure,

    xfer

};

初始化上面的结构体的两个函数,rt的底层spi中有用到这个结构体的两个函数

然后再初始化中将result = rt_spi_bus_register(&spi_bus0, "spi0", &gd32_spi_ops);相应的设备总线注册

 

然后再开发相应的外设设备(芯片)的驱动的时候

初始化中需要传入频率,模式和字节宽度

然后用

static int rt_hw_ssd1351_config(void)

{

    rt_err_t res;

 

    /* oled use PC8 as CS */

    spi_cs.pin = CS_PIN;

    rt_pin_mode(spi_cs.pin, PIN_MODE_OUTPUT);    /* 设置片选管脚模式为输出 */

 

    res = rt_spi_bus_attach_device(&spi_dev_ssd1351, SPI_SSD1351_DEVICE_NAME, SPI_BUS_NAME, (void*)&spi_cs);   将相应的芯片的spi路给绑定上注册好的总线

    if (res != RT_EOK)

    {

        OLED_TRACE("rt_spi_bus_attach_device!\r\n");

        return res;

    }

 

    /* config spi */

    {

        struct rt_spi_configuration cfg;

        cfg.data_width = 8;

        cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;

        cfg.max_hz = 20 * 1000 *1000; /* 20M,SPI max 42MHz,ssd1351 4-wire spi */

 

        rt_spi_configure(&spi_dev_ssd1351, &cfg);   //在这里进行配置

    }

 

    return RT_EOK;

}

然后开始做芯片的寄存器初始化等

static int rt_hw_ssd1351_init(void)

{

    rt_hw_ssd1351_config();

 

    rt_pin_mode(DC_PIN, PIN_MODE_OUTPUT);

    rt_pin_mode(RES_PIN, PIN_MODE_OUTPUT);

 

    rt_pin_write(RES_PIN, PIN_LOW);

    //wait at least 100ms for reset

    rt_thread_delay(100);

    rt_pin_write(RES_PIN, PIN_HIGH);

 

    ssd1351_write_cmd(0xfd); // Command Lock

    ssd1351_write_data(0x12);

 

    ssd1351_write_cmd(0xfd); // Command Lock

    ssd1351_write_data(0xb1);

}

INIT_PREV_EXPORT(rt_hw_ssd1351_init);    /* 使用RT-Thread的组件自动初始化机制 */

(SPI的例子参考了往上的资料,具体可以搜索 ssd1351 rtthread)

 

相应的ssd1351_write_data函数内部调用rt提供的接口rt_spi_send(&spi_dev_ssd1351, &cmd, 1);

 

实际上使用的还是我们定义的xfer函数

 

串口的开发类似上面的套路,iic也是,要考虑不同的总线判断,然后配置函数config中考虑的参数是硬件上不同芯片是否需要做不同的配置选项,需要就作为参数传入

 

rt提供的接口函数可以参考rt的编程指南手册 

二:添加相应的外设驱动说明:

1:添加相应的驱动模块的时候,比如加上hwtimer,需要配置kconfig,然后再env上menuconfig,然后选中选项,然后采用scons --target=mdk5进行重新更新程序

然后再rtconfig中添加相应的头文件宏定义,相应的头文件看rtdevice.h

然后相应的drv-xxx是用户自己写的

可以参考https://www.rt-thread.org/qa/thread-8284-1-1.html

 

2:开发各种总线注册的时候,最主要的是实现rt_xxx_ops这个结构体里面的函数接口,初始化完后开始注册操作,不同设备注册函数不同,相应的函数和接口要求看rt提供的app层接口文件,主要为的是rt_xxx_device结构体服务

分析一下各个rt_xxx_ops,特别是parent.user-data是用户注册设备的时候传进去的数据。

另外外设的初始化中需要用到各种芯片自己支持的函数库的相应的初始化结构体,比如gd32的是

xxx_parameter_struct

 

总结可以得出,需要用户实现对rt提供的外设的函数接口底层,再相应的设备driver中的文件和结构体:E:\rtt\rt-thread-master\components\drivers

可以参看:E:\rtt\rt-thread-master\bsp\gd32303e-eval\drivers 各外设驱动的文件,再工程上添加了相应的驱动源文件后,需要查看rtconfig.h是否开启的相应的宏,开了头文件才会被包含进来,否则报错,相应的宏查看rtdevice.h,然后去到rtconfig.h定义

你可能感兴趣的:(rtthread学习)