【2024-RSOC】Day4 : RT-Thread设备驱动(上)

【2024-RSOC】Day4 : RT-Thread设备驱动(上)

【2024-RSOC】 基于RT-Thread官方开发板星火一号,本篇参考RT-Thread入门pdf资料《RT-Thread 内核-线程间同步》,和夏令营老师讲解,编写而成。本内容面向小白,因为写这个的作者也是小白,跟着夏令营刚开始学,欸嘿(笑)。

0.png
1.png

在线文档♥点♥我♥看♥

如果初次使用spark的bsp软件包,未构建vscode文件,则参考我前日发布【2024-RSOC】夏令营Day2:初识rt-thread及多线程简单试用中的初次搞机(干通官方bsp源码)小节,确保工程文件能正常打开烧录例程,再往下进行。

实验1 注册字符设备

小节相关在线文档♥点♥我♥看♥

代码如下:

#include <rtdevice.h>
#include <rtthread.h>

static int rt_device_test_init(void)
{
    //动态创建设备实例
    rt_device_t test_dev = rt_device_create(RT_Device_Class_Char,0);
    
    if(!test_dev)
    {
        rt_kprintf("test_dev create failed!\n");
        return -RT_ERROR;
    }

    if(rt_device_register(test_dev,"test_dev",RT_DEVICE_FLAG_RDWR)!= RT_EOK)
    {
        rt_kprintf("test_dev register failed\n");
        return -RT_ERROR;
    }
    return RT_EOK;
}
MSH_CMD_EXPORT(rt_device_test_init, rt_device_test_init);

2.png

实验2 按键ulog显示

ulog 是一个非常简洁、易用的 C/C++ 日志组件,第一个字母 u 代表 μ,即微型的意思。它能做到最低ROM<1K, RAM<0.2K的资源占用。ulog 不仅有小巧体积,同样也有非常全面的功能,其设计理念参考的是另外一款 C/C++ 开源日志库:EasyLogger(简称 elog),并在功能和性能等方面做了非常多的改进。

ulog小节相关在线文档♥点♥我♥看♥

首先在env中,我们打开menuconfig.exe,按照下图设置打开ulog。

首先找到ulog。
3.png

选中,再按回车进入内部,勾选Enable ISR log,保存退出,然后scons -j32编译。

4.png

新建.c文件,将以下代码添加进去。按f5运行。

代码如下:


#include <board.h>
#include <rtthread.h>
#include <drv_gpio.h>
#include <ulog.h>
#ifndef RT_USING_NANO
#include <rtdevice.h>
#endif /* RT_USING_NANO */

#define GPIO_LED_B    GET_PIN(F, 11)
#define GPIO_LED_R    GET_PIN(F, 12)
#define KET_UP        GET_PIN(C, 5)
#define KET_DOWN      GET_PIN(C, 1)
#define KET_LIFT      GET_PIN(C, 0)
#define KET_RIGHT     GET_PIN(C, 4)

#define LOG_TAG        "pin.irq"
#define LOG_LVL        LOG_LVL_DBG

void key_up_callback(void *args)
{
    int value = rt_pin_read(KET_UP);
    LOG_I("key up! %d",value);

}


void key_down_callback(void *args)
{
    int value = rt_pin_read(KET_DOWN);
    LOG_I("key down! %d",value);

}


void key_lift_callback(void *args)
{
    int value = rt_pin_read(KET_LIFT);
    LOG_I("key lift! %d",value);

}


void key_right_callback(void *args)
{
    int value = rt_pin_read(KET_RIGHT);
    LOG_I("key right! %d",value);

}


static int rt_pin_irq_example(void)
{
    rt_pin_mode(KET_UP, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KET_DOWN, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KET_LIFT, PIN_MODE_INPUT_PULLUP);
    rt_pin_mode(KET_RIGHT, PIN_MODE_INPUT_PULLUP);

    rt_pin_attach_irq(KET_UP,PIN_IRQ_MODE_FALLING,key_up_callback,RT_NULL);
    rt_pin_attach_irq(KET_DOWN,PIN_IRQ_MODE_FALLING,key_down_callback,RT_NULL);
    rt_pin_attach_irq(KET_LIFT,PIN_IRQ_MODE_FALLING,key_lift_callback,RT_NULL);
    rt_pin_attach_irq(KET_RIGHT,PIN_IRQ_MODE_FALLING,key_right_callback,RT_NULL);

    rt_pin_irq_enable(KET_UP,PIN_IRQ_ENABLE);   
    rt_pin_irq_enable(KET_DOWN,PIN_IRQ_ENABLE);
    rt_pin_irq_enable(KET_LIFT,PIN_IRQ_ENABLE);
    rt_pin_irq_enable(KET_RIGHT,PIN_IRQ_ENABLE);

    return RT_EOK;



}

MSH_CMD_EXPORT(rt_pin_irq_example, rt pin irq examlpe);

