TI: 以cpsw为例学习设备树(内核如何调用这些参数)
2017-09-08 12:30
344 查看
转载于 : http://46aae4d1e2371e4aa769798941cef698.devproxy.yunshipei.com/woshidahuaidan2011/article/details/48526081
对于设备数的语法网上已经有很多了,但是懂了语法之后可能还是不太理解具体设备树的工作原理,这里以ti的CPSW为例说明设备树与内核的驱动之家的微妙关系。
cpsw就是ti公司的Common Platform Ethernet Switch 的缩写,CPSW为三端口调换器(three port switch ),一个cpu端口,两个外部端口。CPSW或者说以太网调换驱动遵循标准的Linux网络接口构造。
对于TI的am335x的CPSW的设备树来说,其定义在am33x.dtsi文件中,内容如下:
mac:ethernet@4a100000 {
compatible ="ti,cpsw";
属性,这是跟驱动函数的匹配字符串,要跟驱动中一直。必须为“ti,cpsw“
ti,hwmods ="cpgmac0";
可选属性:对硬件模块的配置,为了跟驱动,必须是"cpgmac0"
clocks =<&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
指定时钟,其定义在 am33xx-clocks.dtsi文件中
clock-names ="fck", "cpts";
cpdma_channels = <8>;
cpdma(common platformdma)的通道数
ale_entries= <1024>;
制定ALE条目
bd_ram_size =<0x2000>;
描述内部ram的大小
no_bd_ram = <0>;
设置 HW descriptor 是否在内部bd ram,只能是0或者1
rx_descs = <64>;
制定RX描述符的个数
mac_control = <0x20>;
制定默认MAC控制寄存器的内容
slaves = <2>;
从站数量
active_slave = <0>;
cpts_clock_mult =<0x80000000>;
时钟周期转换ns系数的分子
cpts_clock_shift =<29>;
时钟周期转换ns系数的分母
reg = <0x4a100000 0x800
0x4a101200 0x100>;
cpsw寄存器映射地址
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent =<&intc>;
父中断控制器
/*
* c0_rx_thresh_pend
* c0_rx_pend
* c0_tx_pend
* c0_misc_pend
*/
interrupts = <40 41 4243>;
描述中断号
ranges;
davinci_mdio: mdio@4a101000{
compatible ="ti,davinci_mdio";
#address-cells =<1>;
#size-cells =<0>;
ti,hwmods ="davinci_mdio";
bus_freq =<1000000>;
reg = <0x4a1010000x100>;
};
cpsw_emac0: slave@4a100200{
以太网控制器
/* Filled in byU-Boot */
mac-address = [ 0000 00 00 00 00 ];
};
cpsw_emac1: slave@4a100300{
/* Filled in byU-Boot */
mac-address = [ 0000 00 00 00 00 ];
};
phy_sel:cpsw-phy-sel@44e10650 {
compatible ="ti,am3352-cpsw-phy-sel";
reg= <0x44e106500x4>;
phy寄存器的基地址和寄存器大小
reg-names ="gmii-sel";
};
};
接下来看一下内核是如何调用这些参数的:
首先在文件Cpsw.c (drivers\net\ethernet\ti)中的平台驱动结构体中有of_match_table匹配函数:
static structplatform_driver cpsw_driver = {
.driver = {
.name = "cpsw",
.owner = THIS_MODULE,
.pm = &cpsw_pm_ops,
.of_match_table= cpsw_of_mtable,
},
………………
};
驱动是否执行probe函数就是通过上面的函数判断的,就本例而言,首先会通过of_match_table进行判断是否在设备树种可以找到配对资源信息,假如在dtb文件中找不到其次判断是否在平台设备中是否有name为”cpsw”的设备,假如有的话则获取设备信息,然后执行驱动函数。但是,显然之前没有对platform_devicecpsw_device进行设置,因此一般情况下无法配对成功。
进一步展开of_match_table函数可得:
static conststruct of_device_id cpsw_of_mtable[] = {
{ .compatible ="ti,cpsw", },
{ /* sentinel */ },
};
结构体中.compatible = "ti,cpsw",正好跟设备树中的cpsw节点属性一致。于是会匹配成功,进而执行probe函数。
在probe函数中,驱动为了获取dts中设置的参数,其调用了cpsw_probe_dt。该函数的主要获取数据的函数有:
of_property_read_u32(node,"slaves", &prop)
获取在dts文件中的slaves的个数:slaves = <2>;
of_property_read_u32(node,"active_slave",
&prop)
获取设定的active_slave的参数:active_slave= <0>;
of_property_read_u32(node,"cpts_clock_mult", &prop)
获取设定的cpts_clock_mult的参数:cpts_clock_mult =
<0x80000000>;
后面的很多也很类似,不再一一列出。
就这样吧,内核启动就把dts中的信息读出来然后为之后的驱动程序提供数据。
对于设备数的语法网上已经有很多了,但是懂了语法之后可能还是不太理解具体设备树的工作原理,这里以ti的CPSW为例说明设备树与内核的驱动之家的微妙关系。
cpsw就是ti公司的Common Platform Ethernet Switch 的缩写,CPSW为三端口调换器(three port switch ),一个cpu端口,两个外部端口。CPSW或者说以太网调换驱动遵循标准的Linux网络接口构造。
对于TI的am335x的CPSW的设备树来说,其定义在am33x.dtsi文件中,内容如下:
mac:ethernet@4a100000 {
compatible ="ti,cpsw";
属性,这是跟驱动函数的匹配字符串,要跟驱动中一直。必须为“ti,cpsw“
ti,hwmods ="cpgmac0";
可选属性:对硬件模块的配置,为了跟驱动,必须是"cpgmac0"
clocks =<&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
指定时钟,其定义在 am33xx-clocks.dtsi文件中
clock-names ="fck", "cpts";
cpdma_channels = <8>;
cpdma(common platformdma)的通道数
ale_entries= <1024>;
制定ALE条目
bd_ram_size =<0x2000>;
描述内部ram的大小
no_bd_ram = <0>;
设置 HW descriptor 是否在内部bd ram,只能是0或者1
rx_descs = <64>;
制定RX描述符的个数
mac_control = <0x20>;
制定默认MAC控制寄存器的内容
slaves = <2>;
从站数量
active_slave = <0>;
cpts_clock_mult =<0x80000000>;
时钟周期转换ns系数的分子
cpts_clock_shift =<29>;
时钟周期转换ns系数的分母
reg = <0x4a100000 0x800
0x4a101200 0x100>;
cpsw寄存器映射地址
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent =<&intc>;
父中断控制器
/*
* c0_rx_thresh_pend
* c0_rx_pend
* c0_tx_pend
* c0_misc_pend
*/
interrupts = <40 41 4243>;
描述中断号
ranges;
davinci_mdio: mdio@4a101000{
compatible ="ti,davinci_mdio";
#address-cells =<1>;
#size-cells =<0>;
ti,hwmods ="davinci_mdio";
bus_freq =<1000000>;
reg = <0x4a1010000x100>;
};
cpsw_emac0: slave@4a100200{
以太网控制器
/* Filled in byU-Boot */
mac-address = [ 0000 00 00 00 00 ];
};
cpsw_emac1: slave@4a100300{
/* Filled in byU-Boot */
mac-address = [ 0000 00 00 00 00 ];
};
phy_sel:cpsw-phy-sel@44e10650 {
compatible ="ti,am3352-cpsw-phy-sel";
reg= <0x44e106500x4>;
phy寄存器的基地址和寄存器大小
reg-names ="gmii-sel";
};
};
接下来看一下内核是如何调用这些参数的:
首先在文件Cpsw.c (drivers\net\ethernet\ti)中的平台驱动结构体中有of_match_table匹配函数:
static structplatform_driver cpsw_driver = {
.driver = {
.name = "cpsw",
.owner = THIS_MODULE,
.pm = &cpsw_pm_ops,
.of_match_table= cpsw_of_mtable,
},
………………
};
驱动是否执行probe函数就是通过上面的函数判断的,就本例而言,首先会通过of_match_table进行判断是否在设备树种可以找到配对资源信息,假如在dtb文件中找不到其次判断是否在平台设备中是否有name为”cpsw”的设备,假如有的话则获取设备信息,然后执行驱动函数。但是,显然之前没有对platform_devicecpsw_device进行设置,因此一般情况下无法配对成功。
进一步展开of_match_table函数可得:
static conststruct of_device_id cpsw_of_mtable[] = {
{ .compatible ="ti,cpsw", },
{ /* sentinel */ },
};
结构体中.compatible = "ti,cpsw",正好跟设备树中的cpsw节点属性一致。于是会匹配成功,进而执行probe函数。
在probe函数中,驱动为了获取dts中设置的参数,其调用了cpsw_probe_dt。该函数的主要获取数据的函数有:
of_property_read_u32(node,"slaves", &prop)
获取在dts文件中的slaves的个数:slaves = <2>;
of_property_read_u32(node,"active_slave",
&prop)
获取设定的active_slave的参数:active_slave= <0>;
of_property_read_u32(node,"cpts_clock_mult", &prop)
获取设定的cpts_clock_mult的参数:cpts_clock_mult =
<0x80000000>;
后面的很多也很类似,不再一一列出。
就这样吧,内核启动就把dts中的信息读出来然后为之后的驱动程序提供数据。
相关文章推荐
- Pyhton 学习之——Class类中的变量参数是如何调用的
- 面对不断升级的内核,如何学习linux设备驱动
- lua脚本语言的学习-----------------如何实现c++无参数的函数在lua中调用
- 面对不断升级的内核,如何学习linux设备驱动
- .Linux设备驱动程序学习(0)——设备驱动介绍& Hello, world!模块 内核参数传递
- 核心网络设备配置及参数如何备份
- 核心网络设备配置及参数如何备份
- 如何使用 ADO.NET 和 Visual C# .NET 调用带参数的存储过程
- 实例学习如何在ASP中调用DLL
- CSharp Tips:调用Win32 API如何处理指针类型的参数.doc
- VFP如何调用一个带输出参数的Sql Server存储过程?
- 在JAVA里面如何调用ORCALE数据库里的存储过程(带输入输出参数)的????
- CSharp Tips:调用Win32 API如何处理指针类型的参数
- 如何解决mid使用过程中出现的以下问题(无效的过程调用或参数: 'mid')
- [C#学习]在多线程中如何调用Winform
- 收集到的:如何调用存储过程,有返回值的,有参数的,存储过程中调用存储过程。(MS SQL Server)
- 学习Altas 笔记[js调用重载的方法出错,如何处理]
- Intersge无法启动--原因是Message Queues的资源不足,共享内存不足 RedHat如何在系统运行过程中修改内核参数
- 在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysfs、sysctl、系统调用和netlink
- 学习如何在程序中调用.exe文件