DM365的BSP源码分析-基于2.6.18内核

DM365的BSP主要包含mach-davinci和plat-davinci两个目录(及相关头文件),BSP复杂庞大又极其重要,它主要完成了板级的初始化,比如内存映射,时钟和电源初始化,中断和IO初始化,CPU及各模块的初始化,相关平台设备,总线设备的注册等等。下面就分板一下DM365的BSP部分,以程序流程为纵线,以各个文件为横线,进行分析。
 
      内核在经过一系列的初始化后会进行板级的初始化,主要依靠一个MACHINE_START宏,DM365的板定义宏在board-dm365-evm.c文件中,这个宏有以下几个成员phys_io,io_pg_offst,boot_params,map_io,init_irq,timer,init_machine。这些成员变量或函数将会由内核在初始化时在适当的时机调用。DM365开发板对这几个成员都有针对其开发板的内容,phy_io设置为0x01c00000,这是DM365寄存器的起始地址。boot_params为0x80000100,它在DDR中,是用来存放UBOOT的传递参数的。map_io会调用davinci_map_io函数,完成开发板的静态地址映射,同时开发板中此函数还完成了MUX的功能初始化及各模块时钟的初始化。init_irq会调用davinci_dm365_evm_irq_init函数,对开发板的中断系统进行初始化。timer会调用davinci_timer相关的成员,它完成开发板的时间管理初始化。init_machine调用dm365_evm_init函数,完成板级设备(部分)的初始化。下面我们从davinci_map_io函数开始。
 
      davinci_map_io函数主要由三个部分组成,第一是中断优先级的初始化,中断优先级的初始化就是将全局中断优先级结构指针davinci_irq_priorities指向一个默认的中断优先级数组dm365_default_priorities,这个第二是调用davinci_map_common_io函数完成静态地址映射,第三是调用davinci_init_common_hw函数完成MUX的功能初始化及各模块时钟的初始化。
 
      davinci_map_common_io函数最主要就是完成了一段物理地址的静态虚拟地址映射,此后程序中操作这段物理地址的内容时不必再用ioremap动态得到一个虚拟地址了。至于如何做到映射的,不用去深究,只需要在map_desc结构定义的本平台使用的davinci_io_desc[]数组中中添加我们需要映射的地址段就可以了。开发板原程序中只映射了平台寄存器部分的地址空间,其物理起始地址,地址段大小,欲映射成的虚拟起始地址等值填入这个结构中就可以了。这些值定义中io.h文件中,其中物理起始地址IO_PHYS为0x01c00000,这正是寄存器物理地址段的起始地址,地址段大小IO_SIZE为0x00400000,这两个值由手册都可以知道。至于欲映射成的虚拟起始地址则由我们人为决定,可以选用IO_VIRT为0xfbc00000,这样物理地址和虚拟地址就有一个简单的偏移关系IO_OFFSET为0xfa000000。有了这个偏移关系,物理地址便和虚拟地址随时进行变换了,我们可以封装一个宏IO_ADDRESS用来做为物理地址到虚拟地址的转换。这里需要特别注意的,物理地址和虚拟地址的这层映射关系是内核来确定的,而两个地址的简单偏移关系是我们人为决定的,为了处理简单我们选了一个与物理地址有简单偏移关系的地址作为虚拟地址,并让内核去认同。静态映射一定要搞清楚这里面的东西,一开始很容易被迷惑的。davinci_map_common_io函数完成以后,接着是davinci_init_common_hw函数。
 
      davinci_init_common_hw函数极其重要,它里面只有两个函数,davinci_mux_init函数完成模块引脚复用功能的初始化,davinci_clk_init函数完成模块时钟的初始化。
 
      davinci_mux_init函数将各模块的复用进行初始化。它首先将几个重要的结构赋值,davinci_pins是二维指针,它被赋给一个和平台有关的默认的全局结构,比如dm365_pins,它是一个二维数组,分别定义了若干模块及每个模块需要用到的引脚,注意这个维数的索引值是对应模块在PSC管理中的索引值的。davinci_num_pins就是dm365_pins数组的维数。定义一个pin_config结构的指针table,并指向一个默认的全局结构数组davinci_dm365_pinmux,并得到这个数组的维数size。davinci_dm365_pinmux数组极其重要,它的每一维元素都是一个pin_config结构,它是用一个MUX_CFG宏来构造的,用于模块引脚复用功能的选择,实质是构造了欲对PINMUXx寄存器操作的位和欲写入的值。这个要好好理解,配合手册中PINMUXx寄存器理解。几个结构赋值以后就调用davinci_mux_register函数,这个函数将table赋给了全局结构指针pin_table,将size赋给全局变量pin_table_sz,将davinci_get_pins函数地址赋给函数指针get_pin_list,将一个标识用到哪一个pinmux寄存器的数组首址赋给全局指针pinmux_in_use。davinci_get_pins这个函数的作用是通过参数ctr和id来返回davinci_pins数组的某一维,它表示某一个模块用到的引脚。
 
      davinci_clk_init函数完成模块时钟的初始化。它首先将PSC寄存器的地址赋给全局指针psc_bases,然后通过读取PLL相关的寄存器得到预分频,倍频,后分频,分频等值(注意这些设置都在UBL进行设置好了,这里仅仅是读值),这样就得到了各个模块的时钟值,把它们赋给若干全局变量,比如armrate,voicerate,commonrate,vpssrate,ddrrate等。然后定义一个clk结构的指针clk_list,并指向一个默认的全局结构数组davinci_dm365_clks,并得到这个数组的维数num_clks。davinci_dm365_clks数组的每一维元素都是一个clk结构,定义了平台各个模块的时钟管理参数,包括模块名,时钟值,本模块在电源域的索引序号等。以后对某一模块进行时钟电源的开关就是操纵这个结构。
      然后调用davinci_enable_clks函数,这个函数实质是循环调用了clk_register函数和clk_enable函数,从而使能davinci_dm365_clks数组中定义的每一个模块的电源时钟。clk_register函数将当前模块放入全局的clocks链表中,而后根据usecount的判断值调用clk_enable函数,再调用__clk_enable函数,而其最终调用davinci_psc_config函数完成某一模块的时钟电源使能。需要特别注意的是此时几乎全部模块的usecount都不满足,不会调用clk_enable函数,而即使调用了clk_enable函数(AEMIF),也不会真正调用__clk_enable函数。也就是说这初始化部分并没有真正使能很多模块的时钟电源,只是按初始化的流程走了一个过程而已。在后面要提到的板级设备初始化部分会调用davinci_psc_config函数真正使能一些模块的时钟电源。另外其它模块的时钟电源则分布在各个模块的驱动程序中,当驱动加载的时候才会调用clk_enable函数打开这个模块的时钟电源。这部分挺迷惑人的,好好理解。
      davinci_psc_config函数的前一半工作是操作PSC相关的寄存器来使能模块的时钟电源,这部分的操作详见数据手册,是按手册的步骤来实现的,另一半工作是调用davinci_pinmux_setup函数来将此模块相关的复用引脚功能确定,它首先调用get_pin_list函数,它是个函数指针,在先前已经被指向了davinci_get_pins函数,它通过ctlr和id两个参数从先前的dm365_pins数组中得到相应的某一维,这正是某一模块需要的那些引脚。然后再通过一个循环将这几个引脚调用davinci_cfg_reg函数实现其复用的本模块的功能。
      davinci_cfg_reg函数,很重要也很复杂。它定义一个pin_config类型的指针cfg指向当前引脚在pin_table的位置,然后根据其所在的PINMUXx寄存器的位为操作。这里的实现过程操作比较复杂,涉及到屏蔽位,模式等,但总的来说就是模块需要这个引脚做此模块功能而不是其它功能,暂不深究。
 
      到这里,davinci_cfg_reg函数结束了,davinci_pinmux_setup函数也就结束了,davinci_psc_config函数也就结束了,__clk_enable,clk_enable,davinci_enable_clks函数也就结束了,davinci_clk_init函数也就结束了,davinci_init_common_hw函数也就结束了,davinci_map_io函数也就结束了。DM365的BSP板定义宏中的map_io也就结束了。下面分析板定义宏中的init_irq,它指向davinci_dm365_evm_irq_init函数,下面开始分析davinci_dm365_evm_irq_init函数。
 
      davinci_dm365_evm_irq_init函数,只调用一个davinci_irq_init函数。它首先获得全部64个中断的优先级数组,这个前面已经得到并放在全局数组davinci_irq_priorities中。而后操作INTC的寄存器,比如清除中断请求,禁止中断等,而后将设置好的优先级值写入优先级寄存器中。然后就将全部64个中断注册到内核中,主要是利用内核中断管理中的set_irq_chip函数,set_irq_flags函数,set_irq_handler函数,特别是set_irq_chip函数,它将每一个中断绑定到一个irq_chip结构类型的davinci_irq_chip_0,而它包括了三个对中断的处理的函数指针,比如使能unmask,禁止mask等,其实质还是操作了INTC的相关寄存器。这些函数就是在程序中,对某一中断进行使能,禁止的处理,比如调用enable_irq使能某一个中断时,其实最终就是调用unmask所指的函数。
 
      至此,davinci_irq_init函数结束了,davinci_dm365_evm_irq_init函数也就结束了。DM365的BSP板定义宏中的init_irq也就结束了。板定义宏中的timer感觉很复杂,现在不是很理解,以后有机会再看。下面分析板定义宏中的init_machine,它指向dm365_evm_init函数,下面开始分析dm365_evm_init函数。
 
      dm365_evm_init函数是BSP中最重要的了,它完成了部分设备的初始化及注册。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/254034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第四章:Django 模型 —— 设计系统表

