第28章_瑞萨MCU零基础入门系列教程之基于面向对象的工程结构

2023-09-13 23:02:24

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id=728461040949

配套资料获取:https://renesas-docs.100ask.net

瑞萨MCU零基础入门系列教程汇总https://blog.csdn.net/qq_35181236/article/details/132779862


第28章 基于面向对象的工程结构

在前面的章节里,讲解了瑞萨RA6M5的常用外设,重点在于模块的操作原理、如何使用RASC进行配置、如何编写程序。这些模块功能单一,RASC生成的代码封装良好,也是基于面向对象的思想构造了对应的结构体。但是在使用这些模块时,我们没有特意使用面向对象的思想来写程序。

本章之后的内容,将会在FSP所提供的HAL库基础上,去操作更丰富的模块。这些模块的驱动程序,不应该跟底层的HAL库紧密绑定:比如温湿度传感器DHT11的驱动程序,既可以在RA6M5上运行,也能够非常容易地移植到其他平台上。在编写模块驱动程序时,就要把程序分层,每层之间设计好接口,然后使用面向对象的思想来实现各层。

随着功能的增加,一个工程涉及的文件会越来越多,本书设计了如下图所示的工程结构:

  1. 应用程序

位于applications目录下,用于存放业务相关的代码,它们可能是多个模块对象的联调,也可能是数据的处理。比如“根据按键操作LED”,这就属于应用层的代码。按键和LED的操作函数,不属于应用层,而是属于底下的设备层。

这一层需要和底层驱动完全解耦合:这一层的代码移植到其它平台时,无需修改代码。

  1. 头文件

位于include目录下,主要存放error.h和config.h,前者用于统一错误代码,后者用于配置整个工程。

  1. 设备层

位于devices目录。简单设备的文件直接放在devices目录里;对于模块,在devices目录下根据模块名字创建一个子目录,用来存放模块的文件。

在dev_xxx.h中根据设备的特性定义一些结构体,在dev_xxx.c里实现了这些结构体,并使用链表来管理同类设备。上层代码获取这些结构体后,就可以直接调用结构的函数指针来操作设备。

以GPIO设备为例,实现了4个函数:

void IODevicesRegister(void);
void IODeviceInsert(struct IODev *ptdev);
struct IODev *IODeviceFind(const char *name);
void IODeviceList(void);
  • IODevicesRegister:注册所有使用到的GPIO设备;
  • IODeviceInsert:这个函数被底层的drv_gpio.c调用,用来插入一个GPIO设备;
  • IODeviceFind:根据名称查找IO设备;
  • IODeviceList:打印所有的IO设备;
  1. 驱动层

位于drivers目录,存放的平台相关的驱动源代码。

drivers.h:根据config.h中的宏开关,包含drv_xxx.h。

drv_xxx.h:接口,供外部代码调用。

drv_xxx.h:驱动代码,一般用来实现并注册dev_xxx.h中声明的结构体,会调用平台提供的HAL库。

仍以GPIO设备为例,在dev_gpio.h里抽象出了IODev接构体,如下:

typedef struct IODev{
    char            *name;
    unsigned int    port;
    unsigned char   value;
    int             (*Init)(struct IODev *ptDev);
    int             (*Write)(struct IODev *ptDev, unsigned char level);
    int             (*Read)(struct IODev *ptDev);
    struct IODev *next;
}IODevice, *pIODevice;

在drv_gpio.c,对于每一个GPIO引脚,都要实现一个IODev结构体,示例如下:

static struct IODev gDQDev = {
    .name = "DS18B20 DQ",
    .port = BSP_IO_PORT_00_PIN_03,
    .value = 0,
    .Init = IODrvInit,
    .Read = IODrvRead,
    .Write = IODrvWrite,
    .next = NULL
};

最后,在drv_gpio.c里还要实现一个函数,用来注册这些IODev:

void IODevicesCreate(void)
{
    IODeviceInsert(&gDQDev);
}

在drv_gpio.h里声明IODevicesCreate函数,供外部代码调用。

  1. 自定义库

位于libs目录。

存放一些通用功能模块,例如延时函数、环形缓冲区函数、printf重定向函数等。一般来说这些模块跟底层硬件关系不大,但是也有例外。比如延时函数跟底层硬件定时器密切相关,但是它太常用了,所以也放在libs目录下。

  1. RA库

这一层是一个泛指,RA相关的代码。比如使用RASC生成工程时,这些目录的代码都是自动生成的:ra、ra_cfg、ra_gen,它们都属于“RA库”。


本章完
更多推荐

IllusionDiffusion:OpenAI 推出的图像生成新工具

