最近学习内容:
u-boot,设备树,文件系统,驱动以及设备的应用,STM32开发等。
学习重点一:驱动开发
驱动开发需要有开发的环境,内核和文件系统以及驱动代码。
因为我们是在网络中获取系统,所以需要先在电脑上配置环境,然后再转到板子上。
1、ubuntu中配置环境
内核实现、文件系统实现、驱动实现---ubuntu中实现
gcc-4.6.4----->arm-none-linux-gnueabi-gcc
a、通过tftp提供uImage和.dtb----提供内核
b、通过nfs提供文件系统rootfs
2、板子运行环境配置
a、板子上运行uboot引导程序
b、配置uboot环境变量
ipaddr
serverip
gatewayip
支持网络--uboot
bootcmd----uboot自启动模式自动执行
bootcmd tftp 41000000 uImage \; tftp 42000000 xxx.dtb\; bootm 41000000 - 42000000
bootargs----uboot提供给操作系统内核,内核知道怎么执行----执行bootm时
bootargs /dev/nfs rootfs=xxxxx:/xxxxx/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=xxxxxx
c、uboot通过tftp下载内核和设备树
tftp 内存地址 uImage
tftp 内存地址 .dtb
d、uboot运行启动内核
bootm 内核地址 - 设备树地址
a、内核编译
步骤:
1、设置交叉编译环境
打开Makefile
vim Makefile
更改内容
ARCH ?= arm
CROSS_COMPILE ?= /home/ubuntu/tools/gcc-4.6.4/bin/arm-none-linux-gnueabi-
2、选择soc,找到当前硬件对应的soc芯片,必须挑选适配于当前硬件
make exynos_defconfig
生成.config------编译配置(哪些要编译,哪些不编译,内核有哪些功能)
3、针对默认的soc芯片进行裁剪适配于当前硬件
make menuconfig
4、编译内核
make uImage
5、编译设备树:描述设备信息
找最相近的外设设备树,进行修改变成当前硬件设备的设备信息描述
以默认的dts作为参考,变为我们自己的dts
cp linux-3.14/arch/arm/boot/dts/exynos4412-origen.dts linux-3.14/arch/arm/boot/dts/exynos4412-fs4412.dts
vim linux-3.14/arch/arm/boot/dts/Makefile---添加编译
6、编译设备树
make dtbs
学习重点2:中断驱动
中断驱动---检测外部中断
获取外设的数据内容,通过中断信号进行获取
在驱动中设置外设为中断模式:当外设产生设定的特定信号(就是中断)
在驱动中实现中断处理操作(函数)
1、中断号:就是一个号码,中断控制器管理所有中断的编号,外设连接的引脚就对应了引脚的中断控制器的中断号
有硬件设备----设备的中断号
驱动如何获取中断号:
1、宏定义
IRQ_EINT(中断号)
2、设备树中描述,然后再驱动中获取
arch/arm/boot/dts/exynos4412-fs4412.dts
在设备树中添加硬件信息(包括中断)
硬件:
key3 ------GPX1_2--------EINT10 在设备树中:arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
gpx1: gpx1 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
interrupt-parent = <&gic>;
interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
#interrupt-cells = <2>;
};
在设备树中添加自己的硬件设备信息---添加key3节点-----描述当前设备的的信息内容(中断号)
arch/arm/boot/dts/exynos4412-fs4412.dts:实现硬件描述(中断号)
key3_node {
compatible = "key3";
interrupt-parent = <&gpx1>;
interrupts = <2 4>;//26
};
重新编译设备树,发给共享文件夹,即板子的文件系统依托文件夹
make dtbs
cp arch/arm/boot/dts/exynos4412-fs4412.dtb ~/tftp/
2、实现驱动工作----中断驱动应该做什么
(外设产生中断,驱动要能检测到中断---申请中断(根据中断号))
(处理外设产生的中断)
在驱动中申请中断,实现中断处理
a、获取到中断号
获取设备树节点,返回值就是从设备树中找到的节点
struct device_node *of_find_node_by_path(const char *path);
从节点中获取到中断号,返回值就是中断号
unsigned int irq_of_parse_and_map(struct device_node *dev,int index);
b、申请中断
typedef irqreturn_t (*irq_handler_t)(int, void *);----类型替换,irq_handler_t代表函数指针
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
参数1:
unsigned int irq:申请中断的中断号
参数2:
irqreturn_t (*)(int, void *) ---- irq_handler_t
irq_handler_t handler:函数指针,进行注册中断,当产生中断时调用对应的函数进行处理
参数3:
unsigned long flags:中断处理的触发方式
#define IRQF_TRIGGER_NONE 0x00000000
#define IRQF_TRIGGER_RISING 0x00000001
#define IRQF_TRIGGER_FALLING 0x00000002
#define IRQF_TRIGGER_HIGH 0x00000004
#define IRQF_TRIGGER_LOW 0x00000008
参数4:
const char *name:字符串首地址,中断的描述信息
/proc/inruppter
参数5:
void *dev:传递给参数2的函数进行自动调用的(作为参数2这个函数的参数)
返回值:
成功返回0,失败返回非0
释放中断:
void free_irq(unsigned int irq,void * dev_id)
参数1:
unsigned int irq
中断号
参数2:
void * dev_id:与申请中断第五个参数保持一致
对于这段时间的学习内容重点较多,我就提出一个基础和一个难点进行记录一下。
个人学习感受:
对于驱动开发部分掌握不多,涉及的内容个人感觉不太好理解,能够自己实际运用的操作不多,更多的还是需要依靠各种资料来辅助。另外对于自己通过写代码,让一块板子拥有很多功能的操作个人感觉还是很不错的。有着一种成就感。
另外就是对于STM32的开发,现在刚开始学不久,不过感觉比前面学习的驱动开发简单不少,运用HAL函数库能帮我们很简单的完成很多操作。不需要像驱动裸机开发的时候那样,什么东西都得亲力亲为。各种引脚的配置,引脚电平的更改,定时器的开启和关闭,定时器的时间限定等各种操作在STM32上明显感受到了操作量的减少。
个人学习总结:
驱动开发和STM32的学习让我对代码控制硬件的操作有了明确的认识,对于芯片,设备,驱动,软件,机器之间的关系得到了新的认知。对于这个方向我有着很深的兴趣,可又感觉想深入有着还很多的困难。最近又在各种招聘会的影响下学习的兴致薄弱不少,更多心思放在了找工作上。目前就是跟着学习,等以后有空了找时间来接着深入研究。