0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言面向对象编程的最佳实践

技术让梦想更伟大 来源:CSDN 作者:李肖遥 2022-11-17 09:48 次阅读

一、前言

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(constchar*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_


enumLED_state
{
  LED_OFF,
  LED_ON,
  LED_TOGGLE,
};


typedefstructcola_devicecola_device_t;
structcola_device_ops
{
  int(*init)(cola_device_t*dev);
  int(*open)(cola_device_t*dev,intoflag);
  int(*close)(cola_device_t*dev);
  int(*read)(cola_device_t*dev,intpos,void*buffer,intsize);
  int(*write)(cola_device_t*dev,intpos,constvoid*buffer,intsize);
  int(*control)(cola_device_t*dev,intcmd,void*args);
};


structcola_device
{
  constchar*name;
  structcola_device_ops*dops;
  structcola_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
#include 


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)
{
returntrue;
}
cur=cur->next;
}
returnfalse;
}


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;
  }
  return1;
}


/*
驱动注册
*/
int cola_device_register(cola_device_t *dev)
{
  if((NULL==dev)||(cola_device_is_exists(dev)))
  {
    return0;
  }
  if((NULL==dev->name)||(NULL==dev->dops))
  {
    return0;
  }
  returndevice_list_inster(dev);
}


/*
驱动查找
*/
cola_device_t*cola_device_find(constchar*name)
{
  cola_device_t*cur=device_list;
  while(cur!=NULL)
  {
    if(strcmp(cur->name,name)==0)
    {
      returncur;
    }
    cur=cur->next;
  }
  returnNULL;
}


/*
驱动读
*/
int cola_device_read(cola_device_t *dev, int pos, void *buffer, int size)
{
  if(dev)
  {
    if(dev->dops->read)
    {
      returndev->dops->read(dev,pos,buffer,size);
    }
  }
  return0;
}


/*
驱动写
*/
int cola_device_write(cola_device_t *dev, int pos, const void *buffer, int size)
{
  if(dev)
  {
    if(dev->dops->write)
    {
      returndev->dops->write(dev,pos,buffer,size);
    }
  }
  return0;
}


/*
驱动控制
*/
int cola_device_ctrl(cola_device_t *dev, int cmd, void *arg)
{
  if(dev)
  {
    if(dev->dops->control)
    {
      returndev->dops->control(dev,cmd,arg);
    }
  }
  return0;
}

硬件注册方式:以LED为例,初始化接口void led_register(void),需要在初始化中调用。

#include"stm32f0xx.h"
#include"led.h"
#include"cola_device.h"
#definePORT_GREEN_LEDGPIOC
#define PIN_GREENLED GPIO_Pin_13             


/*LED亮、灭、变化*/
#defineLED_GREEN_OFF(PORT_GREEN_LED->BSRR=PIN_GREENLED)
#defineLED_GREEN_ON(PORT_GREEN_LED->BRR=PIN_GREENLED)
#define LED_GREEN_TOGGLE (PORT_GREEN_LED->ODR ^= PIN_GREENLED)


static cola_device_t led_dev;


static void led_gpio_init(void)
{
  GPIO_InitTypeDefGPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC,ENABLE);
  GPIO_InitStructure.GPIO_Pin=PIN_GREENLED;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;
  GPIO_Init(PORT_GREEN_LED,&GPIO_InitStructure);
  LED_GREEN_OFF;
}


static int led_ctrl(cola_device_t *dev, int cmd, void *args)
{
  if(LED_TOGGLE==cmd)
  {
    LED_GREEN_TOGGLE;
  }
  else{
  }
  return1;
}


staticstructcola_device_opsops=
{
  .control=led_ctrl,
};


void led_register(void)
{
  led_gpio_init();
  led_dev.dops=&ops;
  led_dev.name="led";
  cola_device_register(&led_dev);
}

应用层app代码:

#include
#include"app.h"
#include"config.h"
#include"cola_device.h"
#include "cola_os.h"


statictask_ttimer_500ms;
static cola_device_t *app_led_dev;


//led每500ms状态改变一次
static void timer_500ms_cb(uint32_t event)
{
  cola_device_ctrl(app_led_dev,LED_TOGGLE,0);
}


