“扩展板蜂鸣器驱动移植”的版本间的差异

来自华清远见研发中心
跳转至: 导航搜索
(创建页面,内容为“==实验原理== ==实验平台== ==实验步骤==”)
 
实验步骤
 
(未显示同一用户的2个中间版本)
第1行: 第1行:
 
==实验原理==
 
==实验原理==
 +
打开扩展板原理图对照扩展板可以看到扩展板有1个蜂鸣器SP1,如下图:
 +
 +
<center>[[Image:59-1-1.png|640px]]</center><br>
 +
 +
由上图可见通过TIM4_CH1电平改变控制电路的通断从而驱动蜂鸣器。
 +
 +
<center>[[Image:59-1-1.png|640px]]</center>
 +
 +
<center>扩展板与底板接口对照图</center>
 +
查看原理图可知TIM4_CH1对应PB6,查看芯片手册可知PB6可以作为PWM TIMER4的通道1使用,本文实现如何通过PWM驱动蜂鸣器:
 +
{|align="center" border=1
 +
|-
 +
! 原理图网络编号 !! 对应管脚 !! 管脚功能 !! 管脚功能码
 +
|-
 +
| TIM4_CH1
 +
| PB6
 +
| TIM4_CH1
 +
| AF2
 +
|}
 +
 
==实验平台==
 
==实验平台==
 +
华清远见开发环境,FS-MP1A平台
 +
 
==实验步骤==
 
==实验步骤==
 +
<ol>
 +
<li>导入交叉编译工具链</li>
 +
linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
 +
<li>内核配置</li>
 +
 +
内核中为pwm驱动蜂鸣器提供了标准的驱动,只要在内核中配置对应选项即可,驱动路径为:
 +
drivers/input/misc/pwm-beeper.c
 +
执行make menuconfig配置内核对应选项
 +
 +
<pre>
 +
linux@ubuntu:$ make menuconfig
 +
Device Drivers  --->
 +
Input device support  --->
 +
[*]  Miscellaneous devices  --->
 +
<*>  PWM beeper support
 +
</pre>
 +
 +
<li>修改设备树</li>
 +
参考linux内核文档:
 +
 +
<pre>
 +
Documentation/devicetree/bindings/pwm/pwm-stm32.txt
 +
Documentation/devicetree/bindings/input/pwm-beeper.txt
 +
</pre>
 +
修改设备树文件:
 +
arch/arm/boot/dts/stm32mp157a-fsmp1a-extended.dts
 +
 +
由于timers4在stm32mp151.dtsi中已完成定义,这里需要在原有基础添加与硬件对应的相关信息,在文件stm32mp157a-fsmp1a-extended.dts末尾集成并添加timers4相关内容:
 +
<pre>
 +
&timers4 {
 +
/* spare dmas for other usage */
 +
/delete-property/dmas;
 +
/delete-property/dma-names;
 +
status = "okay";
 +
pwm4: pwm {
 +
pinctrl-0 = <&pwm4_pins_c>;
 +
pinctrl-1 = <&pwm4_sleep_pins_c>;
 +
pinctrl-names = "default", "sleep";
 +
#pwm-cells = <2>;
 +
status = "okay";
 +
};
 +
timer@3 {
 +
status = "disabled";
 +
};
 +
};
 +
 +
</pre>
 +
 +
仿照设备树对于pwm管脚的配置添加timers4 pwm输出管脚配置,在stm32mp157a-fsmp1a-extended.dts末尾添加如下内容:
 +
<pre>
 +
&pinctrl {
 +
pwm4_pins_c: pwm4-0 {
 +
pins {
 +
pinmux = <STM32_PINMUX('B', 6, AF2)>; /* TIM4_CH1 */
 +
bias-pull-down;
 +
drive-push-pull;
 +
slew-rate = <0>;
 +
};
 +
};
 +
 +
pwm4_sleep_pins_c: pwm4-sleep-0 {
 +
pins {
 +
pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* TIM4_CH1 */
 +
};
 +
};
 +
};
 +
</pre>
 +
在根节点中添加蜂鸣器对应节点,红色字体部分为添加内容:
 +
 +
<div style="background-color:#F8F8F8;border:1px solid #E5E5E5;font-family: monospace,Courier;">
 +
/ {
 +
:  model = "HQYJ STM32MP157 FSMP1A Discovery Board";
 +
:  compatible = "st,stm32mp157", "st,stm32mp157a-fsmp1a-extended";
 +
: ……
 +
<font color="#F00">
 +
: beeper {
 +
:: compatible = "pwm-beeper";
 +
:: pwms = <&pwm4 0 4000000>;
 +
: };
 +
</font>
 +
};
 +
</div>
 +
 +
<li>重新编译内核和设备树文件</li>
 +
linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
 +
 +
