本帖最后由 supenghou 于 2023-2-17 01:09 编辑  
 
使rtt运行起来关键要素两个: 1、 led灯闪烁起来—main函数 2、 让串口进行命令行调试信息 首先led亮起来 Led关键信息 代码: IO引脚声明 - /* defined the LED pin: GPIO1_IO4 */
 
 - /* GPIO1_4 is Blue LED */
 
 - #define LEDB_PIN      GET_PINS(1, 4)
 
  复制代码 
IO所声明的引脚  
- rt_pin_write(LEDB_PIN, PIN_HIGH);   /* Set GPIO output 1 */
 
 - rt_thread_mdelay(500);                     /* Delay 500mS */
 
 - rt_pin_write(LEDB_PIN, PIN_LOW);    /* Set GPIO output 0 */
 
 - rt_thread_mdelay(500);                     /* Delay 500mS */
 
  复制代码 
 
驱动说明,这里巧妙在宏定义 #define GET_PINS(PORTx, PINx)   (32 * PORTx + PINx + 1) /* PORTx:0,1, PINx:0,1...31 */ (1,4) 代入既是32*1+4+1=37 在驱动drv_pin.c中查表lpc_pin_map[],(在其他芯片有叫pin[]的或者其他名字的) 列表实现: - static struct lpc_pin lpc_pin_map[] =
 
 - {
 
 -        __LPC55S69_PIN_DEFAULT,//代表0无效
 
 - __LPC55S69_PIN(1, GPIO, 0,  0),    /* PIO0_00 */
 
 -       __LPC55S69_PIN( 2, GPIO, 0, 1),    /* PIO0_01 */
 
 -       __LPC55S69_PIN( 3, GPIO, 0, 2),    /* PIO0_02 */
 
 -       __LPC55S69_PIN( 4, GPIO, 0, 3),    /* PIO0_04 */
 
 -       __LPC55S69_PIN( 5, GPIO, 0, 4),    /* PIO0_04 */
 
 - ……
 
 - /* PIO1 / GPIO,1 */
 
 -       __LPC55S69_PIN(33, GPIO, 1, 0),    /* PIO1_00 */
 
 -       __LPC55S69_PIN(34, GPIO, 1, 1),    /* PIO1_01 */
 
 -       __LPC55S69_PIN(35, GPIO, 1, 2),    /* PIO1_02 */
 
 -       __LPC55S69_PIN(36, GPIO, 1, 3),    /* PIO1_03 */
 
 - <font color="#ff0000">      __LPC55S69_PIN(37, GPIO, 1, 4),    /* PIO1_04 */</font>
 
 -       __LPC55S69_PIN(38, GPIO, 1, 5),    /* PIO1_05 */
 
 - ……
 
  
- }
 
  复制代码 