OpenAI近日发布了一款名为IllusionDiffusion的图像生成器,它利用了一种名为“幻觉扩散”的技术来生成逼真的图像。幻觉扩散是一种基于生成对抗网络(GAN)的技术,它通过不断地对原始图像进行修改来生成新的图像。在IllusionDiffusion中,原始图像被称为“幻觉”,而新的图像被称为“扩散”。Ill

【腾讯云】打造未来智能应用的基石:腾讯混元大模型

写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成,愿将昔日所获与大家交流一二,希望对学习路上的你有所助益。同时,博主也想通过此次尝试打造一个完善的技

Python数据分析的增强式AI库

迷途小书童读完需要4分钟速读仅需2分钟1引言近年来,随着数据集的不断增大和复杂性的提高,数据分析变得越来越具有挑战性。在Python中,Pandas一直是处理和分析结构化数据的首选库。然而,随着人工智能的发展,我们需要一种能够轻松应对这些挑战的工具。幸运的是,PandasAI应运而生,它将Pandas的强大功能与人工智

合肥对新通过(CMMI)五级、四级、三级认证的软件企业,对新通过信息技术服务标准(ITSS)认证的软件企业,给予最高50万奖励

合肥市加快软件产业发展推进软件名城创建若干政策实施细则为贯彻落实《合肥市人民政府办公室关于印发合肥市加快软件产业发展推进软件名城创建若干政策的通知》(合政办〔2023〕9号)文件精神,规范政策资金管理,制定本实施细则。一、申报主体在合肥市行政区域范围内注册成立、具有独立法人资格的软件企业或软件园区运营单位。本实施细则中

SpringMVC自定义注解

目录一,Java注解简介1.java注解的定义2.Java注解分类2.1JDK基本注解2.2JDK元注解2.3自定义注解二,自定义注解如何自定义注解?三,Aop自定义注解的应用四,总结一,Java注解简介1.java注解的定义Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配

网页游戏如何开发网页游戏类型有哪些?

随着互联网的普及和技术的发展,网页游戏已经成为娱乐和休闲活动的重要组成部分。无需安装任何应用程序,只需打开浏览器,您就可以畅玩各种类型的网页游戏。然而,开发网页游戏并不是一项容易的任务,因为不同类型的游戏需要不同的开发方式和技术。在本文中,我们将探讨一些常见的网页游戏类型以及它们的开发方式。1.休闲游戏开发休闲游戏通常

【B+树索引】索引的使用和注意事项

索引的使用和注意事项一、索引的注意事项根节点是不会变的!内节点中目录项记录的唯一性一个页面至少容纳两条记录二、回表的代价三、更好的使用索引四、索引的代价一、索引的注意事项上一篇【B+树索引】索引页的结构含有可以快速查询的秘密从索引页的角度认识了MySQL为了提升查询速率,使用了B+树的数据结构对索引页进行了内存存储。以

【2023华为杯B题】DFT类矩阵的整数分解逼近(思路及代码下载)

💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。⛳️座右铭:行百里者,半于九十。📋📋📋本文目录如下:🎁🎁🎁目录💥1概述📚2详细数学模型及题目、数据🎉3参考文献🌈4Matlab代码及思路实现💥1概述离散傅里叶变换(Discre

爬虫逆向实战(34)-某视综数据(MD5、AES)

一、数据接口分析主页地址:某视综1、抓包通过抓包可以发现数据接口是/rank/waiting/fans2、判断是否有加密参数请求参数是否加密?通过查看“载荷”模块可以发现有一个sign参数请求头是否加密?无响应是否加密?通过查看“响应”模块可以发现数据是加密的cookie是否加密?无二、加密位置定位1、sign(1)看

c++八股day3-c++什么时候生成默认拷贝构造函数

背景:如果不提供,就是浅拷贝,即位拷贝(把值按字节复制过去)位拷贝的危害:1、比如某个类的对象当中有堆上的资源(里面有一个指针指向了堆上的资源)2、文件句柄、socket3、虚函数表指针可能会丢失。。。如果是位拷贝,就会出现两个对象持有相同的堆上资源、文件句柄如果有一个对象释放,释放时会把堆上资源进行释放,把文件句柄进

App测试中ios和Android有哪些区别呢?

App测试中,大家最常问到的问题就是:ios和Android有什么区别呢?在Android端,我们经常会使用JavaScript、HTML、CSS等技术来编写一些简单的UI界面。而iOS端,我们经常会使用到UI设计、界面布局、代码结构、API等技术来开发一款App。那究竟有什么区别呢?作为一名开发者,应该了解一些基础知

热文推荐