<li>更新系统内核和设备树</li>
 +
 +
<li>测试</li>
 +
系统启动后可以查看目录/dev/input
 +
 +
<pre>
 +
root@fsmp1a:~# ls /dev/input/
 +
by-path  event0  event1
 +
</pre>
 +
如果系统中有多个input设备,这里可能会有很对eventx,确定哪个event文件是我们的设备文件,可以通过查看/dev/input/by-path或查看dmesg系统启动信息确认:<br>
 +
 +
查看by-path目录下文件
 +
 +
<pre>
 +
root@fsmp1a:# ls /dev/input/by-path/ -l
 +
total 0
 +
lrwxrwxrwx 1 root root 9 May 30 08:43 platform-40013000.i2c-event -> ../event1
 +
lrwxrwxrwx 1 root root 9 May 30 08:43 platform-beeper-event -> ../event0
 +
</pre>
 +
由显示信息可以确认event0是蜂鸣器的设备文件<br>
 +
编写测试程序测试:<br>
 +
编写测试程序或参考:“光盘资料:华清远见-FS-MP1A开发资料\02-程序源码\06-资源扩展板测试程序\01-beeper_test”<br>
 +
pwm-beeper.c<br>
 +
 +
<pre>
 +
#include <stdint.h>
 +
#include <string.h>
 +
#include <fcntl.h>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <linux/input.h>
 +
#include <unistd.h>
 +
 +
#define ESC_KEY  0x1b
 +
 +
int main(int argc, char *argv[])
 +
{
 +
    int fd, version, ret;
 +
    struct input_event event;
 +
    struct timeval time;
 +
 +
    if ((fd = open(argv[1], O_RDWR)) < 0) {
 +
        perror("beep test");
 +
        return 1;
 +
    }
 +
 +
    event.type = EV_SND;
 +
    event.code = SND_TONE;
 +
    event.value = 1000;
 +
    time.tv_sec = 1;
 +
    time.tv_usec = 0;
 +
    event.time = time;
 +
 +
    while( 1 )
 +
    {
 +
        int key;
 +
 +
        ret = write(fd, &event, sizeof(struct input_event));
 +
 +
        printf( "Freq = %d\n", event.value);
 +
 +
        key = getchar();
 +
 +
        switch(key) {
 +
        case '+':
 +
            if( event.value < 20000)
 +
                event.value += 10;
 +
            break;
 +
 +
        case '-':
 +
            if( event.value > 11 )
 +
                event.value -= 10 ;
 +
            break;
 +
 +
        case ESC_KEY:
 +
        case EOF: 
 +
            event.code = SND_BELL;
 +
            event.value = 0000;   
 +
            ret = write(fd, &event, sizeof(struct input_event));
 +
            close(fd);
 +
            return 1;
 +
        default:
 +
            break;
 +
        }
 +
    }
 +
}
 +
 +
</pre>
 +
交叉编译测试程序并将编译好的测试程序下载到板子上,执行程序如下:
 +
<pre>
 +
root@fsmp1a:# ./beeper_test /dev/input/event0
 +
Freq = 1000
 +
</pre>
 +
通过输入‘+’或者‘-’调整频率,输入esc退出程序
 +
<pre>
 +
root@fsmp1a: # ./beeper_test /dev/input/event0
 +
Freq = 1000
 +
+
 +
Freq = 1010
 +
-
 +
Freq = 1000
 +
