- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
7.DB410c开发板dts加载功能测试
录入:edatop.com 点击:
DTS是Device Tree Source的缩写,用来描述设备的硬件细节。在过去的ARM Linux中,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节,而这些板级细节对于内核来讲,不过是垃圾,如板上的platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data。为了去掉这些垃圾代码,Linux采用DTS这种新的数据结构来描述硬件设备。采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在kernel中进行大量的冗余编码。
Linux在启动后,到C入口时,会执行以下操作,加载系统平台上的总线和设备:
start_kernel() init/main.c
--> setup_arch() arch/arm64/kernel/setup.c
--> unflatten_device_tree() drivers/of/fdt.c
unflatten_device_tree函数将DTS节点信息解析出来,保存到allnodes链表中。
随后系统启动,接着调用arch/arm64/kernel/setup.c文件中arm64_device_init函数-->of_platform_populate(....)接口,加载平台总线和平台设备。至此,系统平台上的所有已配置的总线和设备将被注册到系统中。
注意:不是dtsi文件中所有的节点都会被注册,在注册总线和设备时,会对dts节点的状态作一个判断,如果节点里面的status属性没有被定义,或者status属性被定义了并且值被设为“ok”或者“okay”,其他情况则不被注册到系统中。
dtsi定义:

dtsi加载代码:#include "unflatten_dts.dtsi"
驱动源代码:
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/device.h>
- #include <linux/platform_device.h>
- #include <linux/sysfs.h>
- #include <linux/slab.h>
- #include <linux/kernel.h>
- #include <linux/kobject.h>
- #include <linux/string.h>
- #include <linux/of.h>
- #define UNFLATTEN_DTS_TIP "unflatten_dts_tip"
- char unflatten_dts_code[64] = "UNFLATTEN_DTS, unflatten_dts_show";
- static ssize_t show(struct device_driver *driver, char *buf)
- {
- if(NULL != buf)
- {
- /* Newline is not appended on purpose, for convenience of reader programs */
- snprintf(buf, PAGE_SIZE, "%s\n", unflatten_dts_code);
- return strlen(buf);
- }
- return 0;
- }
- DRIVER_ATTR(unflatten_dts, 0444, show, NULL);
- static struct attribute *unflatten_dts_attrs[] = {
- &driver_attr_unflatten_dts.attr,
- NULL,
- };
- static struct attribute_group unflatten_dts_group = {
- .name ="unflatten_dts",
- .attrs = unflatten_dts_attrs,
- };
- static const struct attribute_group *unflatten_dts_groups[] = {
- &unflatten_dts_group,
- NULL,
- };
- static int unflatten_dts_probe(struct platform_device *pdev)
- {
- int nNum;
- const char *m_string;
- if(NULL == pdev)
- {
- printk("xiaomi_test: unflatten_dts_probe failed, pdev is NULL\n");
- return 0;
- }
- if(NULL == pdev->dev.of_node)
- {
- printk( "xiaomi_test: unflatten_dts_probe failed, of_node is NULL\n");
- return 0;
- }
- /* UNFLATTEN_DTS_TIP*/
- if(of_property_read_bool(pdev->dev.of_node, UNFLATTEN_DTS_TIP))
- {
- printk( "unflatten_dts_probe: dtsi<%s> is existing\n", UNFLATTEN_DTS_TIP);
- }
- if (of_property_read_u32(pdev->dev.of_node, "linux,code", &nNum))
- {
- printk(KERN_INFO "=11= nNum=%d\n", nNum);
- }
- else
- {
- printk(KERN_INFO "=12= nNum=%d\n", nNum);
- }
- if (of_property_read_string(pdev->dev.of_node, "linux,string", &m_string))
- {
- printk(KERN_INFO "=11= m_string=%s\n", m_string);
- }
- else
- {
- printk(KERN_INFO "=12= m_string=%s\n", m_string);
- }
- return 0;
- }
- /* .compatible的信息要与dtsi中的compatible一致 */
- static struct of_device_id unflatten_dts_info_match_table[] = {
- { .compatible = "unflatten_dts",},
- { },
- };
- static struct platform_driver unflatten_dts = {
- .driver = {
- /* 当然这里的name要跟dtsi的节点DTS_TEST一致 */
- .name = "unflatten_dts",
- .owner = THIS_MODULE,
- .groups = unflatten_dts_groups,
- .of_match_table = unflatten_dts_info_match_table,
- },
- .probe = unflatten_dts_probe,
- .remove = NULL,
- };
- static int __init unflatten_dts_init(void)
- {
- return platform_driver_register(&unflatten_dts);
- }
- static void __exit unflatten_dts_exit(void)
- {
- platform_driver_unregister(&unflatten_dts);
- }
- module_init(unflatten_dts_init);
- module_exit(unflatten_dts_exit);
- MODULE_LICENSE("GPL");
Makefile文件:

