RT-Thread初识学习-05-设备操作

 IO设备模型

 

RT-Thread初识学习-05-设备操作_第1张图片

 IO设备的理解,比如我们使用了一款传感器,但是RTT并没有提供软件包给我们使用,并且我们不需要使用HAL库进行开发,而是想使用RTT给我们的函数,比如下面的rt_device_find()等,那么我们就需要将该设备注册到驱动中,类似于linux的驱动开发,并且基本上我们不会涉及到设备驱动层开发,我们一般只需要涉及到I/0设备管理层即可

下面的图我们只需要涉及到应用程序和IO设备管理器即可了,至于设备驱动框架和设备驱动,一般是不会让我们写的,跟linux一样

 RT-Thread初识学习-05-设备操作_第2张图片

 RT-Thread初识学习-05-设备操作_第3张图片

模拟添加设备驱动以及如何使用 

 添加drv.demo.c文件成为我们的驱动文件

RT-Thread初识学习-05-设备操作_第4张图片

在该文件中写驱动文件,在main函数中直接使用应用程序对该设备进行操作即可

 驱动代码编写

模拟其他驱动进行编写即可,先不写init函数,并且使用INIT_BOARD_EXPORT把该初始化函数注册到内核中去,那样内核就会调用我们写的initial函数,而我们在init的操作就是赋值多个函数比如close、open等函数

static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
{
    LOG_D("emac open");
    return RT_EOK;
}

static rt_err_t rt_stm32_eth_close(rt_device_t dev)
{
    LOG_D("emac close");
    return RT_EOK;
}

static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    LOG_D("emac read");
    rt_set_errno(-RT_ENOSYS);
    return 0;
}

static rt_size_t rt_stm32_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    LOG_D("emac write");
    rt_set_errno(-RT_ENOSYS);
    return 0;
}

static rt_err_t rt_stm32_eth_control(rt_device_t dev, int cmd, void *args)
{
    switch (cmd)
    {
    case NIOCTL_GADDR:
        /* get mac address */
        if (args) rt_memcpy(args, stm32_eth_device.dev_addr, 6);
        else return -RT_ERROR;
        break;

    default :
        break;
    }

    return RT_EOK;
}


static int rt_hw_stm32_eth_init(void)
{
    rt_err_t state = RT_EOK;

    
    stm32_eth_device.dev_addr[0] = 0x00;
    stm32_eth_device.dev_addr[1] = 0x80;
    stm32_eth_device.dev_addr[2] = 0xE1;
    /* generate MAC addr from 96bit unique ID (only for test). */
    stm32_eth_device.dev_addr[3] = *(rt_uint8_t *)(UID_BASE + 4);
    stm32_eth_device.dev_addr[4] = *(rt_uint8_t *)(UID_BASE + 2);
    stm32_eth_device.dev_addr[5] = *(rt_uint8_t *)(UID_BASE + 0);

    stm32_eth_device.parent.parent.init       = rt_stm32_eth_init;
    stm32_eth_device.parent.parent.open       = rt_stm32_eth_open;
    stm32_eth_device.parent.parent.close      = rt_stm32_eth_close;
    stm32_eth_device.parent.parent.read       = rt_stm32_eth_read;
    stm32_eth_device.parent.parent.write      = rt_stm32_eth_write;
    stm32_eth_device.parent.parent.control    = rt_stm32_eth_control;
    stm32_eth_device.parent.parent.user_data  = RT_NULL;

   

       
}
INIT_DEVICE_EXPORT(rt_hw_stm32_eth_init);

#endif /* BSP_USING_ETH */

 

rt_device_t  My_device = RT_NULL;

rt_err_t My_device_open(rt_device_t dev, rt_uint16_t oflag)
{
    rt_kprintf("My_device_open Enter\r\n");
    
    return RT_EOK;
}

rt_err_t My_device_close(rt_device_t dev)
{
    rt_kprintf("My_device_close Enter\r\n");
    
    return RT_EOK;
    
}


rt_err_t My_device_init(rt_device_t dev)
{
    rt_kprintf("My_device_init Enter\r\n");
    
    My_device = rt_device_create(RT_Device_Class_Char, 32);
    
    My_device->close = My_device_close;
   
    My_device->open =  My_device_open;
    
    rt_device_register(My_device, "My_device",RT_DEVICE_FLAG_RDWR);
    
    return RT_EOK;
}

INIT_BOARD_EXPORT(My_device_init);//初始化函数,等设备运行时,内核会调用rt_demo_init
//如果这一条代码不存在的话,则下面的find设备是会出问题的

rt_device_t  My_dv;
int main(void)
{
   My_dv = rt_device_find("My_device");  //形参为设备名字,返回值为设备对象 
   if(My_dv != RT_NULL)
       rt_kprintf("find is success\r\n");
   
   thread23_sample();
    
   return 0;
}

串口设备使用

#define SAMPLE_UART_NAME    "uart2" /* 串 口 设 备 名 称 */
rt_device_t serial_device; /* 串 口 设 备 句 柄 */

int main(void)
{
   serial_device = rt_device_find(SAMPLE_UART_NAME);
    if(serial_device != RT_NULL)
        rt_kprintf("serial is success\r\n");
    
   thread23_sample();

   return 0;
}

 出现的问题,找不到设备,原因是rtconfig.h没有配置

rtconfig.h的作用相当于freertos上的config.h,因此我这里只定义了串口2,而并没有定义串口1 

 

RT-Thread初识学习-05-设备操作_第5张图片

串口在RTT中是存在初始化设置的,因此如果我们不配置串口的波特率的话,它存在默认选择 ,或者说当我们使用串口的时候,我们可以直接在这里修改即可,无需通过函数进行改变

RT-Thread初识学习-05-设备操作_第6张图片

#define SAMPLE_UART_NAME "uart2" /* 串 口 设 备 名 称 */
static rt_device_t serial; /* 串 口 设 备 句 柄 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初 始 化 配 置 参 数 */
/* step1: 查 找 串 口 设 备 */
serial = rt_device_find(SAMPLE_UART_NAME);
/* step2: 修 改 串 口 配 置 参 数 */
config.baud_rate = BAUD_RATE_9600; //修 改 波 特 率 为 9600
config.data_bits = DATA_BITS_8; //数 据 位 8
config.stop_bits = STOP_BITS_1; //停 止 位 1
config.bufsz = 128; //修 改 缓 冲 区 buff size 为 128
config.parity = PARITY_NONE; //无 奇 偶 校 验 位
/* step3: 控 制 串 口 设 备。 通 过 控 制 接 口 传 入 命 令 控 制 字, 与 控 制 参 数 */
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
/* step4: 打 开 串 口 设 备。 以 中 断 接 收 及 轮 询 发 送 模 式 打 开 串 口 设 备 */
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);

你可能感兴趣的:(#,RT_Thread,学习)