创龙瑞芯微RK3568设备树1(修改设备树GPIO和串口)

前言

    最近一直在搞3568的东西,涉及到底层的设备树修改,驱动编写等等,忙的焦头烂额的,也没时间往下面写东西了。今天差不多底层的东西快弄完了,把最近的感悟给大家分享下,并且加入点设备树的基础知识。给刚刚涉足开发板学习的小伙伴一点帮助。当然对于大神们来说,写的肯定是皮毛。一起共勉!

基础

    涉及到的知识,我会用类比的方法和STM32的硬件做对比,其实弄完之后发现两个差不多,没有什么本质的区别。所以小伙伴看之前的基础是必须编写过单片机的程序,对单片机的架构有一定的了解,要不看完会更迷茫。

题外话

    学习这个真是很痛苦,并且不知道自己做的对不对,需要一遍一遍的测试。并且问了其他小伙伴,有一个共同的感觉:随着年龄的增加,学习能力大大下降。并且已经抽不出那么多精力去学习能力了。

    每天刷抖音,看到什么35岁失业什么的,其实吧,感觉有三个原因吧,仅仅是自己猜测:

(1)技术没有做扎实就转到管理岗了。公司发展太快,所以刚进去的技术还没有很好的基础,就转到管理,使得自己的技术不扎实,再从管理岗转回来,已经很难了。

(2)技术也不错,但是忘记了学习,一直做自己习惯的东西,然后到了管理。但是到了管理之后,技术更新了,以前的技术已经适应不了现在的东西了。这个应该是大部分人的问题吧。就算在一个技术上做的时间长了,也会不学习了,感觉现在的东西够了。当然学习新的东西会很难、很闹心。其实我也想一直做单片机,也就控制几个灯,控制几个外设。然后搞搞逻辑啥的。一直在自己的舒适区。

(3)技术也够,学习也一直在学,但是换个工作工资低了,不愿将就。但愿每个人都是因为这个原因。

内容

    这次介绍4个内容,都是最简单的外设:(1)GPIO,(2)串口,(3)I2C,(4)CAN。这4个应该能包含大部分硬件应用了,当然还有麻烦的,后面再慢慢介绍,一点一点的来。先介绍最基本的,大概有个印象。

1.GPIO

	GPIO_InitTypeDef GPIO_Initure;
	__HAL_RCC_GPIOE_CLK_ENABLE();				

	GPIO_Initure.Pin = GPIO_PIN_15;			
	GPIO_Initure.Mode = GPIO_MODE_INPUT;  		
	GPIO_Initure.Pull = GPIO_PULLUP;         			
	GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  	
	HAL_GPIO_Init(GPIOE, &GPIO_Initure);     		

    这个是单片机的GPIO初始化。定义GPIO结构体,开时钟,管脚号,管脚输入,管脚模式,管脚速度,参数传入结构体。

HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET);

    这个是控制程序。直接根据HALk库给的函数就行。要是不用HAL库,自己控制,也都是别人给好的API函数。

对比下来,在Linux的3568设备树里:

        gpioled1 {
                compatible = "MY,led1";
                led1-gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
                status = "okay";
        };

    先说第二句:gpio的管脚定义,第三句:状态定义。

    第一句是匹配定义,这个后面再说。后面牵涉到驱动部分,这个后面会详细介绍,所以现在先由个概念,知道是这么回事。

    至此到这里,GPIO的设备树部分介绍完毕。下面说下两者的区别,仅仅说对于GPIO设定部分的区别哈,其他的就不说了,没啥用。

    相同点:定义了管脚,并且定义了初始电平;

    不同点:单片机定义了管脚的输入和输出,3568定义了匹配字。至于语法的区别,就不做过多的介绍了。

    所以,3568里面还需要对其他的进行定义,第一个:输入输出定义,第二个:控制程序。这个后面再说。先说下,输入输出定义在驱动里面定义,控制程序也是线程的API,只要拿过来使用就行了。

2.串口

    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    先说第一部分,管脚定义。这部分应该很熟悉,定义管脚,定义管脚复用,然后定义复用到什么上面,然后参数传入结构体。这部分是管脚的定义。

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 1000000;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;

  HAL_UART_Init(&huart2);

    然后说第二部分,串口定义。前面定义了管脚,相当于管脚已经复用到了串口上,然后定义串口的信息。对应串口2,波特率,起始位,停止位等。

    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);

    然后就是中断函数,接收和发送中断。对应的就是接收和发送函数中断。这个API在it.c里面应该可以找到。要是找不到就直接去库函数里面找。

    对比下来,在3568的设备树里:    

