嵌入式Linux裸机开发笔记5(IMX6ULL)—BSP工程管理实验(1)

引言

        在前面的笔记中,我们都是将所有的源码文件放到工程的根目录下,如果工程文件比较少的话这样做无可厚非,但是如果工程源文件达到几十、甚至数百个的时候,这样一股脑全部放到根目录下就会使工程显得混乱不堪。所以我们必须对工程文件做管理,将不同功能的源码文件放到不同的目录中。另外我们也需要将源码文件中,所有完成同一个功能的代码提取出来放到一个单独的文件中,也就是对程序分功能管理。本章我们就来学习一下如何对一个工程进行整理,使其美观、功能模块清晰、易于阅读。

5.1 工程管理简介

        打开我们上一章的工程根目录,如下图所示:

        在上图中我们将所有的源码文件都放到工程根目录下,即使这个工程只是完成了一个简单的流水灯的功能,但是其工程根目录下的源码文件就已经不少了。如果在添加一些其他的功能文件,那么文档就会更大,显得很混乱,所以我们需要对这个工程进行整理,将源码文件分模块、分功能整理。我们可以打开一个 STM32 的例程,如下图所示:
        上图中的工程目录就很美观、不同的功能模块文件放到不同的文件夹中,比如驱动文件就放到 HARDWARE 文件夹中, ST 的官方库就放到 STM32F10x_FWLib 文件夹中,编译产生的过程文件放到 OBJ 文件夹中。我们可以参考这个工程目录结构来整理第十二章的例程工程,新建名为“5_ledc_bsp ”的文件夹,在里面新建 bsp imx6ul obj project 4 个文件夹,
完成以后如下图 所示:

        其中 bsp 用来存放驱动文件; imx6ul 用来存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件;obj 用来存放编译生成的 .o 文件; project 存放 start.S main.c 文件,也就是应用文件;将上次实验中的 cc.h fsl_common.h fsl_iomuxc.h MCIMX6Y2.h 这四个文件拷贝到文件夹 imx6ul 中;将 start.S main.c 这两个文件拷贝到文件夹 project 中。我们前面的实验中所有的驱动相关的函数都写到了 main.c 文件中,比如函数 clk_enable led_init delay ,这三个函数可以分为三类:时钟驱动、LED 驱动和延时驱动。因此我们可以在 bsp 文件夹下创建三个子文件夹:clk delay led ,分别用来存放时钟驱动文件、延时驱动文件和 LED 驱动文件,这样main.c 函数就会清爽很多,程序功能模块清晰。工程文件夹都创建好了,接下来就是编写代码了,其实就是将时钟驱动、LED 驱动和延时驱动相关的函数从 main.c 中提取出来做成一个独立的驱动文件。

5.2 硬件原理分析

硬件就是led0前面的文章有说明,在此就不再赘述。

5.3.1 创建 imx6ul.h 文件

        新建文件 imx6ul.h ,然后保存到文件夹 imx6ul 中,在 imx6ul.h 中输入如下内容:
示例代码:
1 #ifndef __IMX6UL_H
2 #define __IMX6UL_H
3 /***************************************************************
5 文件名 : imx6ul.h
6 作者 : 嘴硬的xiaolaji
7 
8 描述 : 包含一些常用的头文件。
9 其他 :
10 
11 日志 :  2019/1/3 创建
12 ***************************************************************/
13 #include "cc.h"
14 #include "MCIMX6Y2.h"
15 #include "fsl_common.h"
16 #include "fsl_iomuxc.h"
17
18 #endif
        文件 imx6ul.h 很简单,就是引用了一些头文件,以后我们就可以在其他文件中需要引用imx6ul.h 就可以了。

5.3.2 编写 led 驱动代码

新建 bsp_led.h bsp_led.c 两个文件,将这两个文件存放到 bsp/led 中,在 bsp_led.h 中输入
输入如下内容:
示例代码 13.3.2.1 bsp_led.h 文件代码
1 #ifndef __BSP_LED_H
2 #define __BSP_LED_H
3 #include "imx6ul.h"
4 /***************************************************************
5  
6 文件名 : bsp_led.h
7 作者 : 嘴硬的xiaolaji
8 版本 : V1.0
9 描述 : LED 驱动头文件。
10 其他 :
11 
12 日志 : 初版 V1.0 2019/1/4 创建
13 ***************************************************************/
14
15 #define LED0 0
16
17 /* 函数声明 */
18 void led_init ( void );
19 void led_switch ( int led , int status );
20 #endif
        bsp_led.h 的内容很简单,就是一些函数声明,在 bsp_led.c 中输入如下内容:
