已剪辑自: mp.weixin.qq.com/s/Ba7JcNJig…
一、前言
以STM32为例,打开网络上下载的例程或者是购买开发板自带的例程,都会发现应用层中会有stm32f10x.h或者stm32f10x_gpio.h,这些文件严格来时属于硬件层的,如果软件层出现这些文件会显得很乱。 使用过Linux的童鞋们肯定知道linux系统无法直接操作硬件层,打开linux或者rt_thread代码会发现代码中都会有device的源文件,没错,这就是驱动层。
二、实现原理
原理就是将硬件操作的接口全都放到驱动链表上,在驱动层实现device的open、read、write等操作。当然这样做也有弊端,就是驱动find的时候需要遍历一遍驱动链表,这样会增加代码运行时间。
三、代码实现
国际惯例,写代码先写头文件。rt_thread中使用的是双向链表,为了简单在这我只用单向链表。有兴趣的可以自行研究rt_thread 头文件接口:
本次只实现如下接口,device_open 和device_close等剩下的接口可以自行研究。这样就可以在应用层中只调用如下接口可实现:
/\*
驱动注册
\*/
int cola\_device\_register(cola\_device\_t \*dev);
/\*
驱动查找
\*/
cola\_device\_t \*cola\_device\_find(const char \*name);
/\*
驱动读
\*/
int cola\_device\_read(cola\_device\_t \*dev, int pos, void \*buffer, int size);
/\*
驱动写
\*/
int cola\_device\_write(cola\_device\_t \*dev, int pos, const void \*buffer, int size);
/\*
驱动控制
\*/
int cola\_device\_ctrl(cola\_device\_t \*dev, int cmd, void \*arg);
头文件cola_device.h:
#ifndef \_COLA\_DEVICE\_H\_
#define \_COLA\_DEVICE\_H\_
enum LED\_state
{
LED_OFF,
LED_ON,
LED_TOGGLE,
};
typedef struct cola\_device cola\_device\_t;
struct cola\_device\_ops
{
int (\*init) (cola\_device\_t \*dev);
int (\*open) (cola\_device\_t \*dev, int oflag);
int (\*close) (cola\_device\_t \*dev);
int (\*read) (cola\_device\_t \*dev, int pos, void \*buffer, int size);
int (\*write) (cola\_device\_t \*dev, int pos, const void \*buffer, int size);
int (\*control)(cola\_device\_t \*dev, int cmd, void \*args);
};
struct cola\_device
{
const char \* name;
struct cola\_device\_ops \*dops;
struct cola\_device \*next;
};
/\*
驱动注册
\*/
int cola\_device\_register(cola\_device\_t \*dev);
/\*
驱动查找
\*/
cola\_device\_t \*cola\_device\_find(const char \*name);
/\*
驱动读
\*/
int cola\_device\_read(cola\_device\_t \*dev, int pos, void \*buffer, int size);
/\*
驱动写
\*/
int cola\_device\_write(cola\_device\_t \*dev, int pos, const void \*buffer, int size);
/\*
驱动控制
\*/
int cola\_device\_ctrl(cola\_device\_t \*dev, int cmd, void \*arg);
#endif
源文件cola_device.c:
#include "cola\_device.h"
#include <string.h>
#include <stdbool.h>
struct cola\_device \*device_list = NULL;
/\*
查找任务是否存在
\*/
static bool cola\_device\_is\_exists( cola\_device\_t \*dev )
{
cola\_device\_t\* cur = device_list;
while( cur != NULL )
{
if( strcmp(cur->name,dev->name)==0)
{
return true;
}
cur = cur->next;
}
return false;
}
static int device\_list\_inster(cola\_device\_t \*dev)
{
cola\_device\_t \*cur = device_list;
if(NULL == device_list)
{
device_list = dev;
dev->next = NULL;
}
else
{
while(NULL != cur->next)
{
cur = cur->next;
}
cur->next = dev;
dev->next = NULL;
}
return 1;
}
/\*
驱动注册
\*/
int cola\_device\_register(cola\_device\_t \*dev)
{
if((NULL == dev) || (cola\_device\_is\_exists(dev)))
{
return 0;
}
if((NULL == dev->name) || (NULL == dev->dops))
{
return 0;
}
return device\_list\_inster(dev);
}
/\*
驱动查找
\*/
cola\_device\_t \*cola\_device\_find(const char \*name)
{
cola\_device\_t\* cur = device_list;
while( cur != NULL )
{
if( strcmp(cur->name,name)==0)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
/\*
驱动读
\*/
int cola\_device\_read(cola\_device\_t \*dev, int pos, void \*buffer, int size)
{
if(dev)
{
if(dev->dops->read)
{
return dev->dops->read(dev, pos, buffer, size);
}
}
return 0;
}
/\*
驱动写
\*/
int cola\_device\_write(cola\_device\_t \*dev, int pos, const void \*buffer, int size)
{
if(dev)
{
if(dev->dops->write)
{
return dev->dops->write(dev, pos, buffer, size);
}
}
return 0;
}
/\*
驱动控制
\*/
int cola\_device\_ctrl(cola\_device\_t \*dev, int cmd, void \*arg)
{
if(dev)
{
if(dev->dops->control)
{
return dev->dops->control(dev, cmd, arg);
}
}
return 0;
}
硬件注册方式:以LED为例,初始化接口void led_register(void),需要在初始化中调用。
#include "stm32f0xx.h"
#include "led.h"
#include "cola\_device.h"
#define PORT\_GREEN\_LED GPIOC
#define PIN\_GREENLED GPIO\_Pin\_13
/\* LED亮、灭、变化 \*/
#define LED\_GREEN\_OFF (PORT\_GREEN\_LED->BSRR = PIN\_GREENLED)
#define LED\_GREEN\_ON (PORT\_GREEN\_LED->BRR = PIN\_GREENLED)
#define LED\_GREEN\_TOGGLE (PORT\_GREEN\_LED->ODR ^= PIN\_GREENLED)
**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**


**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**
**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**