运行结果如图:按压案件,会打印输出日志。
5.png


##实验3 IIC读写。

首先在env中,我们打开menuconfig.exe,按照下图设置打开IIC。

6.png

然后scons -j32编译。

已经能看到iic1已经注册。

7.png

实验4 修改Kconfig文件以添加自己设备

刚才我们选取IIC1已经看到了有5个IIC。如果我们要添加IIC6,那该如何讷?

在board目录下找到Kconfig文件打开,找到IIC的配置行。

8.png

将IIC5整段复制,粘贴,修改为IIC6,再打开drv_soft_i2c.c,同样添加一段IIC6的代码如图。

9.png

以及修改上方#if defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4) || defined(BSP_USING_I2C5) || defined(BSP_USING_I2C6)(在末尾添加IIC6的判断)

在头文件里也要加上IIC6信息,复制粘贴再修改即可

10.png

保存所有修改好的文件,再次打开menuconfig.exe,发现IIC选项内已有IIC6。如图示。

11.png

按住shift+?,查看依赖信息,显示的信息对接的即Kconfig的内容。


小插曲ಠ_ಠ

消失的libraries库

刚刚在修改HAL驱动包时发现,我的bsp包内不存在libraries文件夹,导致我无法修改HAL库来添加IIC6的配置信息。那么如何将libraries目录改至工程目录呢?

我们进入.vscode目录查看c_cpp_properties.json文件,如图:

12.png

libraries相关的目录全改为工程目录下,改为如下图示,即删去…\之类的东西。记得保存更改。

13.png

此时去stm32目录下,找到libraries文件夹,进入找到星火一号的F407VGT6的HAL库,和HAL_Drivers单独拷贝到工程目录下的libraries文件夹内。scons -j32编译即可。

i2c-tools探测设备地址。

在menuconfig.exe中启用,如图。可以很便捷的查找设备地址。

14.png


实验5 IIC读与写操作

代码如下

#include <rtthread.h>
#include <rtdevice.h>
#include <ulog.h>

#define LOG_TAG    "i2c.app"
#define LOG_LVL    LOG_LVL_DOG

void i2c_sample_single_byte_write(void)
{
    struct rt_i2c_bus_device *i2c_bus;
    struct rt_i2c_msg         msgs;
    rt_uint8_t                buf[2];

    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c2");
    if (i2c_bus == RT_NULL)
    {
        LOG_E("can't find %s device!\n","i2c2");
    }

    buf[0] = 0x6B;

    msgs.addr = 0x68;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 1;

    if (rt_i2c_transfer(i2c_bus,&msgs,1) == 1)
        LOG_I("single byte write success!");
    else
        LOG_E("single byte write failed!");
    

}
MSH_CMD_EXPORT(i2c_sample_single_byte_write, i2c_sample_single_byte_write);



void i2c_sample_multi_byte_write(void)
{
    struct rt_i2c_bus_device *i2c_bus;
    struct rt_i2c_msg         msgs;
    rt_uint8_t                buf[3];

    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c2");
    if (i2c_bus == RT_NULL)
    {
        LOG_E("can't find %s device!\n","i2c2");
    }

    buf[0] = 0x01;
    buf[1] = 0x02;
    buf[2] = 0x03;

    msgs.addr = 0x68;
    msgs.flags = RT_I2C_WR;
    msgs.buf = buf;
    msgs.len = 3;

    if (rt_i2c_transfer(i2c_bus,&msgs,1) == 1)
        LOG_I("multi byte write success!");
    else
        LOG_E("multi byte write failed!");
 
}
MSH_CMD_EXPORT(i2c_sample_multi_byte_write, i2c_sample_multi_byte_write);



void i2c_sample_single_byte_read(void)
{
    struct rt_i2c_bus_device *i2c_bus;
    struct rt_i2c_msg         msgs[2];
    rt_uint8_t                send_buf[1],recv_buf[1];
    rt_err_t ret = RT_EOK;

    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c2");
    if (i2c_bus == RT_NULL)
    {
        LOG_E("can't find %s device!\n","i2c2");
    }

    send_buf[0] = 0x6B;
    recv_buf[1] = 0x6A;
    

    msgs[0].addr = 0x68;
    msgs[0].flags = RT_I2C_WR;
    msgs[0].buf = send_buf;
    msgs[0].len = 1;

    msgs[1].addr = 0x68;
    msgs[1].flags = RT_I2C_RD;
    msgs[1].buf = recv_buf;
    msgs[1].len = 1;


    ret = rt_i2c_transfer(i2c_bus,&msgs,2);
    if (ret == 2)
        LOG_I("single byte read success!");
    else
        LOG_E("single byte read failed! %d", ret);
 
}
MSH_CMD_EXPORT(i2c_sample_single_byte_read, i2c_sample_single_byte_read);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值