void app_init(void)
{
  app_led_dev=cola_device_find("led");
  assert(app_led_dev);
  cola_timer_create(&timer_500ms,timer_500ms_cb);
  cola_timer_start(&timer_500ms,TIMER_ALWAYS,500);
}

这样 app.c 文件中就不需要调用 led.h 头文件了,rtt 就是这样实现的。

四、总结

这样就可以实现软硬件分层了,是不是非常好用!

五、代码下载链接

https://gitee.com/schuck/cola_os




审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    4983

    文章

    18291

    浏览量

    288539
  • STM32
    +关注

    关注

    2240

    文章

    10674

    浏览量

    348844
  • C语言
    +关注

    关注

    180

    文章

    7533

    浏览量

    128811

原文标题:分享一个通用的嵌入式驱动层

文章出处:【微信号:技术让梦想更伟大,微信公众号:技术让梦想更伟大】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式C语言面向对象编程---多态

    前两篇文章主要讲述了 C 语言面向对象编程– 封装和继承。本篇文章继续来讨论一下,如何使用 C 语言实现
    发表于 10-31 14:41 749次阅读

    labview面向对象编程

    点击学习>>《龙哥手把手教你学LabVIEW视觉设计》视频教程使用LabVIEW面向对象编程方法,对于大型测试应用程序来讲,面向对象相对于
    发表于 11-24 11:01

    C编程最佳实践.doc

    C编程最佳实践.doc
    发表于 08-17 14:37

    单片机C语言 -- 基于结构体的面向对象编程技巧

    1、Keil4 C51工程网址:2、需要一定的C语言基础,才看得懂此文。一、面向对象单片机C
    发表于 02-04 21:48

    TIA Portal面向对象编程入门资料下载

    少数人质疑面向对象编程思想,但我们看到的是面向对象技术发展的越来越好,无论是后端语言(JAVA
    发表于 07-02 06:56

    如何用C语言实现面向对象编程

    1 用C语言实现面向对象编程GOF的《设计模式》一书的副标题叫做“可复用面向
    发表于 07-12 07:24

    c语言实现面向对象编程 精选资料分享

    c语言面向对象框架(以RT-Thread软件包rt-robot为例)概述  有一种说法是c语言
    发表于 09-02 07:46

    谈谈面向对象编程

    在工业自动化领域,梯形图逻辑仍然是最常用的编程语言之一,但对于更加复杂的控制对象面向对象编程
    发表于 09-08 07:47

    面向对象编程语言的特点

    在工业自动化领域,梯形图逻辑仍然是最常用的编程语言之一,但对于更加复杂的控制对象面向对象编程
    发表于 09-08 07:44

    面向对象编程介绍

    目录一、面向对象编程介绍1.面向过程编程2.函数式编程3.
    发表于 12-13 07:22

    面向对象编程练习

    实验 3 面向对象编程练习 一、实验目的     通过编程和上机实验理解 Java 语言是如何体现
    发表于 09-23 18:57 2924次阅读

    这可能是Python面向对象编程最佳实践

    本节介绍了attrs和cattrs两个库,让实现Python面向对象编程不再难。
    的头像 发表于 06-22 12:07 2496次阅读

    C语言是如何实现面向对象

    ,C++是 面向对象编程语言,但面向对象的概念是在C语言
    的头像 发表于 12-24 17:08 2w次阅读
    C<b class='flag-5'>语言</b>是如何实现<b class='flag-5'>面向</b><b class='flag-5'>对象</b>的

    嵌入式C语言面向对象编程应用及优势

    既然面向对象是一种编程思想,而编程语言只是一种工具,那么,思想与工具之间就不存在一种强耦合的关系,C++可以
    发表于 11-10 12:00 1124次阅读
    嵌入式C<b class='flag-5'>语言</b><b class='flag-5'>面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b>应用及优势

    C语言是怎么面向对象编程

    在嵌入式开发中,C/C++语言是使用最普及的,在C++11版本之前,它们的语法是比较相似的,只不过C++提供了面向对象编程方式。
    的头像 发表于 02-14 13:57 1244次阅读
    C<b class='flag-5'>语言</b>是怎么<b class='flag-5'>面向</b><b class='flag-5'>对象</b><b class='flag-5'>编程</b>