uart1 {
        /omit-if-no-ref/
        uart1m0_xfer: uart1m0-xfer {
            rockchip,pins =
                /* uart1_rxm0 */
                <2 RK_PB3 2 &pcfg_pull_up>,
                /* uart1_txm0 */
                <2 RK_PB4 2 &pcfg_pull_up>;
        };

        /omit-if-no-ref/
        uart1m0_ctsn: uart1m0-ctsn {
            rockchip,pins =
                /* uart1m0_ctsn */
                <2 RK_PB6 2 &pcfg_pull_none>;
        };

        /omit-if-no-ref/
        uart1m0_rtsn: uart1m0-rtsn {
            rockchip,pins =
                /* uart1m0_rtsn */
                <2 RK_PB5 2 &pcfg_pull_none>;
        };

        /omit-if-no-ref/
        uart1m1_xfer: uart1m1-xfer {
            rockchip,pins =
                /* uart1_rxm1 */
                <3 RK_PD7 4 &pcfg_pull_up>,
                /* uart1_txm1 */
                <3 RK_PD6 4 &pcfg_pull_up>;
        };

        /omit-if-no-ref/
        uart1m1_ctsn: uart1m1-ctsn {
            rockchip,pins =
                /* uart1m1_ctsn */
                <4 RK_PC1 4 &pcfg_pull_none>;
        };

        /omit-if-no-ref/
        uart1m1_rtsn: uart1m1-rtsn {
            rockchip,pins =
                /* uart1m1_rtsn */
                <4 RK_PB6 4 &pcfg_pull_none>;
        };
    };

    这个是pinctrl里面的设备树结构。里面包含串口的各种复用管脚定义。里面m0和m1可以自己选择,当然选择方法在后面。

    对比不同点:单片机里面直接写出来用哪个管脚,用哪个需要自己去写。而3568里面全部给你写出来,然后你自己再配置。

    uart1: serial@fe650000 {
        compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";
        reg = <0x0 0xfe650000 0x0 0x100>;
        interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
        clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
        clock-names = "baudclk", "apb_pclk";
        reg-shift = <2>;
        reg-io-width = <4>;
        dmas = <&dmac0 2>, <&dmac0 3>;
        pinctrl-names = "default";
        pinctrl-0 = <&uart1m0_xfer>;
        status = "disabled";
    };

    然后底层的设备树,这部分不用修改,别人给写好的。至于怎么写,不用管,只知道在这里就行。

    解释下:匹配字,状态,寄存器地址。中断地址,时钟,时钟名称,寄存器偏移,寄存器宽度,DMA,管脚名称,管脚初始定义。

    其实在单片机里,中断函数已经给你配好了,而设备树里直接给你写出来了。怎么写的 ,千万别去研究,别人做好的,直接用就行,或者直接知道是啥东西就行。然后管脚选用的是m0。这个是别人的初始定义,后面可以再修改。所以这个地方就看看,知道是啥就行,至于reg啥的,千万别管。

&uart1 {
    status = "okay";
    pinctrl-0 = <&uart1m1_xfer>;
};

    这是后面的自己定义。前面别人给个初始的,后面用不用看自己。用的话就来个okay,不用就不用管。要是用的话,管脚不一样咋弄,那就给改改。

    然后,然后就没了。就那么多东西。

    对于GPIO中的驱动,GPIO的驱动简单,可以自己写一个。但是串口的比较麻烦,别人都写好了,不用管。配好设备树之后,linux会自己加载驱动函数。就像单片机里面的收发中断,然后放到buffer里面。其实你也不知道咋驱动的,就是可以收到数,然后解析就行。

    切记:千万别深究,千万别深究。

不同

    设备树放的比较乱,如果别人开发的不好,放的会更乱,所以选开发板的时候选大厂的。放的位置好,你就好看点,学习起来也快。至于程序放的位置,放哪都行,随你意,但是最好按照别人写好的去放,看起来方便。

    单片机里面的东西,都是一块一块的,相对来说,别人都给你封好了,3568或者其他开发板里面的程序都是按照功能一大块放一起,看起来比较麻烦。

总结

    设备树就是将单片机的不同的功能,大家放一起,然后自己挑出来。并且用很晦涩的表达方式表达出来,不用看懂具体是啥,也不用纠结怎么去编写,会改管脚就行。给的pdf里面肯定会有说明怎么弄,要是没有,引用别人的话:赶紧跑路,还搞啥,自己肯定编不了。

后续

    接触的时候脑袋疼,这是啥,这又是啥。当真的去一个一个的琢磨之后,才发现,哦,和单片机差不多。学习顺序:克服心理障碍,静下心,一句一句的看,不会的查,改,改,改,不用担心改错,反正也改不坏。还有一定要做好备份,在修改任何东西前,一定先保存一份,万一改错了还能复原,再从开始改。

    后面介绍I2C和CAN的设备树,然后再介绍GPIO的驱动函数,然后就再ETH,然后再其他的。慢慢来。喜欢的小伙伴点个关注,后续文章继续发送。

相关推荐

  1. RK3588驱动设计之DVP并口摄像头2

    2023-12-27 18:56:03       8 阅读
  2. RK3568调试Android 11的各种方法

    2023-12-27 18:56:03       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-27 18:56:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-27 18:56:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-27 18:56:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-27 18:56:03       18 阅读

热门阅读

  1. MongoDB 字段部分内容替换 SQL整理

    2023-12-27 18:56:03       36 阅读
  2. 12.25力扣

    2023-12-27 18:56:03       43 阅读
  3. HBase 创建不分裂的表 ( 禁止 Table Split )

    2023-12-27 18:56:03       32 阅读
  4. [c]统计数字

    2023-12-27 18:56:03       41 阅读
  5. 发布版本自动化记录版本功能方法

    2023-12-27 18:56:03       36 阅读
  6. 【超图】SuperMap 模型处理自动化方案 ——目录

    2023-12-27 18:56:03       43 阅读
  7. 董事会在线审批决策任务都在哪里进行?

    2023-12-27 18:56:03       37 阅读
  8. 提升认识能力,远离诈骗

    2023-12-27 18:56:03       35 阅读