驱动里的 引脚 PC1(nezha_tina_linux)
for (i= 0; i < 100000; i++) {
gpio_direction_output(DHT11_1_PIN, x);
x = ~x;
}
Vmax约为1.63v,百元示波器极限10us了,
问:如何计算GPIO稳定需要的时间以及gpio_direction_output(单条命令耗时);
有设备的大佬,如果可以的话,帮忙测一下来张图呗,提前跪谢~
驱动里的 引脚 PC1(nezha_tina_linux)
for (i= 0; i < 100000; i++) {
gpio_direction_output(DHT11_1_PIN, x);
x = ~x;
}
Vmax约为1.63v,百元示波器极限10us了,
问:如何计算GPIO稳定需要的时间以及gpio_direction_output(单条命令耗时);
有设备的大佬,如果可以的话,帮忙测一下来张图呗,提前跪谢~
@yuzukitsuru 在 【tina_nezha】【求助】pwm无法启用/或寻其他途径控制舵机 中说:
pwm应该不是这样绑定pin的,具体看一下pwm的文档
还有个问题,求大佬指条明路,之前询问控制DHT11,说道使用告诉I2C外设来实现。大佬,具体点,哪款芯片,或者哪一类呢
@yuzukitsuru
我看了那个文档,不过估计是没有完全理解。
类似这种,默认定义了0~7号pwm
然后在板级dts里只配置了pwm0 pwm2 pwm7
其他的写都没写。看样子是要自己添加。但是没有看到介绍如何添加。
然后,提供的内核api需要 pwm号, 返回的错误信息在前面(和/sys/class/pwm下的信息一样)
@yuzukitsuru 好像是的。pwm0、pwm2、pwm7,在board.dts里面配置了休眠和常规两种状态,然后也是默认启用的。
不过我自己添加的pwm1,也是这种情况。
刚刚用gpio_direction_output()和usleep模拟PWM。。不过只能控制舵机0°~160°左右,达不到180°。不知道为什么。。还在摸索
我尝试使用字符驱动和/sys/class/pwm/pwmchip0/export 启用pwm,驱动和用户层操作都是类似下面这种错误pinctrl_get failed
[ 868.035098] platform 2000c17.pwm7: pinctrl_get failed
这是/sys/class下的pwm7(pwm1也是如此)
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# ls
capture output_type power
duty_cycle period uevent
enable polarity waiting_for_supplier
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# echo 2000000 >period
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# echo 1000000 >duty_cycle
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# echo normal >polarity
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# echo 1 > enable
[ 868.035098] platform 2000c17.pwm7: pinctrl_get failed
ash: write error: No such device
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# cat capture
[ 885.724275] platform 2000c17.pwm7: pinctrl_get failed
[ 885.730046] time out is 1000
[ 894.621166] platform 2000c17.pwm7: pinctrl_get failed
[ 894.627001] sunxi_pwm_capture: pwm capture timeout !
[ 894.632728] platform 2000c17.pwm7: pinctrl_get failed
[ 894.638491] time out is 1000
[ 903.529004] platform 2000c17.pwm7: pinctrl_get failed
[ 903.534865] sunxi_pwm_capture: pwm capture timeout !
cat: read error: Operation not permitted
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7# cat /sys/kernel/debug/pwm
platform/2000c00.pwm, 8 PWM devices
pwm-0 (vdd-cpu ): requested period: 0 ns duty: 0 ns polarity: inverse
pwm-1 (sysfs ): requested period: 2000000 ns duty: 0 ns polarity: inverse
pwm-2 (lcd ): requested enabled period: 1000000 ns duty: 390625 ns polarity: normal
pwm-3 ((null) ): period: 0 ns duty: 0 ns polarity: inverse
pwm-4 ((null) ): period: 0 ns duty: 0 ns polarity: inverse
pwm-5 ((null) ): period: 0 ns duty: 0 ns polarity: inverse
pwm-6 ((null) ): period: 0 ns duty: 0 ns polarity: inverse
pwm-7 (sysfs ): requested period: 2000000 ns duty: 1000000 ns polarity: normal
root@TinaLinux:/sys/devices/platform/soc@3000000/2000c00.pwm/pwm/pwmchip0/pwm7#
下面是修改过的设备树
pwm1_pin_a: pwm1@0 {
pins = "PB6";
// allwinner,muxsel = <5>;//这个地方尝试过,也是pinctrl_get failed
function = "pwm1";
drive-strength = <10>;
bias-pull-up;
};
pwm1_pin_b: pwm1@1 {
pins = "PB6";
function = "gpio_in";
};
&pwm1 {
pinctrl-names = "active", "sleep";
pinctrl-0 = <&pwm1_pin_a>;
pinctrl-1 = <&pwm1_pin_b>;
status = "okay";
};
我还把设备树中PB6相关的其他设备都“disable”了(TWI3和daudio2)(i2s2的我没找到 )结果和上面相同
allwinner,muxsel = <5>;我试着加在了pwm1_pin_a: pwm1@0 {} 里,也没效果
@yuzukitsuru 就是说这个gpio_direction_output()的响应速度不能满足dht11这类对时序要求高的传感器嘛?
方便一点的办法是使用I2C设备来传嘛
@yuzukitsuru 大佬,我再问俩问题,
像gpio_direction_output()这一类gpio操作的函数,延迟是什么级别的 能达到<5us嘛
不修改设备树的情况下,单字符驱动,不用虚拟总线,直接使gpio_request()可以达到操作dht11,ds18b20之类的要求吗
@yuzukitsuru 在 【萌新入门】如何编写一个应用程序,调用Tina Linux提供的GPIO驱动,实现某个GPIO脚的电平周期反转 中说:
@the_qiang D1是RISCV,与ARM的不太一样,没有先删了看看能不能编译过,能就没问题
编号计算:全志引脚计算器 AllwinnerPin 小工具发布
https://bbs.aw-ol.com/topic/1166/share/1
感谢大佬,是我向太复杂了,真就是你另一个标题里的PC1 = ('C'-'A')*32+1
@yuzukitsuru 在 【萌新入门】如何编写一个应用程序,调用Tina Linux提供的GPIO驱动,实现某个GPIO脚的电平周期反转 中说:
@lgkgkfg 是,在内核控制更方便些,不过一些高速操作都使用高速外设了
我也请教一下
tina SDK关于GPIO的参考文档里给出的介绍
如图,上面的这个gpio编号如何计算。例如PC1口。
另外我编译ko文件时没有这个<mach/gpio.h>(抄的V853的led驱动头文件引用)
(我很菜,别骂 )
大佬们指点下(如果可以的话,发俩demo参考学习下也好,尤其是带IO操作以及IIC设备的 ):
1.在SDK目录下 make kernel_menuconfig 里的选项如何保存并应用,直接选择save一路回车?
(百度上搜了一堆,什么cp xxxx,还有make save 都没反应)
2.想要编写驱动程序生成.KO文件,Makefile 文件如何编写(SDK目录下执行过mkernel,看了些论坛上和百度上的Makefile,尝试了未果)。
3.写的网上学来的基本驱动框架没有在 /dev/下生成节点(放在/opt/d1/tina_d1_open_v2/lichee/linux-5.4/drivers/char/下 并修改
Kconfig 追加hello_drv default y 然后SDK 下make时,就会在该目录下生成相应的ko文件,insmod后也没见节点,
make kernel_menuconfig勾选后 再make,烧录img 也没有节点 )(相关代码在页面最底下)
4.比如/opt/d1/tina_d1_open_v2/lichee/linux-5.4/drivers/ 里的i2c-dev-basexxx一类的c文件,里面的函数(如i2c_transfer();),
编写APP时如何调用?还是说只能写的驱动才能调用?
5.关于linux设备数上添加节点,SDK文档介绍说最好是在board.dts中添加,配置pin是这样嘛(也是到处参照写的)?
&pio {
........
dth_11_pin:dht_11_pin{
pins = "PC1";
function = "gpio_out";
allwinner,pull = <1>;
bias-pull-up;
};
........
}
不需要再 上面dht_11_pin 后面家@0x.....(地址)嘛?上下的差异很不解
sun20iw1p1.dtsi中
pio: pinctrl@2000000 {
.....
ledc: ledc@2008000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "allwinner,sunxi-leds";
reg = <0x0 0x02008000 0x0 0x400>;
interrupts-extended = <&plic0 36 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "ledcirq";
clocks = <&ccu CLK_LEDC>, <&ccu CLK_BUS_LEDC>;
clock-names = "clk_ledc", "clk_cpuapb";
dmas = <&dma 42>, <&dma 42>;
dma-names = "rx", "tx";
resets = <&ccu RST_BUS_LEDC>;
reset-names = "ledc_reset";
status = "disable";
};
......
}
6.哪吒板子上的iio接口在哪(看到iio下有DHT11驱动想直接用)
下面是参照官方的APP的Makefile
CTOOL := riscv64-unknown-linux-gnu-
CCL := /opt/d1/tina_d1_open_v2/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
CC := ${CCL}/bin/${CTOOL}gcc
myproject : *.c
${CC} -o myproject $^
clean :
rm myproject
相关路径给大佬参上:
whycan@ubuntu:/opt/d1/tina_d1_open_v2$ pwd
/opt/d1/tina_d1_open_v2
whycan@ubuntu:/opt/d1/tina_d1_open_v2$ find -name "linux-5*"
./out/d1-h-nezha/compile_dir/target/linux-d1-h-nezha/linux-5.4.61
./.repo/project-objects/lichee/linux-5.4.git
./.repo/projects/lichee/linux-5.4.git
./lichee/linux-5.4
./device/config/chips/d1-h/configs/nezha_min/linux-5.4
./device/config/chips/d1-h/configs/nezha/linux-5.4
./device/config/chips/d1s/configs/nezha/linux-5.4
whycan@ubuntu:/opt/d1/tina_d1_open_v2$
漫长无聊的代码以及错误信息参上:
whycan@ubuntu:/mnt/hgfs/vmout/project/hellodev$ ls
hello_drv.c Makefile
whycan@ubuntu:/mnt/hgfs/vmout/project/hellodev$ cat Makefile
KDIR =/opt/d1/tina_d1_open_v2/out/d1-h-nezha/compile_dir/target/linux-d1-h-nezha/linux-5.4.61
CTOOL := riscv64-unknown-linux-gnu-
CCL := /opt/d1/tina_d1_open_v2/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
CC := ${CCL}/bin/${CTOOL}gcc
CURRENT_PATH:=$(shell pwd)
LINUX_KERNEL:=$(shell uname -r)
KVERSION:=5.4
PWD:=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv
#myproject : *.c
# ${CC} -o myproject $^
clean :
rm myproject
obj-m += hello_drv.o
whycan@ubuntu:/mnt/hgfs/vmout/project/hellodev$ make
make -C /opt/d1/tina_d1_open_v2/out/d1-h-nezha/compile_dir/target/linux-d1-h-nezha/linux-5.4.61 M=/mnt/hgfs/vmout/project/hellodev modules CROSS_COMPILE=riscv64-unknown-linux-gnu- ARCH=riscv
make[1]: Entering directory '/opt/d1/tina_d1_open_v2/lichee/linux-5.4'
make[1]: riscv64-unknown-linux-gnu-gcc: Command not found
CC [M] /mnt/hgfs/vmout/project/hellodev/hello_drv.o
In file included from ./include/linux/list.h:9,
from ./include/linux/module.h:9,
from /mnt/hgfs/vmout/project/hellodev/hello_drv.c:1:
./include/linux/kernel.h:6:10: fatal error: stdarg.h: No such file or directory
#include <stdarg.h>
^~~~~~~~~~
compilation terminated.
scripts/Makefile.build:286: recipe for target '/mnt/hgfs/vmout/project/hellodev/hello_drv.o' failed
make[2]: *** [/mnt/hgfs/vmout/project/hellodev/hello_drv.o] Error 1
Makefile:1810: recipe for target '/mnt/hgfs/vmout/project/hellodev' failed
make[1]: *** [/mnt/hgfs/vmout/project/hellodev] Error 2
make[1]: Leaving directory '/opt/d1/tina_d1_open_v2/lichee/linux-5.4'
Makefile:15: recipe for target 'all' failed
make: *** [all] Error 2
whycan@ubuntu:/mnt/hgfs/vmout/project/hellodev$ cat hello_drv.c
//==============================================
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
static int major =0;
static int err;
static char kernel_buf [1024];
static struct class * hello_class;
#define MIN(a,b)(a < b ? a : b)
static ssize_t hello_drv_read(struct file *file, char __user *user, size_t bytesize, loff_t *this_loff_t){
int err0;
printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
err0 = copy_to_user(user,kernel_buf,MIN(1024,bytesize));
return err0;
}
static ssize_t hello_drv_write(struct file *file, const char __user *user, size_t bytesize, loff_t *this_loff_t){
int err0;
printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
err0 = copy_from_user(kernel_buf,user,MIN(1024,bytesize));
return err0;
}
static int hello_drv_open(struct inode *inode, struct file *file){
int err0;
err0 = printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
return err0;
}
static int hello_drv_close(struct inode *inode, struct file *file){
int err0;
err0 = printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
return err0;
}
static struct file_operations hello_drv ={
.owner = THIS_MODULE,
.open = hello_drv_open,
.read = hello_drv_read,
.write = hello_drv_write,
.release = hello_drv_close
};
static int __init hello_init(void){
printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
register_chrdev(0,"hello",&hello_drv);
hello_class = class_create(THIS_MODULE ,"hello_class");
err = PTR_ERR(hello_class);
if(IS_ERR (hello_class)){
unregister_chrdev(major,"hello");
return -1;
}
device_create(hello_class,NULL ,MKDEV(major ,0),NULL,"hello");
return 0;
}
static void __exit hello_exit(void){
printk("%s %s line %d \n ",__FILE__,__FUNCTION__,__LINE__);
unregister_chrdev(major,"hello");
device_destroy(hello_class,MKDEV(major,0));
class_destroy(hello_class);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XD");
//==============================================
@yuzukitsuru 在 【Tina_哪吒】在虚拟机上按流程make后部分构建失败 中说:
@the_qiang 是的,
sudo rm -rf out/ tmp/
然后make clean && make distclean
感谢大佬~
下回知道避免root了
不过我make clean && make distclean 的时候报错了
当初忘了复制一遍虚拟机了,现在在下载新的了。
@yuzukitsuru 佬,我在同目录下执行了下,还是必须root才能正常make,还是有一些构建失败,是因为我之前用root整过一遍,文件权限变了嘛。
大佬们帮我这小白看看问题在哪。
在这个虚拟机上倒是成功过,都按流程source buid..... lunch ....然后再make的
(后用make kernel_menuconfig修改过.config和cp .config /arch/riscv/config/xxxxdeconfig 后又改回原文件)。
错误信息如图
(root:make):
(直接make):
(sudo make):