公司的板子使用两片SC16IS762 将一路SPI扩展成4路UART,使用内核中自带的SC16IS7xx通用驱动发现存在问题,

驱动提示SPI0.0 不存在,导致probe失败,但SPI使用spidev 驱动测试发现没有问题,同时由于最近在学习SPI驱动,

所以尝试自己写一个简单的驱动,这里介绍驱动的调试过程。

主要参考这位网友的文章,将驱动修改为设备树的形式在Linux 4.x 的版本运行,并解决一些BUG.

原文链接: https://blog.csdn.net/u014106791/article/details/52208249

芯片晶振为18.432M HZ,网友要根据自己的电路晶振设置分频值!

驱动代码如下(包含设备树):

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <asm/uaccess.h>
#include <linux/sched.h>#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/of_irq.h>
#include <linux/irq.h>
#include <asm/mach/map.h>
#include <asm/io.h>#if 0
/* 注意RST 引脚要拉高 !!*/
&spi0 {status = "okay";max-freq = <48000000>;       //spi internal clk, don't modifypinctrl-names = "default";   //pinctrl according to you boardpinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0 &spi0_cs1>;#if 0   spidev@0 {compatible = "rockchip,spidev";reg = <0>;spi-max-frequency = <24000000>;//spi-cpha = <1>;};spidev@1 {compatible = "rockchip,spidev";reg = <1>;spi-max-frequency = <24000000>;//spi-cpha = <1>;};#endif#if 1//pinctrl-names = "default";   //pinctrl according to you board//pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0 &spi0_cs1>;sc16is762@01 {compatible = "mysc16is762";reg = <0x01>;   //chip select  0:cs0  1:cs1spi-max-frequency = <1000000>;   //spi output clockpinctrl-names = "default";       //pinctrl according to you boardpinctrl-0 = <&sc16is762_irqgpio>;interrupt-parent = <&gpio8>;interrupts = <1 IRQ_TYPE_EDGE_FALLING>;irq-gpio = <&gpio8 1 GPIO_ACTIVE_LOW>;//cs-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>;//rst-gpio = <&gpio6 22 GPIO_ACTIVE_HIGH>;};#endif
};sc16is762_irqgpio {sc16is762_irqgpio: sc16is762-irqgpio {rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;};rst_gpio: rst-gpio {rockchip,pins = <6 22 RK_FUNC_GPIO &pcfg_pull_up>;};};
#endif/*
//device tree like this
&spi0 {status = "okay";max-freq = <48000000>;   //spi internal clk, don't modify//dma-names = "tx", "rx";   //enable dmapinctrl-names = "default";  //pinctrl according to you boardpinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0 &spi0_cs1>;sc16is762@01 {compatible = "sc16is762";reg = <0>;   //chip select  0:cs0  1:cs1id = <0>;spi-max-frequency = <1000000>;   //spi output clockpinctrl-names = "default";  //pinctrl according to you boardpinctrl-0 = <&sc16is762_irqgpio>;interrupt-parent = <&gpio8>;interrupts = <1 IRQ_TYPE_EDGE_FALLING>;irq-gpio = <&gpio8 1 GPIO_ACTIVE_HIGH>;//spi-cpha;      not support//spi-cpol;   //if the property is here it is 1:clk is high, //else 0:clk is low  when idle};};sc16is762_irqgpio {pinctrl_mykey: keygrp {rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_up>;};
};
*/ #define     RHR          0x00            //R
#define     THR         0x00            //W#define     IER          0x01#define     FCR         0x02            //R
#define     IIR         0x02            //W#define     LCR          0x03
#define     MCR         0x04
#define     LSR         0x05
#define     MSR_1       0x06            //本来是直接定义为MSR的,但是这样定义与汇编指令MSR有冲突
#define     SPR         0x07#define     TCR         0x06            //These registers are accessible only when EFR[4] = 1, and MCR[2] = 1
#define     TLR         0x07#define     TXLVL       0x08
#define     RXLVL       0x09
#define     IODIR_762       0x0a
#define     IOSTATE     0x0b
#define     IOINTENA        0x0c
#define     RESERVED        0x0d
#define     IOCONTROL       0x0e
#define     EFCR        0x0f//special register The Special Register set is accessible only when LCR[7] = 1 and not 0xBF
#define     DLL         0x00
#define     DLH         0x01//enhanced register Enhanced Features Registers are only accessible when LCR = 0xBF
#define     EFR         0x02
#define     XON1        0x04
#define     XON2        0x05
#define     XOFF1       0x06
#define     XOFF2       0x07//定义端口
#define channelA        0x0
#define channelB        0x1#define KEY_NUM 1 /* 按键数量 */
//定义spi uart操作幻数
#define SET_channleA _IOW('k', 0, int)
#define SET_channleB _IOW('k', 1, int)
#define SET_STOP_BIT _IOW('k', 2, int)
#define SET_BPS _IOW('k', 3, int)struct irq_keydesc {int gpio; /* gpio */int irqnum; /* 中断号 */char name[15]; /* 名字 */irqreturn_t (*handler)(int, void *); /* 中断服务函数 */
}; struct sc16is762_dev {struct device_node *nd; /* 设备节点 */struct spi_device *spi;spinlock_t spi_lock;struct mutex lock;unsigned char *buf;unsigned int channel_num;int gpio; int irqnum;struct irq_keydesc irqkeydesc[KEY_NUM]; /* 按键 init 述数组 */struct work_struct *sc762_irq_work;wait_queue_head_t sc16is762_q;unsigned int condition;
};static struct sc16is762_dev *sc16is762=NULL; static char read_762_reg(unsigned int reg, unsigned int channel)
{struct spi_transfer t[2];struct spi_message m;unsigned long flags;char val = 0;unsigned char cmd = 0x80 | (reg << 3) | (channel << 1);spi_message_init(&m);memset(t, 0, (sizeof t));t[0].tx_buf = &cmd;t[0].len = 1;spi_message_add_tail(&t[0], &m);t[1].rx_buf = &val;t[1].len = 1;spi_message_add_tail(&t[1], &m);spin_lock_irqsave(&sc16is762->spi_lock,flags);spi_sync(sc16is762->spi, &m);spin_unlock_irqrestore(&sc16is762->spi_lock,flags);return val;
}static ssize_t read_channel(int len)
{
#if 0struct spi_transfer t[2];struct spi_message m;unsigned char cmd;cmd = 0x80 | (THR << 3) | (sc16is762->channel_num<< 1);printk(KERN_INFO "enter read_channel\n");spi_message_init(&m);memset(t, 0, (sizeof t));t[0].tx_buf = &cmd;t[0].len = 1;spi_message_add_tail(&t[0], &m);t[1].rx_buf = sc16is762->buf;t[1].len = len;spi_message_add_tail(&t[1], &m);spin_lock_irq(&sc16is762->spi_lock);spi_sync(sc16is762->spi, &m);spin_unlock_irq(&sc16is762->spi_lock);printk(KERN_INFO "m.actual_length = %d\n",m.actual_length);return m.actual_length;
#endifunsigned int length = 0;unsigned char status = 0;do{status = read_762_reg(LSR, sc16is762->channel_num);if(status & 0x01){   sc16is762->buf[length] = read_762_reg(RHR, sc16is762->channel_num);length ++;}}while(status & 0x01);return length;
}static void write_762_reg(unsigned int reg, unsigned int channel, unsigned char data)
{struct spi_transfer t[2];struct spi_message m;unsigned long flags;char val = data; unsigned char cmd;cmd = 0x00 | (reg << 3) | (channel << 1);spi_message_init(&m);memset(t, 0, (sizeof t));t[0].tx_buf = &cmd;t[0].len = 1;spi_message_add_tail(&t[0], &m);t[1].tx_buf = &val;t[1].len = 1;spi_message_add_tail(&t[1], &m);spin_lock_irqsave(&sc16is762->spi_lock,flags);spi_sync(sc16is762->spi, &m);spin_unlock_irqrestore(&sc16is762->spi_lock,flags);return;
}static void write_channel(unsigned char *buf, int len)
{struct spi_transfer t[2];struct spi_message m;unsigned char status;unsigned char cmd;cmd = 0x00 | (THR << 3) | (sc16is762->channel_num << 1);status = read_762_reg(LSR, sc16is762->channel_num);if (status & 0x20){spi_message_init(&m);memset(t, 0, (sizeof t));t[0].tx_buf = &cmd;t[0].len = 1;spi_message_add_tail(&t[0], &m);t[1].tx_buf = buf;t[1].len = len;spi_message_add_tail(&t[1], &m);spin_lock_irq(&sc16is762->spi_lock);spi_sync(sc16is762->spi, &m);spin_unlock_irq(&sc16is762->spi_lock);}return;
}static int sc16is762_open(struct inode *inode, struct file *filp)
{filp->private_data = sc16is762;/*initlizate channel A*/write_762_reg(LCR, channelA, 0x80);write_762_reg(DLL, channelA, 0x0a);write_762_reg(DLH, channelA, 0x00);write_762_reg(LCR, channelA, 0xbf);write_762_reg(EFR, channelA, 0x10);write_762_reg(LCR, channelA, 0x03);write_762_reg(IER, channelA, 0x01);write_762_reg(FCR, channelA, 0xf1);//write_762_reg(FCR, channelA, 0x51);write_762_reg(SPR, channelA, 0x41);write_762_reg(IODIR_762, channelA, 0xff);write_762_reg(IOSTATE, channelA, 0x00);/*initlizate channel B*/write_762_reg(LCR, channelB, 0x80);write_762_reg(DLL, channelB, 0x0a);write_762_reg(DLH, channelB, 0x00);write_762_reg(LCR, channelB, 0xbf);write_762_reg(EFR, channelB, 0x10);write_762_reg(LCR, channelB, 0x03);write_762_reg(IER, channelB, 0x01);write_762_reg(FCR, channelB, 0xf1);//write_762_reg(FCR, channelB, 0x51);write_762_reg(SPR, channelB, 0x41);write_762_reg(IODIR_762, channelB, 0xff);write_762_reg(IOSTATE, channelB, 0x00);//request spi buffersc16is762->buf = kmalloc(64,GFP_KERNEL);if(!sc16is762->buf){printk(KERN_INFO "kzallo buf error\n");return -ENOMEM;}nonseekable_open(inode, filp);//设置为不可随机读取。printk(KERN_INFO "open and initlizate channel A/B succeed\n "); return 0;
}static int sc16is762_release(struct inode *inode, struct file *filp)
{if (NULL != sc16is762->buf)kfree(sc16is762->buf);return 0;
} static long sc16is762_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
{unsigned char tmp = 0;switch (cmd) {case SET_channleA:{sc16is762->channel_num = channelA;break;}case SET_channleB:{sc16is762->channel_num = channelB;break;}case SET_STOP_BIT:{tmp = read_762_reg(LCR, sc16is762->channel_num);if(1 ==  args){tmp &= (~(0x01<<2));//设置1位停止位write_762_reg(LCR, sc16is762->channel_num, tmp);}else if (2 == args){tmp |= (0x01<<2);//设置1.5/2位停止位write_762_reg(LCR, sc16is762->channel_num, tmp);}break;}case SET_BPS:{tmp = read_762_reg(IER, sc16is762->channel_num);tmp &= (~(0x01<<4));//禁止睡眠模式才可以设置波特率。write_762_reg(IER, sc16is762->channel_num, tmp);if(57600 == args){   write_762_reg(LCR, sc16is762->channel_num, 0x80);write_762_reg(DLL, sc16is762->channel_num, 0x14);write_762_reg(DLH, sc16is762->channel_num, 0x00);write_762_reg(LCR, sc16is762->channel_num, 0xbf);write_762_reg(EFR, sc16is762->channel_num, 0x10);write_762_reg(LCR, sc16is762->channel_num, 0x03);write_762_reg(IER, sc16is762->channel_num, 0x01);write_762_reg(FCR, sc16is762->channel_num, 0xf1);write_762_reg(SPR, sc16is762->channel_num, 0x41);write_762_reg(IODIR_762, sc16is762->channel_num, 0xff);write_762_reg(IOSTATE, sc16is762->channel_num, 0x00);}else if(115200 == args){write_762_reg(LCR, sc16is762->channel_num, 0x80);write_762_reg(DLL, sc16is762->channel_num, 0x0a);write_762_reg(DLH, sc16is762->channel_num, 0x00);write_762_reg(LCR, sc16is762->channel_num, 0xbf);write_762_reg(EFR, sc16is762->channel_num, 0x10);write_762_reg(LCR, sc16is762->channel_num, 0x03);write_762_reg(IER, sc16is762->channel_num, 0x01);write_762_reg(FCR, sc16is762->channel_num, 0xf1);write_762_reg(SPR, sc16is762->channel_num, 0x41);write_762_reg(IODIR_762, sc16is762->channel_num, 0xff);write_762_reg(IOSTATE, sc16is762->channel_num, 0x00);}else if(9600 == args){write_762_reg(LCR, sc16is762->channel_num, 0x80);write_762_reg(DLL, sc16is762->channel_num, 0x78);write_762_reg(DLH, sc16is762->channel_num, 0x00);write_762_reg(LCR, sc16is762->channel_num, 0xbf);write_762_reg(EFR, sc16is762->channel_num, 0x10);write_762_reg(LCR, sc16is762->channel_num, 0x03);write_762_reg(IER, sc16is762->channel_num, 0x01);write_762_reg(FCR, sc16is762->channel_num, 0xf1);write_762_reg(SPR, sc16is762->channel_num, 0x41);write_762_reg(IODIR_762, sc16is762->channel_num, 0xff);write_762_reg(IOSTATE, sc16is762->channel_num, 0x00);}break;}default:break;    }return 0;
}static ssize_t sc16is762_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
{struct sc16is762_dev *sc16is762 = filp->private_data;int length = 0;int missing;//wait_event(sc16is762->sc16is762_q,sc16is762->condition);//用此函数会导致进程杀不死。wait_event_interruptible(sc16is762->sc16is762_q,sc16is762->condition);mutex_lock(&sc16is762->lock);length = read_channel(size);missing = copy_to_user(buf, sc16is762->buf, length);if (missing == length)length = -EFAULT;elselength = length - missing;mutex_unlock(&sc16is762->lock);sc16is762->condition = 0;return length;
}static ssize_t sc16is762_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
{int missing ;struct sc16is762_dev *sc16is762 = filp->private_data;//一次最大写64 bytes , sc16is762 fifo 长度if(size > 64)return -EMSGSIZE;mutex_lock(&sc16is762->lock);missing = copy_from_user(sc16is762->buf, buf, size);write_channel(sc16is762->buf, size);mutex_unlock(&sc16is762->lock);if(missing == 0){return size;}else if(missing > 0){return size-missing;}return 0;
}struct file_operations sc16is762_fops = {.owner = THIS_MODULE,.open = sc16is762_open,.write = sc16is762_write,.read = sc16is762_read,.unlocked_ioctl = sc16is762_ioctl,.release = sc16is762_release,
};struct miscdevice sc16is762_misc = {.minor = MISC_DYNAMIC_MINOR,.name = "sc16is762",.fops = &sc16is762_fops,
}; void sc762_work_func(struct work_struct *work)
{//unsigned char tmp = 0;//tmp = read_762_reg(IIR, sc16is762->channel_num);printk(KERN_INFO "enter sc762_work_func\n");//判断是否为接收中断//if(tmp & 0x04) //{sc16is762->condition = 1;wake_up(&sc16is762->sc16is762_q);//}
}irqreturn_t sc16is762_handler(int irq, void *dev_id)
{schedule_work(sc16is762->sc762_irq_work);printk(KERN_INFO "enter sc16is762_handler\n");return IRQ_HANDLED;
}/** @description : 按键 IO 初始化* @param : 无* @return : 无*/
static int irqgpio_init(void)
{unsigned char i = 0;char name[10];int ret = 0;sc16is762->nd = of_find_node_by_path("/spi@ff110000/sc16is762@01");if (sc16is762->nd== NULL){printk("key node not find!\r\n");return -EINVAL;}/* 提取 GPIO */for (i = 0; i < KEY_NUM; i++) {sc16is762->irqkeydesc[i].gpio = of_get_named_gpio(sc16is762->nd,"irq-gpio", i);if (sc16is762->irqkeydesc[i].gpio < 0) {printk("can't get key%d\r\n", i);}}/* 初始化 key 所使用的 IO,并且设置成中断模式 */for (i = 0; i < KEY_NUM; i++) {memset(sc16is762->irqkeydesc[i].name, 0, sizeof(name));sprintf(sc16is762->irqkeydesc[i].name, "irq-gpio%d", i);gpio_request(sc16is762->irqkeydesc[i].gpio, name);gpio_direction_input(sc16is762->irqkeydesc[i].gpio);sc16is762->irqkeydesc[i].irqnum = irq_of_parse_and_map(sc16is762->nd, i);
#if 0sc16is762->irqkeydesc[i].irqnum = gpio_to_irq(sc16is762->irqkeydesc[i].gpio);
#endifprintk("irq%d:gpio=%d, irqnum=%d\r\n",i,sc16is762->irqkeydesc[i].gpio,sc16is762->irqkeydesc[i].irqnum);}/* 申请中断 */sc16is762->irqkeydesc[0].handler = sc16is762_handler;for (i = 0; i < KEY_NUM; i++) {ret = request_irq(sc16is762->irqkeydesc[i].irqnum,sc16is762->irqkeydesc[i].handler,IRQF_TRIGGER_FALLING,sc16is762->irqkeydesc[i].name, sc16is762);if(ret < 0){printk("irq %d request failed!\r\n",sc16is762->irqkeydesc[i].irqnum);return -EFAULT;}}/* 初始化等待队列头 */
//  init_waitqueue_head(&imx6uirq.r_wait);return 0;
}static int sc16is762_probe(struct spi_device *spi)
{int ret = 0;//printk(KERN_INFO "Spi device sc16is762 is probed!\n");sc16is762 = kzalloc(sizeof(*sc16is762), GFP_KERNEL);if (!sc16is762)return -ENOMEM;sc16is762->channel_num = channelA;//默认使用channelAsc16is762->buf = NULL;//sc16is762->irq = spi->irq;    //中断sc16is762->spi = spi;spin_lock_init(&sc16is762->spi_lock);mutex_init(&sc16is762->lock);ret = misc_register(&sc16is762_misc);if (ret != 0) {printk(KERN_INFO "cannot register miscdev err = %d\n", ret);}//printk(KERN_INFO "sc16is762->irq %d\n",sc16is762->irq);
//  ret = request_threaded_irq(sc16is762->irq, NULL, sc16is762_handler,
//      IRQF_TRIGGER_FALLING, "sc16is762", NULL);ret = irqgpio_init();if (ret < 0 ){  printk(KERN_INFO  "Failed to request IRQ!\n");}sc16is762->sc762_irq_work = kzalloc(sizeof(struct work_struct),GFP_KERNEL);INIT_WORK(sc16is762->sc762_irq_work, sc762_work_func);init_waitqueue_head(&sc16is762->sc16is762_q);sc16is762->condition = 0;//初始化等待条件为0spi_set_drvdata(spi, sc16is762);return 0;
}static int  sc16is762_remove(struct spi_device *spi)
{unsigned i = 0;misc_deregister(&sc16is762_misc);for (i = 0; i < KEY_NUM; i++) {free_irq(sc16is762->irqkeydesc[i].irqnum, sc16is762);}kfree(sc16is762);return 0;
}static struct spi_driver sc16is762_driver = {.driver = {.name        = "mysc16is762",.owner       = THIS_MODULE,},.probe     = sc16is762_probe,.remove      = sc16is762_remove,
};static int __init sc16is762_init(void)
{return spi_register_driver(&sc16is762_driver);
}static void __exit sc16is762_exit(void)
{spi_unregister_driver(&sc16is762_driver);
}module_init(sc16is762_init);
module_exit(sc16is762_exit);MODULE_DESCRIPTION("Driver for most SPI sc16is762");
MODULE_AUTHOR("KuangMH");
MODULE_LICENSE("GPL");
MODULE_ALIAS("sct");

测试代码如下:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>#define SC752 "/dev/sc16is762"#define SET_channleA _IOW('k', 0, int)
#define SET_channleB _IOW('k', 1, int)
#define SET_STOP_BIT _IOW('k', 2, int)
#define SET_BPS _IOW('k', 3, int)#define STOP_BIT_1 0x01
#define STOP_BIT_2 0x02/**************************************************/
/*  说明:752可以设置1 1.5 2 位停止位,默认设置为1个停止位,字长度默认为8,且不可修改 */
/*  默认波特率设置为9600  */
/*  0-1个停止位(字长度=5,6,7,8) */
/*  1.5个停止位(字长度=5)*/
/*  2个停止位 */
/**************************************************/int main(void)
{char buf[64] = {0};int length = 0;int i = 0;int fd = open(SC752, O_RDWR);if (fd < 0) {printf("Open %s failure.\n", SC752);return -1;}int rate;char c;ioctl(fd, SET_channleB);while(1){/*默认是通道A,波特率115200,停止位1位*/printf("this is default test,stop bit is 1,Baud rate is 115200\n");rate = write(fd, "hello", 6);printf("send %d byte\r\n",rate);sleep(1);write(fd, "world", 6);printf("send success\r\n");length = read(fd, buf, 30);for(i = 0;i<length; i++){printf("%s\r\n", buf);    }printf("\n");memset(buf, 0, 64);sleep(1);}close(fd);return 0;
}

SC16IS762 在RK3288 上的应用相关推荐

  1. rk1808交叉编译opencv_关于在RK3288上安装Opencv的方法

    本帖最后由 暴走的阿Sai 于 2017-7-7 10:30 编辑 Opencv是一个开源的计算机视觉库,可以给开发人员提供更便捷的方式设计复杂的视觉应用,Opencv主要是用c和c++编写,可以运行 ...

  2. 在平台RK3288上编写键盘驱动

    环境介绍 硬件:RK3288.键盘驱动芯片PCA9535(I2C-GPIO) 软件:android 7.1 linux4.4 原理图: I2C1_INT:GPIO5_B3 I2C1_RST:GPIO7 ...

  3. rk3288上ap6212自定义wifi的mac地址

    先看log打印: [ 103.514715] bcmsdh_oob_intr_register: HW_OOB irq=229 flags=0x4 [ 103.515484] dhd_get_memd ...

  4. 导出RK3288开发板上的根文件系统,并打包img

    整体操作一共三步: 一.将Rk3288的整个根文件系统的文件,通过ssh拷贝到PC系统(Ubuntu): 二.将此拷贝的全部文件,加载到虚拟光盘中,制作成img文件: 三.将img文件,再烧回RK32 ...

  5. RK3288下如何实现虚拟摄像头。

    提示:安卓.RK3288.虚拟摄像头 文章目录 前言 一.v4l2loopback是什么 二.ffmepg是什么 三.ubuntu环境准备 四.安卓源代码编译环境准备 五.RK3288开发环境准备 六 ...

  6. rk3288 7.1 mlx90640调试

    由于疫情的影响,最近在调试测温模块mlx90640 mlx90614,下面简单描述下mlx90640的驱动开发. 站在巨人(https://blog.csdn.net/qq_33487044/arti ...

  7. 多才多艺的移动式人形机器人iPal,担当起小朋友的“好家教”

    AvatarMind近日开始在中国发布移动式人形iPal机器人的早期版本,并正在为美国的发行做准备.iPal机器人主要面向的客户群体包括长者.特殊需要儿童以及医院病人的对话伴侣,同时也适合应用于教育. ...

  8. internal compiler error: Killed (program cc1plus)

    遇到问题的场景:在rk3288上编译时需要较大的内存空间超过了板子的内存限制,故报错 可以使用临时使用磁盘空间作为swap空间来解决,命令如下: sudo dd if=/dev/zero of=/sw ...

  9. 基于NEON指令的图像旋转加速【armv7】

    目录 前言 知识直通车 NEON转置指令 右旋90 4x4矩阵右旋实例 灰度图(单通道)右旋90 彩图(RGB三通道)右旋90 左旋90 4x4矩阵左旋实例 灰度图(单通道)左旋90 彩图(RGB三通 ...

最新文章

  1. oracle 并接去掉字符串,ORACLE删除字符-TRIM字符截取-substr查找字符-instr
  2. LINUX网络状态工具SS命令使用详解
  3. Leaflet快速入门与加载OSM显示地图
  4. jdbc获取结果行数_如何获取JDBC中的行数?
  5. 执行git命令时提示秘钥权限太开放‘Permissions 0644 for ‘/Users/liuml/.ssh/id_rsa_tz‘ are too open.’
  6. Android开发之SQLite的使用方法
  7. Python 之 文件
  8. Django2.1简介及安装
  9. atitit.无线网卡 不能搜索到WiFi 无线路由信号的解决不能上网
  10. vijos一元三次方程求解
  11. 张小七的C#语言笔记
  12. 在vue中报export ‘default‘ (imported as ‘Vue‘) was not found in ‘vue 解决办法
  13. S7-1200PLC定时器计数器的应用
  14. 去处word红色波浪线
  15. 在Linux下驱动D-link DFE-530TX(最终稿)(转)
  16. 奉劝学弟学妹,学完JavaScript就该学TypeScript了,让我们一起了解TypeScript和如何去搭建运行环境吧
  17. 不可以涩涩!AI续写软件初体验;迁移学习路线图;谷歌新闻非官方搜索API;CS295『因果推理』2021课程资料;前沿论文 | ShowMeAI资讯日报
  18. 产品经理必懂的技术知识
  19. .net core发布linux详解
  20. 亲友定位助手--具备实时共享位置的智能手机定位地图软件的设计

热门文章

  1. 编程为什么要立flag
  2. 十三、C# WINDOW窗体技术及基础控件(3)
  3. python爬取股票信息—简略版(沪股)
  4. 信创势不可挡,数据传输软件怎样国产化替代?
  5. live555 如何设置时间戳
  6. (5) — ARC之Outlet与弱引用 转自易飞扬
  7. [日推荐]『法里法律咨询』没钱也能有个私人专业法律顾问,免费的
  8. ArrayList类
  9. Centos7搭建Ngrok内网穿透
  10. 商丘市助理工程师职称评定评审条件及流程