示例代码:
1 #include "bsp_led.h"
2 /***************************************************************
3  
4 文件名 : bsp_led.c
5 作者 : 嘴硬的xiaolaji
6 版本 : V1.0
7 描述 : LED 驱动文件。
8 其他 :
9 
10 日志 : 初版 V1.0 2019/1/4 创建
11 ***************************************************************/
12
13 /*
14 * @description : 初始化 LED 对应的 GPIO
15 * @param : 无
16 * @return : 无
17 */
18 void led_init ( void )
19 {
20
/* 1 、初始化 IO 复用 */
21 IOMUXC_SetPinMux ( IOMUXC_GPIO1_IO03_GPIO1_IO03 , 0 );
22
23
/* 2 、、配置 GPIO1_IO03 IO 属性 */
24 IOMUXC_SetPinConfig ( IOMUXC_GPIO1_IO03_GPIO1_IO03 , 0X10B0 );
25
26
/* 3 、初始化 GPIO,GPIO1_IO03 设置为输出 */
27 GPIO1 -> GDIR |= ( 1 << 3 );
28
29
/* 4 、设置 GPIO1_IO03 输出低电平,打开 LED0*/
30 GPIO1 -> DR &= ~( 1 << 3 );
31 }
32
33 /*
34 * @description : LED 控制函数,控制 LED 打开还是关闭
35 * @param - led : 要控制的 LED 灯编号
36 * @param - status : 0 ,关闭 LED0 1 打开 LED0
37 * @return :
38 */
39 void led_switch ( int led , int status )
40 {
41 switch ( led )
42
{
43 case LED0 :
44 if ( status == ON )
45 GPIO1 -> DR &= ~( 1 << 3 ); /* 打开 LED0 */
46 else if ( status == OFF )
47 GPIO1 -> DR |= ( 1 << 3 ); /* 关闭 LED0 */
48 break ;
49 }
50 }
        bsp_led.c 里面就两个函数 led_init led_switch led_init 函数用来初始化 LED 所使用的
IO led_switch 函数是控制 LED 灯的打开和关闭,这两个函数都很简单。

5.3.3 编写时钟驱动代码

        新建 bsp_clk.h bsp_clk.c 两个文件,将这两个文件存放到 bsp/clk 中,在 bsp_clk.h 中输入如下内容:
示例代码:
1 #ifndef __BSP_CLK_H
2 #define __BSP_CLK_H
3 /***************************************************************
5 文件名 : bsp_clk.h
6 作者 : 嘴硬的xiaolaji
7 版本 : V1.0
8 描述 : 系统时钟驱动头文件。
9 其他 :
10 
11 日志 : 初版 V1.0 2019/1/4 创建
12 ***************************************************************/
13
14 #include "imx6ul.h"
15
16 /* 函数声明 */
17 void clk_enable ( void );
18
19 #endif
        bsp_clk.h 很简单,在 bsp_clk.c 中输入内容:
示例代码:
1 #include "bsp_clk.h"
2
3 /***************************************************************
5 文件名 : bsp_clk.c
6 作者 : 嘴硬的xiaolaji
7 版本 : V1.0
8 描述 : 系统时钟驱动。
9 其他 :
10 
11 日志 : 初版 V1.0 2019/1/4 创建
12 ***************************************************************/
13
14 /*
15 * @description : 使能 I.MX6U 所有外设时钟
16 * @param : 无
17 * @return : 无
18 */
19 void clk_enable ( void )
20 {
21 CCM -> CCGR0 = 0XFFFFFFFF ;
22 CCM -> CCGR1 = 0XFFFFFFFF ;
23 CCM -> CCGR2 = 0XFFFFFFFF ;
24 CCM -> CCGR3 = 0XFFFFFFFF ;
25 CCM -> CCGR4 = 0XFFFFFFFF ;
26 CCM -> CCGR5 = 0XFFFFFFFF ;
27 CCM -> CCGR6 = 0XFFFFFFFF ;
28 }
        bsp_clk.c 只有一个 clk_enable 函数,用来使能所有的外设时钟。
13.3.4 编写延时驱动代码
新建 bsp_delay.h bsp_delay.c 两个文件,将这两个文件存放到 bsp/delay 中,在 bsp_delay.h
中输入输入如下内容:
示例代码:
1 #ifndef __BSP_DELAY_H
2 #define __BSP_DELAY_H
3 /***************************************************************
4  
5 文件名 : bsp_delay.h
6 作者 : 嘴硬的xiaolaji
7 版本 : V1.0
8 描述 : 延时头文件。
9 其他 :
10 
11 日志 : 初版 V1.0 2019/1/4 创建
12 ***************************************************************/
13 #include "imx6ul.h"
14
15 /* 函数声明 */
16 void delay ( volatile unsigned int n );
17
18 #endif
bsp_delay.c 中输入内容:
示例代码:
/***************************************************************
文件名 : bsp_delay.c
作者 : 嘴硬的xiaolaji
版本 : V1.0
描述 : 延时文件。
其他 :
日志 : 初版 V1.0 2019/1/4 创建
***************************************************************/
1 #include "bsp_delay.h"
2
3 /*
4 * @description : 短时间延时函数
5 * @param - n : 要延时循环次数 ( 空操作循环次数,模式延时 )
6 * @return : 无
7 */
8 void delay_short ( volatile unsigned int n )
9 {
10
while ( n --){}
11 }
12
13 /*
14 * @description : 延时函数 , 396Mhz 的主频下
15 * 延时时间大约为 1ms
16 * @param - n : 要延时的 ms
17 * @return :
18 */
19 void delay ( volatile unsigned int n )
20 {
21 while ( n --)
22 {
23 delay_short ( 0x7ff );
24 }
25 }
        bsp_delay.c 里面就两个函数, delay_short delay ,这两个其实就是第十二章中 main.c 里面的函数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值