1. Django框架提供了完善的模型(Model )层来创建和存储数据,每一个模型对应数据库中的唯一的一张表。 2. Django 模型基础知识: 。每一本模型是一个Python类,继承了django.db.models.Model类 。该模型中每一个属性一个…

DM365 使用BT656协议驱动LCD的实现

前两天已经调好了,主要是对davinci_platform.c的修改 因为输入输出都为pal的制式,所以就在pal的函数中进行了修改。 在PAL设置的函数中,修改如下: /* * setting PAL mode */ static void davinci_enc_set_pal(struct vid_enc_mode…

工业视觉镜头NAVITAR

品牌介绍 美国NAVITAR是优越的上等光学系统制造商和供应商,工业视觉镜头NAVITAR为机器视觉、检测和生物医学诊断行业提供的定制光学解决方案。 工业视觉镜头NAVITAR用于鉴定产品、检查产品缺陷、测量零件尺寸、操纵机器人设备和协助进行科学分析与探索。 还用来引导…

TCP系列48—拥塞控制—11、FRTO拥塞撤销

一、概述FRTO虚假超时重传检测我们之前重传章节的文章已经介绍过了,这里不再重复介绍,针对后面的示例在说明两点1、FRTO只能用于虚假超时重传的探测,不能用于虚假快速重传的探测。2、延迟ER重传触发的进入Recovery状态时候,并不会…

娱乐一下

6年前,没几个人知道尤里米尔纳(Yuri Milner)是谁。但今天,他已经是地球上最有名的投资人了。 短短几年内,这家伙掌管的风险投资基金DST(数字天空科技)投遍了全球的互联网明星企业,并…

机器视觉行业市场现状及发展前景分析

1.中国的机器视觉起步较晚,目前正处于快速增长期。 我国机器视觉最早起源于20世纪80年代。机器视觉生产线和先进设备自1998年众多电子、半导体企业落户广东、上海以来,先后在国内诞生了国际代理商和机器视觉系统集成商。 第一个阶段是1999-2003年的启蒙…

从bootm 命令讲起/U-boot的环境变量: bootcmd 和bootargs

从bootm 命令讲起 1 找到linux的内核入口 Bootm命令通过读取uImage的头部040字节的信息,将uImage定位到正确的地址,同时找到linux的内核入口地址。 这个地方就涉及到uImage的头部040字节信息到底是什么的问题?uboot提供了mkimage命令去把040字节加在lin…

关于创建SWAP示例

cd /data 进入指定目录dd if/dev/zero of/data/swapfile bs1M count102400【参数说明】if文件名&#xff1a;输入文件名&#xff0c;缺省为标准输入。即指定源文件。< ifinput file >of文件名&#xff1a;输出文件名&#xff0c;缺省为标准输出。即指定目的文件。< of…

一个公式来说明加接圈的作用和缺点

一个公式来说明加接圈的作用和缺点 在很多视觉项目中&#xff0c;如果想要将视野缩小&#xff0c;一种方式是换用长焦镜头&#xff1b;另一种方式则是通过加接圈的方式来实现。那么&#xff0c;接圈到底改变的是什么参数&#xff0c;能够使图像进行放大呢&#xff1f;核心公式上…

bzoj4636: 蒟蒻的数列

作为惟一一个离线动态开点线段树的。。我是不是没救了。。 维护一下区间修改和区间和。。。 然而由于一些奇怪的原因翻车 到最后索性跑到一个点直接开左右儿子 最后注意区间左右端点可以相等。。。 1 #include<cstdio>2 #include<iostream>3 #include<algorithm…

module_param 在内核编程中的作用

module_param 在用户态下编程可以通过main()的来传递命令行参数&#xff0c;而编写一个内核模块则通过module_param()! module_param的作用一.module_param1.为什么引入 在用户态下编程可以通过main()来传递命令行参数&#xff0c;而编写一个内核模块则可通过module_param()来传…

ubuntu 备忘

卷组扩容 Linux mint采用默认卷组的安装方式 sainLinux ~ $ df -hl Filesystem Size Used Avail Use% Mounted on udev 3.7G 0 3.7G 0% /dev tmpfs 743M 9.5M 733M 2% /run /dev/mapper/mint--vg-root…

DDL DML DCL

2019独角兽企业重金招聘Python工程师标准>>> DDL is Data Definition Language statements. Some examples:数据定义语言&#xff0c;用于定义和管理 SQL 数据库中的所有对象的语言 DML is Data Manipulation Language statements. Some examples:数据操作语言&…

学习halcon的论坛与书籍

论坛、培训 halcon学习网&#xff1a;http://www.ihalcon.com/鸟叔机器视觉&#xff1a;http://bbs.szvbt.com/forum.php 博客 韩兆新的博客园majunfuLife and Codingzhaojun的博客風韻無聲骑蚂蚁上高速的博客小马_xiaoLV2小新识图程序园-程序员的世界章柯渊的博客 注&…

LINUX内核中的xx_initcall初始化标号

LINUX内核中的xx_initcall初始化标号 田海立CSDN 2011-07-02 LINUX内核中有很多的初始化指示标志postcore_initcall(), arch_initcall(), subsys_initcall(), device_initcall(), etc. 这些起什么作用呢&#xff1f;查阅源代码&#xff08;android goldfish-2.6.29&#xff09;…

代码习惯---打印参数

打印参数很重要。转载于:https://www.cnblogs.com/Andomly/p/6050773.html

javascript设置和获取cookie的方法

设置cookie的方法&#xff0c;和获取cookie的方法例如以下 设置cookie document.cookie"name"value;//获取cookie当中index是cookie的名称function getCookie(index){var allcookies document.cookie; var cookie_pos allcookies.indexOf(index);if (cookie_pos !…

favicon.ico--网站标题小图片二三事

前言: 什么是favicon? 直接用图说话:这个就是favicon favicon.ico 是一种格式&#xff0c;一般用于网页地址栏前或者在标签上以缩略方式显示网站标志&#xff0c;也可以拖曳favicon到桌面以建立到网站的快捷方式。为什么要设置favicon图标&#xff0c;以图像形态显示&#xff…

镜头MTF传递函数解读

什么是镜头的MTF曲线&#xff1f;MTF全称是Modulation Transfer Function&#xff0c;译为调制传递函数&#xff0c;其单位以line/mm来表示。MTF综合反映了镜头的反差和分辨率特性&#xff0c; MTF是用仪器测量的&#xff0c;因而可以完全排除胶片等客观因素的影响和人工判读的…