博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
例说uboot从命令到驱动
阅读量:5265 次
发布时间:2019-06-14

本文共 2369 字,大约阅读时间需要 7 分钟。

我们知道uboot的最终目标是实现将OS内核由flash中复制到ram中,并跳到操作系统分内核的入口address,将处理器的控制权交给操作系统。U-boot的一个很重要的特点就是使用命令实现对底层的操作,通过执行指令我们就可以实现上述目标。这里以实现一个简单的led_blink硬件操作,解析uboot从命令执行到操作led的过程。依照这个example,我们可以对对包括NAND,USB,串口等驱动的执行过程以及uboot的移植有一个相对清晰的认识。

在common目录下面是常用的命令文件,文件名格式为cmd_xxx.c。如图:

在这个目录下建立我们的命令,以及命令指定的操作函数。操作函数调用drivers目录下的驱动程序,也就是直接操作硬件的代码。drivers目录下包含了各类具体设备的驱动程序,基本上是通用的,它们通过宏从外部引入与平台或者开发板相关的functions。如图:

从单片机的角度,drivers目录下面的驱动文件由该驱动文件同目录的makefile文件指定预处理、编译、生成静态库文件,链接器从库文件取得所需的代码,复制到生成的中。所以我们需要将我们自己写的驱动文件和命令文件都要在makefile中指定编译规则。

下面是led_blink具体实现过程。

首先从功能的角度,我们要实现从上层的命令操作到底层的物理操作,需要建立两个文件,一个是在drivers/gpio/sml2440_led_blink.c文件;一个是在

文件。这样我们就可以分别依照uboot的规则,在sml2440_led_blink.c文件中写驱动,在cmd_ledblink.c文件中写命令了。

cmd_ledblink.c具体的内容如下:

 

//common/cmd_ledblink.c#include 
#include
int do_led(void){ s3c24x0_led_blink(); return 0 ;}U_BOOT_CMD( led, 2, 1, do_led, "ledblink, just for test", "测试指令,让led闪烁" "学习指令和驱动流程");

分析:

 

U_BOOT_CMD();是建立指令的格式(宏),led是指令名称,2是指令的参数个数,1是指令可重复执行,do_led是指令执行的函数指针。所以我们再写了一个do_led的函数,其内容是调用底层驱动的s3c24x0_led_blink();函数。头文件自行分析。

drivers/gpio/sml2440_led_blink.c文件内容如下:

//drivers/gpio/sml2440_led_blink.c#include 
#include
static void delay (unsigned long loops){ __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0" (loops));}int s3c24x0_led_init(void){ struct s3c24x0_led *led = s3c24x0_get_base_led(); led->GPFCON = 0x55 ; led->GPFUP = 0xff ; led->GPFDAT = 0 ; return 0 ;}int s3c24x0_led_blink(void){ int N = 10 ; struct s3c24x0_led *led = s3c24x0_get_base_led(); while(N--){ led->GPFDAT = 0xff ; delay(20000000); led->GPFDAT = 0x00 ; delay(20000000); } return 0 ; }

分析:首先我们知道上层的指令led将调用s3c24x0_led_blink()函数,我们在底层续写之。为了实现这个函数,满足对底层操作的要求,我们需要操作控制led的寄存器。相信程led闪烁的方式都看得懂,就是让io引脚延时拉高,延时拉低的结果。  struct s3c24x0_led *led = s3c24x0_get_base_led();在 这篇博文里已有说明,是取出一块首地址固定符合自定义寄存器要求的内存空间。我们在s3c24x0.h中定义一块连续的寄存器空间,具体实现方法请查看链接博文(这里只是一个实现的技巧)。然后对寄存器写数据即可。

 

紧接着为了生成可执行文件,我们还需要对makefile进行modified,指定规则使source file被编译。对drivers/gpio下的makefile文件内添加:

COBJS-$(CONFIG_SML2440_LED)		+= sml2440_led_blink.o

然后就会被连接生成静态库

 

 

LIB 	:= $(obj)libgpio.a

对于common下面的makefile文件,添加如下code即可。

 

 

COBJS-y += cmd_ledblink.o

这样我们把编译生成的uboot镜像文件下载到flash中,在terminal输入help,就会看到led驱动及其说明。我们敲入led,就会看到led闪烁了十次后,terminal回到命令接受模式。这样led_blink的uboot下的实现就完成了。

 

 

转载于:https://www.cnblogs.com/jiangu66/archive/2013/04/22/3035885.html

你可能感兴趣的文章
Oracle HRMS API's
查看>>
PostgreSQL中如何查看一个表所对应的文件
查看>>
mysql_real_escape_string() vs addslashes() vs addcslashes()
查看>>
string与stringbuilder的区别
查看>>
2012-01-12 16:01 hibernate注解以及简单实例
查看>>
iOS8统一的系统提示控件——UIAlertController
查看>>
基于visual Studio2013解决C语言竞赛题之1060寻找回文数
查看>>
几道字典树题目
查看>>
PAT甲级——1101 Quick Sort (快速排序)
查看>>
Stripe
查看>>
python创建进程的两种方式
查看>>
1.2 基础知识——关于猪皮(GP,Generic Practice)
查看>>
迭代器Iterator
查看>>
java易错题----静态方法的调用
查看>>
php建立MySQL数据表
查看>>
最简单的线程同步的例子
查看>>
结对编程总结 1175 1176
查看>>
内核链表使用--删除链表节点
查看>>
eclipse启动无响应,停留在Loading workbench状态
查看>>
How exactly does Google AdWords work?
查看>>