#define __LPC55S69_PIN(INDEX, REG, PORT,PIN) {INDEX, REG, PORT, PIN}                                       序号    属性   大类  分类IO序号 通过宏定义得知给驱动拼凑字符的,这里不明显,引用其他的芯片特性 比如单片机es8p5086驱动相关 __ES8P_PIN(3, B, 2) 则宏定义为#define __ES8P_PIN(index, gpio,gpio_index) {index, GPIO##gpio, GPIO_Pin_##gpio_index} 使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起,既为(3,GPIOB,GPIO_Pin_2) 关键字符GPIOB和GPIO_Pin_2,这样驱动,有转义字符对应的数字好处具有直视感。 操作方法和芯片给与的驱动有关系,他要什么,程序就要给什么。 我这里用的自己板子,led1是P1.1 我就把上面的GET_PINS(1, 4)该成了GET_PINS(1, 1)。  
第二个需要改的是命令调试串口,这里板子和例程对应上去了无需更改,但是也说以下 更改串口,主要三个位置 1、启用对应串口驱动,2、串口对应的io脚位的对应,3、命令控制台挂在串口上 1、在rt_config.h 
1 
 
 2、在drv_uart.c 实际上对外输出驱动具有寄存器,数据缓存操作区,然后针对io的映射设置三大项 上面开启串口0就是寄存器和数据缓存区打通了,然后这里对io映射进行打通,因为一个模块比如串口0可以映射到多个io口进行对外操作。 啰嗦语:实际上驱动关键信息是以结构体形式封装为整体,由系统进行发起,驱动对结构体进行实现,而驱动之际占用数据存储内存为通用内存池,驱 动实现了结构体的操作地址,换句话说是操作系统通过结构体的动作操作地址来找驱动操作方法,这里进行包含与反包含的操作,而驱动的中断也由驱动实现,尽可能的短暂的把操作把寄存器数据存储到数据缓存操作区,可以通知系统后续操作。重点在那个驱动结构体,也叫类,而动用驱动的句柄就是指引到这个类的。Find句柄得驱动,也得到驱动的“操作”。 但是io的定义在上述文件drv_uart.c未找到,那整个板子得io口都是整板声明了,很板级化,在下述文件pin_mux.c中找到了io定义位置: - void BOARD_InitPins(void)
 
 - {
 
 -    /* Enables the clock for the I/O controller.: Enable Clock. */
 
 -     CLOCK_EnableClock(kCLOCK_Iocon);
 
 -     ... ...
 
 -     const uint32_t port0_pin29_config = (/* Pinis configured as FC0_RXD_SDA_MOSI_DATA */ <font color="#ff0000">//串口P0.29_UART_RXD</font>
 
 -                                         IOCON_PIO_FUNC1 |
 
 -                                          /* Noaddition pin function */
 
 -                                          IOCON_PIO_MODE_INACT|
 
 -                                          /*Standard mode, output slew rate control is enabled */
 
 -                                         IOCON_PIO_SLEW_STANDARD |
 
 -                                          /* Input function is not inverted */
 
 -                                         IOCON_PIO_INV_DI |
 
 -                                          /*Enables digital function */
 
 -                                         IOCON_PIO_DIGITAL_EN |
 
 -                                          /* Open drain isdisabled */
 
 -                                         IOCON_PIO_OPENDRAIN_DI);
 
 -     /* PORT0 PIN29 (coords: 92) is configuredas FC0_RXD_SDA_MOSI_DATA */
 
 -     IOCON_PinMuxSet(IOCON, 0U, 29U,port0_pin29_config);
 
  
-     const uint32_t port0_pin30_config = (/* Pinis configured as FC0_TXD_SCL_MISO_WS */<font color="#ff0000"> //串口P0.30_UART_TXD</font>
 
 -                                         IOCON_PIO_FUNC1 |
 
 -                                          /* Noaddition pin function */
 
 -                                         IOCON_PIO_MODE_INACT |
 
 -                                          /*Standard mode, output slew rate control is enabled */
 
 -                                          IOCON_PIO_SLEW_STANDARD |
 
 -                                          /*Input function is not inverted */
 
 -                                         IOCON_PIO_INV_DI |
 
 -                                          /*Enables digital function */
 
 -                                         IOCON_PIO_DIGITAL_EN |
 
 -                                          /*Open drain is disabled */
 
 -                                         IOCON_PIO_OPENDRAIN_DI);
 
 -     /* PORT0 PIN30 (coords: 94) is configuredas FC0_TXD_SCL_MISO_WS */
 
 -     IOCON_PinMuxSet(IOCON, 0U, 30U,port0_pin30_config);
 
 -     ... ...
 
 - }
 
  复制代码在这个函数调用 - void BOARD_InitBootPins(void)
 
 - {      //主板初始化引导
 
 - <font color="#ff0000">   BOARD_InitPins();</font>
 
 - }
 
  复制代码 
这里就涉及到芯片引脚定义工具了,不是人为的写入。实用了io引脚定义化工具来勾选是arm高级芯片常规操作,一个程序直接对应一套板子,io固定。 实际上上面函数没用,属于批量生成函数。 而在board.c中用初始化函数调用了 BOARD_InitPins();  。 - void rt_hw_board_init()
 
 - {
 
 -    /* Hardware Initialization */
 
 - <font color="#ff0000">    BOARD_InitPins();         //调用在这里</font>
 
 -     ... ...
 
 - }
 
  复制代码而函数rt_hw_board_init()又被components.c中的如下函数调用 - int rtthread_startup(void)
 
 - {
 
 -     ... ...
 
 - <font color="#ff0000">    rt_hw_board_init();</font>
 
 -     ... ...
 
 - }
 
  复制代码 
而上述函数又被main截胡函数引用 - int $Sub$main(void)
 
 - {
 
 - <font color="#ff0000">   rtthread_startup();</font>
 
 -    return 0;
 
 - }
 
  复制代码 
我一直以为会被组件初始化宏接口调用比如INIT_BOARD_EXPORT(rt_hw_board_init);初始化结果如此简单粗暴,实际用了int $Sub$$main(void)函数,函数作用是在执行main前截胡,执行这个函数,然后再通过对应语句回去,但是众所周知,是回不去的,rtt把main函数当成线程了,启动main线程了,也就是rtt不会像前后台那样执行main函数,而是做成了优先级为20的线程,main函数只有象征意义了。 3、使用uart0为控制台输出 也在rt_config.h里定义 
2 
 
 这里直接引用了设备名称,因为在调用串口之前,会find到串口句柄,后续命令控制台就可以操作了。  
罗嗦语:其实find有好多种,驱动find,就是在容器内找对应名字的句柄,除了驱动find外还有通用find,只要知道名字你就能找到线程然后继续操作,或者找寻信号量,只要知道名字,因为任何类都在大统一容器内,而容器分类后所有的东西都是通过链表挂连的. 其实rtt就是一种c面向对象的编程方法教材。 在github下载的5.0遇到的问题        
        
        
         |