【RT-Thread】RT-Thread外设例程——I/O口控制(高低电平、中断)

目录

前言

一、学习的重点内容

1.1、内核

1.1.1、内核基础

1.1.2、线程管理

1.2、 设备和驱动

1.2.1、I/O口设备模型

 1.2.2、PIN设备

二、示例程序

2.1、外设例程——Led

2.1、外设例程——PIN

前言

使用的芯片:STM32F407ZG,正点原子探索者板

  • 前面几篇博文已经对RT-Thread进行了大体的了解

在本专栏的前期工作基本已经准备好,对于BSP的制作与RT-Thread的继续学习将在本篇博客展开,写博客的目的也是在对自己的学习过程有一个总结。

如何看RT-Thread文档、RT的工程建立和BSP快速构建_追逐者-桥的博客-CSDN博客

RT-Thread中常用的指令_追逐者-桥的博客-CSDN博客

RT-Thread内核快速入门,内核实现与应用开发学习随笔记_追逐者-桥的博客-CSDN博客

RT-Thread改变打印串口(在BSP的基础上添加其他功能)_追逐者-桥的博客-CSDN博客

  • 对于RT的学习将再这篇博文进行整理

​​​​​​​

 本篇笔记主要记录了:

内核:内核基础、线程管理

设备和驱动:I/O口设备模型     

示例程序:内核例程(线程)、外设例程(LED)

一、学习的重点内容

1.1、内核

1.1.1、内核基础

  • 线程调度、时钟管理、线程间同步、线程间通讯、内存管理、I/O口设备管理
  • 启动流程:

  • 内存分布:​​​​​​​​​​​​​​
  • 自动初始化机制:

  • 内核对象模型

  • 内核配置文件

配置主要是通过修改工程目录下的 rtconfig.h 文件来进行,用户可以通过打开 / 关闭该文件中的宏定义来对代码进行条件编译,最终达到系统配置和裁剪的目的 

1.1.2、线程管理

线程属性:栈、状态、优先级、时间片、入口函数、错误码、状态转换

动态线程、静态线程、时间片轮转调度、调度器钩子函数

钩子函数中最好不要调用API

1.2、 设备和驱动

1.2.1、I/O口设备模型

 1.2.2、PIN设备

芯片上的引脚分为4类:电源、时钟、控制、 I/O。

I/O口主要的特点

  • 可编程中断:

  • I/O口输入输出模式可控

PIN设备管理接口​​​​​​​

  • 获取引脚编号:使用API、使用宏定义、查看驱动文件
  • 设置引脚模式:(上/下拉)输入、(开漏)输出
  • 设置引脚电平:PIN_LOW、PIN_HIGH
  • 读取引脚电平:
  • 绑定引脚中断回调函数:中断触发方式
  • 使能引脚中断:开启、关闭
  • 脱离引脚中断回调函数:

二、示例程序

2.1、外设例程——Led

控制要求:

通过PIN设备管理接口控制LED亮灭,学会创建线程,使用之前创建的简单BSP程序

硬件I/O口:

BEEP——PF8

LED0——PF9

LED1——PF10

KEY0——PE4

KEY1——PE3

KEY2——PE2

程序代码

/*
 * Copyright (c) 2022-7-27, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-7-27     	Qiao      first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <stdlib.h>

/* 
 *获取引脚编号:使用(RT)API、使用宏定义、查看驱动文件
 *这里采用使用宏定义
 */
#define BEEP  GET_PIN(F, 8)
#define LED0  GET_PIN(F, 9)
#define LED1  GET_PIN(F, 10)
#define KEY0  GET_PIN(E, 4)
#define KEY1  GET_PIN(E, 3)
#define KEY2  GET_PIN(E, 2)

/*
 *led线程控制块—rtdef.h
 */
#define LED_PRIORITY    RT_THREAD_PRIORITY_MAX / 3   //rtconfig.h最大优先级
#define LED_STACK_SIZE  512
#define LED_TIMESLICE   50

static rt_thread_t led_tid = RT_NULL;

int main(void)
{
    int count = 1;
    /* set LED0 pin mode to output */
    rt_pin_mode(LED0, PIN_MODE_OUTPUT);

    while (count++)
    {
        rt_pin_write(LED0, PIN_HIGH);
//				rt_kprintf("thread run count ");
        rt_thread_mdelay(500);
        rt_pin_write(LED0, PIN_LOW);
        rt_thread_mdelay(500);
    }

    return RT_EOK;
}  

static void led_entry(void *parameter)
{
		rt_pin_mode(LED1, PIN_MODE_OUTPUT);
		for(int i=1; i<20; i++)
		{
				/* 点亮LED1 */
				rt_pin_write(LED1, PIN_LOW);
				rt_kprintf("thread run count : %d\r\n", i);
			  rt_thread_mdelay(1000);			
        /* 熄灭LED1 */
        rt_pin_write(LED1, PIN_HIGH);
        rt_kprintf("led off!\r\n");
        rt_thread_mdelay(1000);				
		}	
}