编译,拷贝,insmod后的运行信息如下:


将前者与dtsi的内容做比较,我们可以确定dtsi文件里面的信息显示完全正确。
后者则是sysfs的一个显示,修改代码可以将dtsi中的内容在设备节点中显示。
知识点:
1.linux kernel的加载顺序;
2.dts dtsi的概念,应用;
3.sysfs概念,应用;
4.驱动模块编译,加载。
代码那块好乱。
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗霉閿濆牊顏犵紒鈧繝鍌楁斀闁绘ɑ褰冮埀顒€顕槐鎾愁潩鏉堛劌鏋戦梺鍝勫暙閻楀嫰鍩€椤戣法绐旂€殿喕绮欓、姗€鎮欓懠鍨涘亾閸喒鏀介柨娑樺娴犙呯磼椤曞懎鐏︾€殿噮鍋婇幃鈺冪磼濡攱瀚奸梻鍌欑贰閸嬪棝宕戝☉銏″殣妞ゆ牗绋掑▍鐘炽亜閺傛娼熷ù婊勭矋閵囧嫰骞樼捄杞版勃闂佺ǹ顑冮崕鎶藉焵椤掑喚娼愭繛鍙夌矒楠炲﹪骞樼拠鑼弨婵犮垼娉涜墝闁哄閰i弻鐔兼焽閿曗偓閺嬫稓绱掗幓鎺撳仴婵﹤顭峰畷鎺戔枎閹存繂顬夐梻浣筋嚃閸犳牠鎮ラ悡搴f殾闁圭増婢橀崡鎶芥煟韫囨凹鍤欑紓宥咃躬楠炲啫饪伴崼鐔风檮婵犮垼娉涢惌鍫ュ船閻㈠憡鈷戦悹鍥ㄥ絻閸よ京绱撳鍛棦鐎规洑鍗冲浠嬵敃閵堝嫮鐟濋梻浣告惈鐞氼偊宕曢弻銉﹀亗婵炲棗绶疯ぐ鎺撳亗閹艰揪绲鹃幉鐓庘攽閻愭潙姣嗛柛銉e妿閸橀潧顪冮妶鍡橆梿鐎规洜鏁哥划锝夊籍閳ь剟骞堥妸锔剧瘈闁告侗鍣禒鈺呮⒑閸涘﹦澧柣妤冨Т椤曪綁骞橀钘変簻闂佸憡绺块崕杈╁緤閸喒鏀介柨娑樺娴滃ジ鏌涙繝鍐ㄧ伌鐎规洜顢婇妵鎰板箳閹惧瓨鐝栨俊鐐€曠换鎰版偋閸曨垰鐒垫い鎴f硶椤︼箓鏌嶇拠鏌ュ弰妤犵偞锚閻g兘宕堕懜鏁屟冣攽閿涘嫬浜奸柛濠冪墵閹兾旈崘銊︾€抽悗骞垮劚椤︿即宕愰崹顐犱簻闁瑰搫妫楁禍楣冩⒑鐎圭媭娼愰柛銊ユ健楠炲啫鈻庨幘宕囩厬婵犮垼鍩栬摫闁挎稐绶氬缁樻媴鐟欏嫬浠╅梺鍛婃煥闁帮絽鐣锋导鏉戝唨鐟滄粓宕甸弴鐐╂斀闁绘ê纾。鏌ユ煛閸涱喗鍊愰柡灞诲姂閹倝宕掑☉姗嗕紦 | More...
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗霉閿濆牊顏犵紒鈧繝鍌楁斀闁绘ɑ褰冮埀顒€顕槐鎾愁潩鏉堛劌鏋戦梺鍝勫暙閻楀嫰鍩€椤戣法绐旂€殿喕绮欓、姗€鎮欓懠鍨涘亾閸喒鏀介柨娑樺娴犙呯磼椤曞懎鐏︾€殿噮鍋婇幃鈺冪磼濡攱瀚奸梻鍌欑贰閸嬪棝宕戝☉銏″殣妞ゆ牗绋掑▍鐘炽亜閺傛娼熷ù婊勭矋閵囧嫰骞樼捄杞版勃闂佺ǹ顑冮崕鎶藉焵椤掑喚娼愭繛鍙夌矒楠炲﹪骞樼拠鑼弨婵犮垼娉涜墝闁哄閰i弻鐔兼焽閿曗偓閺嬫稓绱掗幓鎺撳仴婵﹤顭峰畷鎺戔枎閹存繂顬夐梻浣筋嚃閸犳牠鎮ラ悡搴f殾闁圭増婢橀崡鎶芥煟韫囨凹鍤欑紓宥咃躬楠炲啫饪伴崼鐔风檮婵犮垼娉涢惌鍫ュ船閻㈠憡鈷戦悹鍥ㄥ絻閸よ京绱撳鍛棦鐎规洑鍗冲浠嬵敃閵堝嫮鐟濋梻浣告惈鐞氼偊宕曢弻銉﹀亗婵炲棗绶疯ぐ鎺撳亗閹艰揪绲鹃幉鐓庘攽閻愭潙姣嗛柛銉e妿閸橀潧顪冮妶鍡橆梿鐎规洜鏁哥划锝夊籍閳ь剟骞堥妸锔剧瘈闁告侗鍣禒鈺呮⒑閸涘﹦澧柣妤冨Т椤曪綁骞橀钘変簻闂佸憡绺块崕杈╁緤閸喒鏀介柨娑樺娴滃ジ鏌涙繝鍐ㄧ伌鐎规洜顢婇妵鎰板箳閹惧瓨鐝栨俊鐐€曠换鎰版偋閸曨垰鐒垫い鎴f硶椤︼箓鏌嶇拠鏌ュ弰妤犵偞锚閻g兘宕堕懜鏁屟冣攽閿涘嫬浜奸柛濠冪墵楠炴劖銈i崘銊х崶闁瑰吋鐣崝宥夊磻閻旇褰掓偂鎼达絾鎲奸梺鎶芥敱閸ㄥ潡寮诲☉妯锋婵鐗婇弫楣冩煟鎼达紕浠涢柣鐔叉櫊瀵顓奸崼顐n€囬梻浣告啞閹搁箖宕版惔顭戞晪闁挎繂妫涚弧鈧┑顔斤供閸樿棄鈻嶉姀銈嗏拺閻犳亽鍔屽▍鎰版煙閸戙倖瀚�
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗銆掑锝呬壕濡ょ姷鍋涢ˇ鐢稿极閹剧粯鍋愰柛鎰紦缂冩洟姊绘担鍛婃儓婵炲眰鍔嶉幈銊︻槹鎼达絿鐒兼繝鐢靛Т閸婄敻寮ㄦ禒瀣厽婵☆垰鎼痪褔鏌熼崗鐓庡闁哄本绋撴禒锔炬嫚閹绘帩娼庨梻浣告惈閺堫剙煤閻旈鏆﹂柣鎾崇岸閺€浠嬫煙闁箑甯ㄧ憸鏂款潖閾忓湱鐭欐繛鍡樺劤閸擃參姊洪崨濠冪叆闁活厼鍊搁敃銏$瑹閳ь剙顫忓ú顏勭閹艰揪绲块悾鐢告⒑閻熸澘鏆遍梺甯到椤曪綁骞庨懞銉ヤ簻闂佺ǹ绻楅崑鎰板储娴犲鈷戦柛婵嗗閳ь剙婀遍埀顒傜懗閸パ冩優闂佹悶鍎洪崜姘舵偂濞嗘劑浜滈柡鍐e亾妞ゆ垶鐟ュ玻鍧楀箛閻楀牏鍘甸悗鐟板婢ф宕甸崶顒佺厵妞ゆ梹鍎抽崢瀛橆殽閻愯尙效妞ゃ垺宀稿畷銊╊敊瑜忛崑娑㈠煘閹达附鏅柛鏇ㄥ亗閺夘參姊虹粙鍖℃敾闁绘濞€閻涱噣骞囬鐘电槇濠殿喗锕╅崜娑㈡偩濞差亝鈷戠紒瀣濠€鐗堟叏濡ǹ濮傜€殿喗濞婇弫鍐磼濞戞艾寮伴梻濠庡亜濞诧箓宕欓悷鎼細闁规壆澧楅悡鏇㈢叓閸ャ劍鈷掗柣顓熷浮閺岋紕浠﹂崜褉妲堝Δ妤婁簷閸楁娊宕洪埀顒併亜閹烘垵鈧鎯岄崱妞尖偓鎺戭潩閿濆懍澹曢柣搴㈩問閸n噣宕戞繝鍥╁祦閹兼番鍔嶉崵宥夋煏婢诡垰鍟粻娲⒒閸屾瑨鍏岀紒顕呭灦閺佸鎮楀▓鍨灈闁绘牕銈搁悰顕€寮介鐐电杸濡炪倖甯掗ˇ閬嶅船閻㈠憡鍋℃繝濠傚暟閻忛亶鏌涢幒鎾崇瑨闁宠閰i獮姗€鎼归锛版岸姊绘笟鈧ḿ褏鎹㈤崼銉ョ9闁哄稁鍘奸悿楣冩煙闂傚鍔嶉柣鎾卞劦閺岋綁寮撮悙娴嬪亾閸︻厸鍋撳鐐
闂傚倸鍊搁崐鎼佸磹閹间礁纾瑰瀣捣閻棗霉閿濆牊顏犵紒鈧繝鍌楁斀闁绘ɑ褰冮埀顒€顕槐鎾愁潩鏉堛劌鏋戦梺鍝勫暙閻楀嫰鍩€椤戣法绐旂€殿喕绮欓、姗€鎮欓懠鍨涘亾閸喒鏀介柨娑樺娴犙呯磼椤曞懎鐏︾€殿噮鍋婇幃鈺冪磼濡攱瀚奸梻鍌欑贰閸嬪棝宕戝☉銏″殣妞ゆ牗绋掑▍鐘炽亜閺傛娼熷ù婊勭矋閵囧嫰骞樼捄杞版勃闂佺ǹ顑冮崕鎶藉焵椤掑喚娼愭繛鍙夌矒楠炲﹪骞樼拠鑼弨婵犮垼娉涜墝闁哄閰i弻鐔兼焽閿曗偓閺嬫稓绱掗幓鎺撳仴婵﹤顭峰畷鎺戔枎閹存繂顬夐梻浣筋嚃閸犳牠鎮ラ悡搴f殾闁圭増婢橀崡鎶芥煟韫囨凹鍤欑紓宥咃躬楠炲啫饪伴崼鐔风檮婵犮垼娉涢惌鍫ュ船閻㈠憡鈷戦悹鍥ㄥ絻閸よ京绱撳鍛棦鐎规洑鍗冲浠嬵敃閵堝嫮鐟濋梻浣告惈鐞氼偊宕曢弻銉﹀亗婵炲棗绶疯ぐ鎺撳亗閹艰揪绲鹃幉鐓庘攽閻愭潙姣嗛柛銉e妿閸橀潧顪冮妶鍡橆梿鐎规洜鏁哥划锝夊籍閳ь剟骞堥妸锔剧瘈闁告侗鍣禒鈺呮⒑閸涘﹦澧柣妤冨Т椤曪綁骞橀钘変簻闂佸憡绺块崕杈╁緤閸喒鏀介柨娑樺娴滃ジ鏌涙繝鍐ㄧ伌鐎规洜顢婇妵鎰板箳閹惧瓨鐝栨俊鐐€曠换鎰版偋閸曨垰鐒垫い鎴f硶椤︼箓鏌嶇拠鏌ュ弰妤犵偞锚閻g兘宕堕懜鏁屟冣攽閿涘嫬浜奸柛濠冪墱閺侇噣骞掑Δ鈧壕褰掓煕椤垵娅橀柣搴ゅ煐閵囧嫰寮捄銊︾檨闂佽 鍋撳ù鐘差儏缁犳娊鏌熼幆鐗堫棄缁炬儳缍婇弻锟犲炊閳轰絿娑㈡煕鐎n偅灏い顐g箞椤㈡鍩€椤掆偓鍗卞┑鐘崇閹虫岸鏌i幇顔煎妺闁绘挶鍎甸弻锝夊即閻愭祴鍋撻崷顓涘亾濮樼偓瀚�
闂傚倸鍊搁崐鎼佸磹瀹勬噴褰掑炊椤掑鏅悷婊冪箻楠炴垿濮€閵堝懐鐤€濡炪倖妫佸Λ鍕償婵犲洦鈷戠憸鐗堝笒娴滀即鏌涢悩鍐叉诞鐎规洘鍨块獮姗€骞囨担鐟板厞婵$偑鍊栭崝鎴﹀垂閸︻厾鐭堟い鏇楀亾婵﹥妞藉Λ鍐ㄢ槈濞嗘ɑ顥i梻浣呵归敃銈夆€﹂悜鐣屽祦闁硅揪绠戠粈瀣亜閹烘垵鈧骞婂┑鍡╂富闁靛牆妫涙晶顒傜棯閺夎法孝闁宠绉电换婵嬪炊閵娿垺瀚藉┑鐐存尰閸╁啴宕戦幘瀵哥濞达絽鍟垮ú锕傚疾椤掑嫮鍙撻柛銉e妿閳藉鏌i幒鎴犱粵闁靛洤瀚伴獮鎺楀箣濠垫劒鎮i梻浣芥閸熶即宕伴弽顓炶摕闁哄洢鍨归柋鍥ㄧ節閸偄濮堥弫鍫ユ⒒娴e懙褰掝敄閸愵喖绀夌€广儱顦闂佸憡娲﹂崹浼村礃閳ь剟姊洪棃娑掑悍濠碘€虫搐閳绘捇濡堕崱娆戠槇闂佸啿鐨濋崑鎾绘煕閺囥劌澧版い锔垮嵆濮婃椽宕崟顓犲姽缂傚倸绉崇欢姘舵偘椤斿槈鐔煎礂閻撳孩鐎梻浣告啞濞诧箓宕㈣ぐ鎺戠劦妞ゆ巻鍋撻柨鏇ㄤ簻椤繐煤椤忓懎浠梺鍝勵槹鐎笛傜昂濠碉紕鍋戦崐鏍垂閻㈡潌鍥偨缁嬭銉ッ归敐鍛棌婵炵鍔戦弻宥堫檨闁告挾鍠栭悰顕€宕橀妸銏犵墯闂佸壊鍋呯换鍌炴嚀閸喒鏀芥い鏃傜摂濞堟梹淇婇锝庢疁鐎殿噮鍋夐妵鎰板箳閹绢垱瀚藉┑鐐舵彧缂嶁偓婵☆偄瀚板畷銉ㄣ亹閹烘挾鍘遍梺缁樓圭亸娆掑€存繝鐢靛仜濡酣宕归懞銉ょ箚闁兼悂娼х欢鐐测攽閻樻彃顏撮柛鐐垫暬濮婄粯鎷呴懞銉с€婇梺闈╃秶缁犳捇鐛箛娑欐櫢闁跨噦鎷