哪吒板体验记之三 —— 点灯之旅(附代码)



  • 上篇我们留了一个课后作业,那么在今天开讲之前,还是应该先解答下上次留下的问题:D1的功耗会有多大?散热片是不是必须的?
    首先来看下D1的功耗问题,一般是根据手册上核心电压和电流消耗、GPIO电压和电流消耗等做个极限评估即可知道一个芯片的最大功耗。但是实际上D1的核心设计应该是1.5GHz的主频,目前给到大家手上内测的版本只有1GHz的主频,因此在当前手册上关于核心电流上标注为“TBD”,意为待补充。只有GPIO电流和电压给出了详细信息,目前粗算3.3V*(78+48+138+108+42+114)mA = 1.7424W,如果说随意一点估计核心电流最大消耗为500mA的话,则CPU核心功耗为1.0V*500mA = 0.5W,保守估计D1的最大功耗应该是2.5W左右的。
    芯片工作时的结温由下式计算:
    T_J max =T_A max+ (P_D max × θ_JA )
    目前手册上关于最大工作结温T_J max、以及空气热阻θ_JA均还是处于“TBD”状态,无法详细得知,根据一般BGA封装在静止空气状态下的热阻系数约20~35估算,大概在环温T_A max = 25℃时,可估算极限状态下T_J max = 75℃~112.5℃ ,一般芯片允许工作的T_J max 约为90℃~125℃左右。所以如果D1的散热设计的好的话,是不需要散热片的,但是如果设计的一般则还是需要加上散热片稳妥一点,这个具体还是需要等到正式版本(1.5GHz出货时)的芯片手册会说明。既然我们是内测版,为了不掉坑加上散热片比较保险。
    下面开始进入今天的正题了,如何来点灯。刚上电的时候,我就非常好奇,为何只有Power指示灯,没有系统运行灯?但是仔细凑上去看了下,在Power指示灯旁边就是一个RGB灯珠。可是为何灯不闪呢?一般我们习惯性的会加入一个系统运行指示灯,在系统开机完成后开始一闪一闪的运行着,一旦系统出现故障,一般这个灯就会变成常亮、常灭或者闪烁不正常,方便用户第一时间知悉系统是否工作正常。
    回到正题,既然有灯那么就必然可以点亮,除非全志的硬件工程师打了个旽,漏接了控制灯的IO,这个概率是微乎其微的,毕竟大公司不会允许这种低级问题的发生。通过查看原理图,确实看到了一个型号为WS2812C的器件接了一个名为LEDC的信号,这里我也无法确定是不是就是LED,毕竟板子上标的是“LED”,而原理图上标的是U13。
    f8311d32-538c-462e-a950-034a30447e96-image.png

    那么我便将WS2812C-2020放到百度搜索了一下,果然找到信息。它是东莞一个叫world-semi的公司生产的LED,顺着官网去下载了它的手册。
    c9b7b17c-e80d-4747-9b7f-72487d5b4675-image.png

    不过这LED的资料一看就整个人都变得不开心了,这个LED可不简单,不是普通的LED呀,它可是支持256个亮度等级且可以显示16777216种颜色的高端货呀。瞬间感觉这个灯不好点了,头都大了。说白了这个灯不是一般的灯,它是户外彩色广告屏上使用的东西。
    我们来简单看下它的控制逻辑,使用PWM控制,需要不同的高低电平时隙间隔来编码发送0和1,说白了就是普通的高低电平控制是行不通的。
    集成控制LED典型应用电路:
    5b60ff14-c985-4e91-89df-e866f0fe228f-image.png

    控制数据格式:
    ea9fb98e-337a-4519-bbc6-5fd2c3498284-image.png

    编码的格式:
    1b697451-2a19-4bab-98d6-692ad6a69951-image.png

    编码的时隙要求:
    f4857142-4e4f-4ca7-91d4-86658eed875e-image.png

    所以这个要是从零开始做驱动的话,一般是需要示波器的了。那怎么办呢?难道说就束手无策了?不会的,既然板子已经做好了板级的BSP包,那么应该是做好了驱动的,只要这个灯接到了IO上就一定有驱动(就算现在没有,未来的某天也总会更新进来的)。这里还是要回到原理图继续找线索,根据信号名LEDC,可以查到这个控制信号是连接到了PC0脚,而PC0脚上还有个信号复用类型“LEDC-DO”,且在搜索“LEDC”这个信号的过程中,好几个GPIO都出现了这个信号复用类型“LEDC-DO”,那么这个信息表明很可能D1处理器内部已经集成了的一个功能单元“LEDC”。
    6bcb6cd4-ceca-4c36-8bf6-01136821df2a-image.png

    于是继续回到D1的芯片手册,不过这次需要查找的是LEDC这个关键名词。果然在手册里提及了这个神秘且神奇的LEDC控制器部分:
    6471b2e0-40cb-4199-9bfc-825f6b939bcc-image.png

    故事既然已经讲到了这里,我也就不再继续跟大家卖关子了。我就直接教大家如何点灯吧。这个灯的控制是D1芯片已经集成了的控制器,所以驱动是已经完成的了。我们只需要找到对应这个LED的驱动文件就好了(记住,Linux下一切皆文件,这个概念需要大家用心理解)。
    关于这个LED的驱动文件它所在的路径为:/sys/class/leds/ 。因为这个LED支持Red/Green/Blue三种颜色,所以进一步的对三种颜色做了区分。比如红色对应的驱动文件路径为/sys/class/leds/sunxi_led0r/,其下一共有8个文件:
    75c7533c-6c6b-48cf-91e4-f40115e12d77-image.png

    关于具体的8个文件的使用说明需要看全志LEDC部分的驱动说明手册,因为全志目前还没有开放出来,所以我无法确切知道这些驱动文件该如何使用。但是我看到了brightness这个文件,根据一般的经验,既然支持256个亮度等级,那么我可以直接尝试往这个文件写入一个合理的亮度值,应该就能将点灯的任务顺利完成了。
    这里我直接尝试输入了一下命令:

    echo 255 > /sys/class/leds/sunxi_led0r/brightness
    

    回车键一敲完,果然就亮瞎了我的24K钛合金的狗眼。好吧,我得关掉这个两眼的光芒,于是我又输入了命令:

    echo 0 > /sys/class/leds/sunxi_led0r/brightness
    

    灯顺利的熄灭了,也就是说点灯操作成功了!!!
    29986faf-94b5-4fb4-bee0-ae0277c9c718-image.png

    既然事情已经发展到了这里,我也就再用shell写了一段依次点三种颜色LED的命令:

    #!/bin/bash
    
    i=1
    until [ "$i" == "0" ]
    do
    echo 20 > /sys/class/leds/sunxi_led0r/brightness
    sleep 0.5s
    
    echo 0 > /sys/class/leds/sunxi_led0r/brightness
    sleep 1.5s
    
    echo 20 > /sys/class/leds/sunxi_led0g/brightness
    sleep 0.5s
    
    echo 0 > /sys/class/leds/sunxi_led0g/brightness
    sleep 1.5s
    
    echo 20 > /sys/class/leds/sunxi_led0b/brightness
    sleep 0.5s
    
    echo 0 > /sys/class/leds/sunxi_led0b/brightness
    sleep 1.5s
    done
    

    这里的话建议大家直接将其新建一个shell脚本文件保存,方便随时启动,而不需要每次重复输入命令。当然有兴趣的朋友也可以采取C语言编程用户空间模式,直接编译一个binary文件去执行。
    我建立了一个led_beat.sh的文件,放在github:https://github.com/manwjh/d1_demo/blob/main/led_play/led_beat.sh
    感兴趣的也可以直接下载下来运行,好了本次的点灯之旅到此就算结束了,希望大家能一起多多交流和探讨D1的更多功能使用方法。



  • This post is deleted!


  • This post is deleted!

Log in to reply