zigbee_bm023模块:
默认3.3v供电为: 低电平,复位引脚 为高电平;
使用uart1:节点为ttyS1
操作节点:
3.3v供电引脚:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control
复位引脚:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control
1 查看如下图,原理图以及gpio映射表可以知道zigbee_bm023模块 使用3.3v作为供电,供电引脚为gpio24,复位引脚为:gpio25,由此可以配置st3x3x 光距感传感器 的dts
配置zigbee_bm023模块的dts
zigbee_bm023:zigbee_bm023{
compatible = "mediatek,zigbee_bm023";
status = "okay";
zigbee_3v3_en_gpio = <&pio 24 0>;
zigbee_rst_gpio = <&pio 25 0>;
};
2 编写zigbee_bm023驱动
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ZIGBEE_DEVICE_NAME "zigbee_bm023"
#define ZIGBEE_DEVNAME "zigbee_bm023_by_elink"//节点名称
static dev_t zigbee_devno;//设备号
static struct class *zigbee_class;//class类
static struct device *zigbee_device;//设备
static int zigbee_power_gpio_ctrl_status = 0;
static int zigbee_rst_gpio_ctrl_status = 0;
#define ZIGBEE_PAGE_SIZE 10
static unsigned int zigbee_3v3_en_gpio;
static unsigned int zigbee_rst_gpio;
static const struct of_device_id zigbee_bm023_match_table[] = {
{ .compatible = "mediatek,zigbee_bm023", },
{/* KEEP THIS */},
};
MODULE_DEVICE_TABLE(of, zigbee_bm023_match_table);
static ssize_t zigbee_power_gpio_control_show(struct device *dev, struct device_attribute *attr, char *buf)
{
// printk("moved in func: %s zigbee_power_gpio_ctrl_status = %d \n", __func__,zigbee_power_gpio_ctrl_status);
return snprintf(buf, ZIGBEE_PAGE_SIZE,"%d\n", zigbee_power_gpio_ctrl_status);
}
static ssize_t zigbee_power_gpio_control_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int temp;
temp = simple_strtol(buf, NULL, 10);//把字符串转为数字
zigbee_power_gpio_ctrl_status = temp;
//printk("in func: %s, zigbee_power_gpio_ctrl_status = %d", __func__, zigbee_power_gpio_ctrl_status);
// printk("in func: %s, count = %d", __func__, count);
if(zigbee_power_gpio_ctrl_status == 1) {
// printk("in func: %s, set zigbee_3v3_en_gpio output to high", __func__);
if(zigbee_3v3_en_gpio > 0)
gpio_set_value(zigbee_3v3_en_gpio, 1);
// printk("------- %s %d gpio_set_value(zigbee_3v3_en_gpio, 1) successed ------- \n", __func__,__LINE__);
} else if(zigbee_power_gpio_ctrl_status == 0){
// printk("in func: %s, set zigbee_3v3_en_gpio output to low", __func__);
if(zigbee_3v3_en_gpio > 0)
gpio_set_value(zigbee_3v3_en_gpio, 0);
// printk("------- %s %d gpio_set_value(zigbee_3v3_en_gpio, 0) successed ------- \n", __func__,__LINE__);
}else
printk("dsy invalid parameter,the zigbee_power_gpio_ctrl_status must be 1 or 0\n");
// printk("in func: %s, gpio_get_value(zigbee_3v3_en_gpio) = %d", __func__, gpio_get_value(zigbee_3v3_en_gpio));
return count;
}
static ssize_t zigbee_rst_gpio_control_show(struct device *dev, struct device_attribute *attr, char *buf)
{
// printk("moved in func: %s zigbee_rst_gpio_ctrl_status = %d \n", __func__,zigbee_rst_gpio_ctrl_status);
return snprintf(buf, ZIGBEE_PAGE_SIZE,"%d\n", zigbee_rst_gpio_ctrl_status);
}
static ssize_t zigbee_rst_gpio_control_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int temp;
temp = simple_strtol(buf, NULL, 10);//把字符串转为数字
zigbee_rst_gpio_ctrl_status = temp;
// printk("in func: %s, zigbee_rst_gpio_ctrl_status = %d", __func__, zigbee_rst_gpio_ctrl_status);
// printk("in func: %s, count = %d", __func__, count);
if(zigbee_rst_gpio_ctrl_status == 1) {
// printk("in func: %s, set zigbee_rst_gpio output to high", __func__);
if(zigbee_rst_gpio > 0)
gpio_set_value(zigbee_rst_gpio, 1);
// printk("------- %s %d gpio_set_value(zigbee_rst_gpio, 1) successed ------- \n", __func__,__LINE__);
} else if(zigbee_rst_gpio_ctrl_status == 0){
// printk("in func: %s, set zigbee_rst_gpio output to low", __func__);
if(zigbee_rst_gpio > 0)
gpio_set_value(zigbee_rst_gpio, 0);
// printk("------- %s %d gpio_set_value(zigbee_rst_gpio, 0) successed ------- \n", __func__,__LINE__);
}else
printk("dsy invalid parameter,the zigbee_rst_gpio_ctrl_status must be 1 or 0\n");
// printk("in func: %s, gpio_get_value(zigbee_rst_gpio) = %d", __func__, gpio_get_value(zigbee_rst_gpio));
return count;
}
//定义设备属性节点zigbee_power_gpio_control zigbee_rst_gpio_control,和show函数,store函数
static DEVICE_ATTR(zigbee_power_gpio_control, 0664, zigbee_power_gpio_control_show, zigbee_power_gpio_control_store);
static DEVICE_ATTR(zigbee_rst_gpio_control, 0664, zigbee_rst_gpio_control_show, zigbee_rst_gpio_control_store);
static int zigbee_gpio_ctrl_sysfs_create(struct platform_device * pdev)
{
int ret = 0;
// printk("-------dsy:elink %s %d start ------- \n", __func__,__LINE__);
//申请设备号--下面需要用的这个设备号
ret = alloc_chrdev_region(&zigbee_devno, 0, 1, ZIGBEE_DEVNAME);
if (ret) {//申请成功
printk(" %s %d alloc_chrdev_region fail: %d ~",__func__,__LINE__,ret);
//goto torch_chrdev_error; 这里应该跳到unregister函数,懒得写
} else {//申请失败
printk(" %s %d major: %d, minor: %d ~", __func__,__LINE__, MAJOR(zigbee_devno),
MINOR(zigbee_devno));
}
//在sys/class创建zigbee_class 类
zigbee_class = class_create(THIS_MODULE, ZIGBEE_DEVNAME);
if (IS_ERR(zigbee_class)) {//创建失败
printk("%s %d Unable to create class:zigbee_class\n", __func__,__LINE__);
}
//在sys/class/zigbee_class/下创建设备节点
zigbee_device =device_create(zigbee_class, NULL, zigbee_devno,
NULL, ZIGBEE_DEVNAME);
if(NULL == zigbee_device)//创建失败
printk("%s %d device_create zigbee_device fail \n", __func__,__LINE__);
// printk(" %s %d moved in function: device_create succed %s",__func__,__LINE__, __func__);
//在sys/class/zigbee_class/zigbee_class下创建属性文件led_one_control
ret = device_create_file(zigbee_device, &dev_attr_zigbee_power_gpio_control);
if (ret) {
printk("in function: %s, create fs zigbee_power_gpio_control failed", __func__);
return -1;
}
// printk("------- %s %d create fs zigbee_power_gpio_control successed ------- \n", __func__,__LINE__);
ret = device_create_file(zigbee_device, &dev_attr_zigbee_rst_gpio_control);
if (ret) {
printk("in function: %s, create fs zigbee_rst_gpio_control failed", __func__);
return -1;
}
// printk("------- %s %d create fs zigbee_rst_gpio_control successed ------- \n", __func__,__LINE__);
return ret;
}
static int zigbee_bm023_probe(struct platform_device *pdev)
{
int ret=0;
struct device_node *node = NULL;
node = of_find_compatible_node(NULL, NULL, "mediatek,zigbee_bm023");
if(!node){
printk("%s find zigbee_bm023 node failed!!\n", __func__);
return -EINVAL;
}
printk("%s findzigbee_bm023 node successed!!\n", __func__);
zigbee_3v3_en_gpio = of_get_named_gpio(node, "zigbee_3v3_en_gpio", 0);
if ((!gpio_is_valid(zigbee_3v3_en_gpio)))
return -EINVAL;
zigbee_rst_gpio = of_get_named_gpio(node, "zigbee_rst_gpio", 0);
if ((!gpio_is_valid(zigbee_rst_gpio)))
return -EINVAL;
printk("zigbee_3v3_en_gpio %d\n", zigbee_3v3_en_gpio);
printk("zigbee_rst_gpio %d\n", zigbee_rst_gpio);
ret = gpio_request_one(zigbee_3v3_en_gpio, GPIOF_OUT_INIT_LOW, "zigbee_3v3_en_gpio");
gpio_direction_output(zigbee_3v3_en_gpio, 0);
ret = gpio_request_one(zigbee_rst_gpio, GPIOF_OUT_INIT_LOW, "zigbee_rst_gpio");
gpio_direction_output(zigbee_rst_gpio, 0);
ret = zigbee_gpio_ctrl_sysfs_create(pdev);
if(ret < 0) {
printk("create sysfs failed.");
}
//printk("-------%s %d gpio_get_value(zigbee_3v3_en_gpio) = %d gpio_get_value(zigbee_rst_gpio) = %d end-----\n", __func__,__LINE__,gpio_get_value(zigbee_3v3_en_gpio),gpio_get_value(zigbee_rst_gpio));
return 0;
}
static int zigbee_bm023_remove(struct platform_device *pdev)
{
return 0;
}
static struct platform_driver zigbee_bm023_driver = {
.probe = zigbee_bm023_probe,
.remove = zigbee_bm023_remove,
.driver = {
.name = ZIGBEE_DEVICE_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(zigbee_bm023_match_table),
},
};
static int __init zigbee_bm023_init(void)
{
int err;
err = platform_driver_register(&zigbee_bm023_driver);
if(err)
{
printk(" failed to register driver\n");
return -ENODEV;
}
return err;
}
static void __exit zigbee_bm023_exit(void)
{
platform_driver_unregister(&zigbee_bm023_driver);
}
module_init(zigbee_bm023_init);
module_exit(zigbee_bm023_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Test zigbee_bm023 Driver For zigbee_bm023");
MODULE_AUTHOR(");
3 为3.3v供电引脚和复位引脚两个节点赋予相关的权限,目的是让客户有权限直接操作这2个节点
3.1 赋予666权限
\device\mediatek\mt8167\init.mt8167.rc
#added by dongshiyi for zigbee_bm023 start 20200507
chmod 0666 /sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control
chown root system /sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control
chmod 0666 /sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control
chown root system /sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control
#added by dongshiyi for zigbee_bm023 end 20200507
3.2 增加相关的策略
\device\mediatek\mt8167\sepolicy\bsp\file_contexts
#added by dongshiyi for zigbee_bm023 start 20200507
/sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control u:object_r:system_app_zigbee_bm023_by_elink_file:s0
/sys/devices/virtual/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control u:object_r:system_app_zigbee_bm023_by_elink_file:s0
#added by dongshiyi for zigbee_bm023 end 20200507
\device\mediatek\mt8167\sepolicy\bsp\file.te
#added by dongshiyi for zigbee_bm023 start 20200507
type system_app_zigbee_bm023_by_elink_file,fs_type,sysfs_type;
#added by dongshiyi for zigbee_bm023 end 20200507
\device\mediatek\mt8167\sepolicy\basic\cameraserver.te
#added by dongshiyi for zigbee_bm023 start 20200507
allow system_app system_app_zigbee_bm023_by_elink_file:file rw_file_perms;
#added by dongshiyi for zigbee_bm023 end 20200507
备注:
3.3v供电引脚拉高:往3.3v供电引脚节点写1 如下:
write("/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control" , "1");
3.3v供电引脚拉低:往3.3v供电引脚节点写0 如下:
write("/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_power_gpio_control" , "0");
复位引脚拉高:往3.3v供电引脚节点写0 如下:
write("/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control" , "0");
复位引脚拉低:往3.3v供电引脚节点写1 如下:
write("/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink/zigbee_rst_gpio_control" , "1");
上层app write方法参考:
import java.io.File;
import java.io.FileWriter;
private void write(String path , String content) {
FileWriter fw = null;
try {
File file = new File(path);
if (file.exists()) {
fw = new FileWriter(file, true);
fw.write(content);
}
} catch (Exception ex) {
Log.i("elink", "write error = "+ex.toString());
} finally {
try {
if (fw != null)
fw.close();
} catch (Exception ex) {
}
}
}
调试技巧
aiot8362am3_bsp:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink #
cat zigbee_power_gpio_control
0
aiot8362am3_bsp:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink #
zigbee_power_gpio_control zigbee_rst_gpio_control
echo 1 > zigbee_power_gpio_control
aiot8362am3_bsp:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink #
cat zigbee_power_gpio_control
1
zigbee_power_gpio_control zigbee_rst_gpio_control
echo 1 > zigbee_rst_gpio_control
aiot8362am3_bsp:/sys/class/zigbee_bm023_by_elink/zigbee_bm023_by_elink #
cat zigbee_rst_gpio_control
1