^[
 +
</pre>
 +
调整频率后听不同频率蜂鸣器发出声音的不同。
 +
</ol>

2021年3月23日 (二) 13:38的最新版本

实验原理

打开扩展板原理图对照扩展板可以看到扩展板有1个蜂鸣器SP1,如下图:

59-1-1.png

由上图可见通过TIM4_CH1电平改变控制电路的通断从而驱动蜂鸣器。

59-1-1.png
扩展板与底板接口对照图

查看原理图可知TIM4_CH1对应PB6,查看芯片手册可知PB6可以作为PWM TIMER4的通道1使用,本文实现如何通过PWM驱动蜂鸣器:

原理图网络编号 对应管脚 管脚功能 管脚功能码
TIM4_CH1 PB6 TIM4_CH1 AF2

实验平台

华清远见开发环境,FS-MP1A平台

实验步骤

  1. 导入交叉编译工具链
  2. linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
    
  3. 内核配置
  4. 内核中为pwm驱动蜂鸣器提供了标准的驱动,只要在内核中配置对应选项即可,驱动路径为:

    drivers/input/misc/pwm-beeper.c
    

    执行make menuconfig配置内核对应选项

    linux@ubuntu:$ make menuconfig 
    Device Drivers  --->
    	Input device support  --->
    		[*]   Miscellaneous devices  --->
    			<*>   PWM beeper support
    
  5. 修改设备树
  6. 参考linux内核文档:

    Documentation/devicetree/bindings/pwm/pwm-stm32.txt
    Documentation/devicetree/bindings/input/pwm-beeper.txt
    

    修改设备树文件:

    arch/arm/boot/dts/stm32mp157a-fsmp1a-extended.dts
    

    由于timers4在stm32mp151.dtsi中已完成定义,这里需要在原有基础添加与硬件对应的相关信息,在文件stm32mp157a-fsmp1a-extended.dts末尾集成并添加timers4相关内容:

    &timers4 {
    	/* spare dmas for other usage */
    	/delete-property/dmas;
    	/delete-property/dma-names;
    	status = "okay";
    	pwm4: pwm {
    		pinctrl-0 = <&pwm4_pins_c>;
    		pinctrl-1 = <&pwm4_sleep_pins_c>;
    		pinctrl-names = "default", "sleep";
    		#pwm-cells = <2>;
    		status = "okay";
    	};
    	timer@3 {
    		status = "disabled";
    	};
    };
    
    

    仿照设备树对于pwm管脚的配置添加timers4 pwm输出管脚配置,在stm32mp157a-fsmp1a-extended.dts末尾添加如下内容:

    &pinctrl {
    	pwm4_pins_c: pwm4-0 {
    		pins {
    			pinmux = <STM32_PINMUX('B', 6, AF2)>; /* TIM4_CH1 */
    			bias-pull-down;
    			drive-push-pull;
    			slew-rate = <0>;
    		};
    	};
    
    	pwm4_sleep_pins_c: pwm4-sleep-0 {
    		pins {
    			pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* TIM4_CH1 */
    		};
    	};
    };
    

    在根节点中添加蜂鸣器对应节点,红色字体部分为添加内容:

    / {

    model = "HQYJ STM32MP157 FSMP1A Discovery Board";
    compatible = "st,stm32mp157", "st,stm32mp157a-fsmp1a-extended";
    ……

    beeper {
    compatible = "pwm-beeper";
    pwms = <&pwm4 0 4000000>;
    };

    };

  7. 重新编译内核和设备树文件
  8. linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
    
  9. 更新系统内核和设备树
  10. 测试
  11. 系统启动后可以查看目录/dev/input

    root@fsmp1a:~# ls /dev/input/
    by-path  event0  event1
    

    如果系统中有多个input设备,这里可能会有很对eventx,确定哪个event文件是我们的设备文件,可以通过查看/dev/input/by-path或查看dmesg系统启动信息确认:

    查看by-path目录下文件

    root@fsmp1a:# ls /dev/input/by-path/ -l
    total 0
    lrwxrwxrwx 1 root root 9 May 30 08:43 platform-40013000.i2c-event -> ../event1
    lrwxrwxrwx 1 root root 9 May 30 08:43 platform-beeper-event -> ../event0
    

    由显示信息可以确认event0是蜂鸣器的设备文件
    编写测试程序测试:
    编写测试程序或参考:“光盘资料:华清远见-FS-MP1A开发资料\02-程序源码\06-资源扩展板测试程序\01-beeper_test”
    pwm-beeper.c

    #include <stdint.h>
    #include <string.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <linux/input.h>
    #include <unistd.h>
    
    #define ESC_KEY  0x1b
    
    int main(int argc, char *argv[])
    {
        int fd, version, ret;
        struct input_event event;
        struct timeval time;
    
        if ((fd = open(argv[1], O_RDWR)) < 0) {
            perror("beep test");
            return 1;
        }
    
        event.type = EV_SND;
        event.code = SND_TONE;
        event.value = 1000;
        time.tv_sec = 1;
        time.tv_usec = 0;
        event.time = time;
    
        while( 1 )
        {
            int key;
    
            ret = write(fd, &event, sizeof(struct input_event));
    
            printf( "Freq = %d\n", event.value);
    
            key = getchar();
    
            switch(key) {
            case '+':
                if( event.value < 20000)
                    event.value += 10;
                break;
    
            case '-':
                if( event.value > 11 )
                    event.value -= 10 ;
                break;
    
            case ESC_KEY:
            case EOF:   
                event.code = SND_BELL;
                event.value = 0000;     
                ret = write(fd, &event, sizeof(struct input_event));
                close(fd);
                return 1;
            default:
                break;
            }
        }
    }
    
    

    交叉编译测试程序并将编译好的测试程序下载到板子上,执行程序如下:

    root@fsmp1a:# ./beeper_test /dev/input/event0
    Freq = 1000
    

    通过输入‘+’或者‘-’调整频率,输入esc退出程序

    root@fsmp1a: # ./beeper_test /dev/input/event0
    Freq = 1000
    +
    Freq = 1010
    -
    Freq = 1000
    ^[
    

    调整频率后听不同频率蜂鸣器发出声音的不同。