static int led_thread_create(void)
{
		rt_err_t ret = RT_EOK;    //错误等级:无错误		
		led_tid = rt_thread_create("led",
																led_entry,
																RT_NULL,
																LED_STACK_SIZE,
																LED_PRIORITY - 1,
																LED_TIMESLICE);
		if(led_tid != RT_NULL)
		{
				rt_thread_startup(led_tid);
		}
		else
		{
				ret = RT_ERROR;
		}
		
		return ret;
}
INIT_APP_EXPORT(led_thread_create);

下载调试

使用ENV工具中的scons --target=mdk5,重新生成工程

观察LED灯的状态

发现会打印LED灯线程内的信息

PS可以查看线程,看到创建的led灯的线程

出现问题:

功能已实现,但是有问题,问题如下:

1、在不连接串口助手时:下载后可以自动启动

2、在打开串口助手时:在下载程序后必须重启才能运行程序

2.1、外设例程——PIN

程序

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 * Change Logs:
 * Date           Author       Notes
 * 2022-7-29     	Qiao         PIN
 * 建立GPIO口中断实验
 */

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>  
#include <led.h>

 /* 
 *获取引脚编号:使用(RT)API、使用宏定义、查看驱动文件
 *这里采用使用宏定义,必须添加<board.h>文件
 */
#define BEEP  GET_PIN(F, 8)
#define KEY0  GET_PIN(E, 4)
#define KEY1  GET_PIN(E, 3)
#define KEY2  GET_PIN(E, 2)


void beep_on(void *args)
{
    rt_kprintf("turn on beep!\n");
//    rt_pin_write(BEEP, PIN_HIGH);
		rt_pin_write(LED1, PIN_LOW);
}
void beep_off(void *args)
{
    rt_kprintf("turn off beep!\n");
//    rt_pin_write(BEEP, PIN_LOW);
	  rt_pin_write(LED1, PIN_HIGH);
}

static void pin_beep_irq(void)
{
		/* BEEP的I/O口配置 */
		rt_pin_mode(BEEP, PIN_MODE_OUTPUT);
		rt_pin_write(BEEP, PIN_LOW);
		/* 
		 * 验证对于操作逻辑简单的设备,可以不经过设备驱动框架层,
	   * 直接将设备注册到 I/O 设备管理器中
	   */
		rt_pin_mode(KEY0, PIN_MODE_INPUT_PULLUP);
    rt_pin_attach_irq(KEY0, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
		rt_pin_irq_enable(KEY0, PIN_IRQ_ENABLE);
		
	
		rt_pin_mode(KEY1, PIN_MODE_INPUT_PULLUP);
    rt_pin_attach_irq(KEY1, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL);
		rt_pin_irq_enable(KEY1, PIN_IRQ_ENABLE);	
}

INIT_APP_EXPORT(pin_beep_irq);

下载调试

使用ENV工具中的scons --target=mdk5,重新生成工程

可以使用外部输入中断控制beep和灯的亮灭

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RT-Linux(实时Linux)是一个基于Linux内核的实时操作系统,它提供了对实时性的支持。RT-Linux使用内核级线程来实现实时性,它可以在Linux内核和实时任务之间提供良好的交互。编写RT-Linux应用程序与编写普通的Linux应用程序类似,但需要特别注意一些实时性相关的问题。 在RT-Linux中,可以使用POSIX实时扩展(也称为RTAI)或Xenomai框架来编写实时应用程序。这些框架提供了运行实时任务所需的API和机制,并与Linux内核进行交互。 编写RT-Linux应用程序需要考虑以下几个方面: 1. 实时任务的调度:在RT-Linux中,需要为实时任务设置优先级,并使用适当的调度策略来确保实时任务按时执行。常用的调度策略包括FIFO(先进先出)和RR(循环调度)。 2. 中断处理:实时应用程序通常需要与硬件设备进行交互,因此需要处理硬件中断。在RT-Linux中,可以使用中断处理程序来处理硬件中断,并采取适当的措施来保证实时性。 3. 实时性分析:为了确保实时任务能够按时执行,需要进行实时性分析。这包括确定任务的执行时间和响应时间,并根据实时性要求进行优化。 4. 同步和通信:在多个实时任务之间进行同步和通信是很常见的需求。RT-Linux提供了各种同步和通信机制,如信号量、互斥锁和消息队列等,可以用于实现任务之间的数据共享和通信。 总之,RT-Linux编程需要对实时性要求有一定的了解,并使用适当的编程技术和工具来满足这些要求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐者-桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值