基于亚博K210开发板——串口中断以及开启双核任务

2023-11-02

开发板

亚博K210开发板
在这里插入图片描述

实验目的

本实验配置串口通信,并开启接收中断,主程序开启双核,核心0任务实现LED灯交替亮灭并打印数据,核心1任务实现实时读取串口数据,当达到一定条件开启或RGB交替亮灭并打印对应数据

实验准备

硬件原理图

Tpye-C 接口连接 K210 的 IO4 和 IO5 接口,其中 IO4 为 K210 芯片的接收引脚,IO5
为 K210 芯片的发送引脚。
在这里插入图片描述

软件对应SDK

对应的头文件 uart.h

通用 UART 为 UART1、UART2 和 UART3,支持异步通信(RS232 和 RS485 和IRDA,通信速率可达到 5Mbps。UART 支持 CTS 和 RTS 信号的硬件管理以及软件流控(XON 和 XOFF)。3 个接口均可被 DMA 访问或者 CPU 直接访问。每次传输数据为 8 字节,支持异步时钟,可单独配置数据时钟,实现全双工模式,保证两个时钟域中数据同步。

uart 默认为 RS232 模式,也可以配置为软件可编程式 RS485 模式。

用 THRE 中断模式来提升串口性能。当 THRE 模式和 FIFO 模式被选择之后,如果 FIFO 中少于阈值便触发 THRE 中断。

uart.h接口函数

• uart_init:初始化 uart
• uart_config (0.6.0 后不再支持,请使用 uart_configure)
• uart_configure:配置串口的波特率等
• uart_send_data:通过串口发送数据
• uart_send_data_dma:通过 dma 通道发送数据
• uart_send_data_dma_irq:UART 通过 DMA 发送数据,并注册 DMA 接收完成中断函数,仅单次中断
• uart_receive_data:读取串口数据
• uart_receive_data_dma:串口通过 dma 接收数据
• uart_receive_data_dma_irq:UART 通过 DMA 接收数据,并注册 DMA 接收完成中断函数,仅单次中断
• uart_irq_register:注册串口中断函数
• uart_irq_deregister:注销串口中断
• uart_set_work_mode:设置 uart 工作模式。有四种模式:普通 uart、红外、RS485 全双工、RS485 半双工。
• uart_set_rede_polarity:设置 RS485 re de 管脚有效时的极性。
• uart_set_rede_enable:使能 re de 管脚,主要用在 rs485 全双工模式,re 和 de 必须手动控制。单双工模式不用调用该函数,单双工时硬件会自动设置 re de。
• uart_set_tat:配置 re de 互相的时间间隔,这个与外部的 485 模块有关。
• uart_set_det:设置 de 有效无效转换时数据的时间延时。
• uart_debug_init:配置调试串口。系统默认使用 UART3 做为调试串口,调用该函数用户可以自定义使用哪个 uart 做为调试串口,如果使用 UART1 或 UART2 需要使用 fpioa 设置管脚。因此调试脚不局限于 fpioa4、5
• uart_handle_data_dma:UART 通过 DMA 传输数据

高速通用异步收发传输器(UARTHS)对应的头文件 uarths.h

高速 UART 为 UARTHS(UART0),通讯速率可达到 5Mbps,8 字节发送和接收FIFO,可编程式 THRE 中断,不支持硬件流控制或者其他调制解调器控制信号,或同步串行数据转换器。系统的 printf 调试函数默认就是调用 UARTHS 串口来实现发送数据的。

uarths.h接口函数

• uarths_init:初始化 UARTHS,系统默认波特率为 115200 8bit 1 位停止位无检验位。因为uarths 时钟源为 PLL0,在设置 PLL0 后需要重新调用该函数设置波特率,否则会打印乱码。
• uarths_config:设置 UARTHS 的参数。默认 8bit 数据,无校验位。
• uarths_receive_data:通过 UARTHS 读取数据。
• uarths_send_data:通过 UART 发送数据。
• uarths_set_irq:设置 UARTHS 中断回调函数。
• uarths_get_interrupt_mode:获取 UARTHS 的中断类型。接收、发送或接收发送同时中断。
• uarths_set_interrupt_cnt : 设 置 UARTHS 中断时的 FIFO 深度。 当中断类UARTHS_SEND_RECEIVE,发送接收 FIFO 中断深度均为 cnt;

板级对应的头文件 bsp.h

bsp.h 头文件是与平台相关的通用函数,核之间锁的相关操作。提供获取当前运行程序的 CPU 核编号的接口以及启动第二个核的入口。
K210 是双核 CPU,那么什么是双核 CPU 呢?双核 CPU 是在一个 CPU 中拥有两个一样功能的处理器芯片,从而提高计算能力。K210 的核心 0 和核心 1 都可以单独工作,系统默认使用核心 0,如果需要使用核心 1 需要手动开启核心 1 的服务。

bsp.h接口函数

• register_core1:向核心 1 注册函数,并启动核心 1
• current_coreid:获取当前 CPU 的核心编号(0/1)
• read_cycle:获取 CPU 开机至今的时钟数。可以用使用这个函数精准的确定程序运行时钟。可以配合 sysctl_clock_get_freq(SYSCTL_CLOCK_CPU)计算运行的时间。
• spinlock_lock:自旋锁,不可嵌套,不建议在中断使用,中断中可以使用 spinlock_trylock。
• spinlock_unlock:自旋锁解锁。
• spinlock_trylock:获取自旋锁,成功获取锁会返回 0,失败返回-1。
• corelock_lock:获取核间锁,核之间互斥的锁,同核内该锁会嵌套,只有异核之间会阻塞。不建议在中断使用该函数,中断中可以使用 corelock_trylock。
• corelock_trylock:获取核间锁,同核时锁会嵌套,异核时非阻塞。成功获取锁会返回 0,失败返回-1。
• corelock_unlock:核间锁解锁。
• sys_register_putchar:注册系统输出回调函数,printf 时会调用该函数。系统默认使用UART3,如果需要修改 UART 则调用 uart_debug_init 函数。
• sys_register_getchar:注册系统输入回调函数,scanf 时会调用该函数。系统默认使用UART3,如果需要修改 UART 则调用 uart_debug_init 函数。
• sys_stdin_flush:清理 stdin 缓存。
• get_free_heap_size:获取空闲内存大小。
• printk:打印核心调试信息,用户不必理会。

实验代码

bsp_led_rgb.h

#ifndef __BSP_LED_RGB_H_
#define __BSP_LED_RGB_H_
/*****************************HEAR-FILE************************************/
#include "fpioa.h"
#include "gpiohs.h"
#include "gpio.h"
#include "fpioa.h"
#include "sleep.h"

/*****************************HARDWARE-PIN*********************************/

#define IS_HIGH_GPIO  1


// 硬件IO口,与原理图对应

//led
#define PIN_LED_0             (0)
#define PIN_LED_1             (17)

//rgb
#define PIN_RGB_R                 (6)
#define PIN_RGB_G                 (7)
#define PIN_RGB_B                 (8)

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应

//led
#define LED0_GPIONUM          (3)
#define LED1_GPIONUM          (4)

//rgb
#define RGB_R_GPIONUM          (0)
#define RGB_G_GPIONUM          (1)
#define RGB_B_GPIONUM          (2)

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口

//led
#define FUNC_LED0             (FUNC_GPIO0 + LED0_GPIONUM)
#define FUNC_LED1             (FUNC_GPIO0 + LED1_GPIONUM)

//rgb
#if  IS_HIGH_GPIO
#define FUNC_RGB_R             (FUNC_GPIOHS0 + RGB_R_GPIONUM)
#define FUNC_RGB_G             (FUNC_GPIOHS0 + RGB_G_GPIONUM)
#define FUNC_RGB_B             (FUNC_GPIOHS0 + RGB_B_GPIONUM)
#else
#define FUNC_RGB_R             (FUNC_GPIO0 + RGB_R_GPIONUM)
#define FUNC_RGB_G             (FUNC_GPIO0 + RGB_G_GPIONUM)
#define FUNC_RGB_B             (FUNC_GPIO0 + RGB_B_GPIONUM)
#endif

void rgbInit(void);
void ledInit(void);
void rgbClose(void);
void ledClose(void);
void ledFlash(int ms);
void rgbFlash(int ms);


#endif /* __BSP_LED_RGB_H_ */

bsp_led_rgb.c

#include "bsp_led_rgb.h"

void hardware_init(void)
{

    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);

    fpioa_set_function(PIN_RGB_R, FUNC_RGB_R);
    fpioa_set_function(PIN_RGB_G, FUNC_RGB_G);
    fpioa_set_function(PIN_RGB_B, FUNC_RGB_B);
}

void rgbInit()
{
    gpio_init();
    //硬件初始化,绑定GPIO口
    fpioa_set_function(PIN_RGB_R, FUNC_RGB_R);
    fpioa_set_function(PIN_RGB_G, FUNC_RGB_G);
    fpioa_set_function(PIN_RGB_B, FUNC_RGB_B);

    //设置模式为输出
#if  IS_HIGH_GPIO     
    gpiohs_set_drive_mode(RGB_R_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(RGB_G_GPIONUM, GPIO_DM_OUTPUT);
    gpiohs_set_drive_mode(RGB_B_GPIONUM, GPIO_DM_OUTPUT);
#else
    gpio_set_drive_mode(RGB_R_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(RGB_G_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(RGB_B_GPIONUM, GPIO_DM_OUTPUT);
 #endif 
}


void ledInit()
{
    gpio_init();
    //硬件初始化,绑定GPIO口
    fpioa_set_function(PIN_LED_0, FUNC_LED0);
    fpioa_set_function(PIN_LED_1, FUNC_LED1);
    //设置LED0和LED1的GPIO模式为输出
    gpio_set_drive_mode(LED0_GPIONUM, GPIO_DM_OUTPUT);
    gpio_set_drive_mode(LED1_GPIONUM, GPIO_DM_OUTPUT);

}

void rgbClose()
{
#if  IS_HIGH_GPIO    
    gpiohs_set_pin(RGB_R_GPIONUM, GPIO_PV_HIGH);
    gpiohs_set_pin(RGB_G_GPIONUM, GPIO_PV_HIGH);
    gpiohs_set_pin(RGB_B_GPIONUM, GPIO_PV_HIGH);
#else
    gpio_set_pin(RGB_R_GPIONUM, GPIO_PV_HIGH);
    gpio_set_pin(RGB_G_GPIONUM, GPIO_PV_HIGH);
    gpio_set_pin(RGB_B_GPIONUM, GPIO_PV_HIGH);
#endif    
}


void ledClose()
{
    // 先关闭LED0和LED1
    gpio_pin_value_t value = GPIO_PV_HIGH;
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value);

}

void ledFlash(int ms)
{
    static gpio_pin_value_t value = GPIO_PV_HIGH;
    msleep(ms);
    gpio_set_pin(LED0_GPIONUM, value);
    gpio_set_pin(LED1_GPIONUM, value = !value);
}

void rgbFlash(int ms)
{
    static uint8_t rgbIndex = 0;
    rgbIndex %= 3; 
    rgbClose();
    gpiohs_set_pin(rgbIndex, GPIO_PV_LOW);
    rgbIndex++;
    msleep(ms);
}
bsp_usart.h

```c
#ifndef __BSP_USART_H
#define __BSP_USART_H
/*****************************HEAR-FILE************************************/
#include "fpioa.h"
#include "uart.h"
#include "sysctl.h"

/*****************************HARDWARE-PIN*********************************/
// 硬件IO口,与原理图对应
#define PIN_UART_USB_RX       (4)
#define PIN_UART_USB_TX       (5)

/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
#define UART_USB_NUM           UART_DEVICE_3

/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_UART_USB_RX       (FUNC_UART1_RX + UART_USB_NUM * 2)
#define FUNC_UART_USB_TX       (FUNC_UART1_TX + UART_USB_NUM * 2)



typedef struct UsartRecData
{
    uint8_t reclen;
    char recData;
    /* data */
}UsartRecData;
 



void usartInit(int uartNum,int baudRrate);
void uartSendData(int uartNum,char *data,int size);
bool waitForMessage(int uartNum);

extern UsartRecData usartData;

#endif /* _PIN_CONFIG_H_ */

bsa_usart.c

#include "bsp_usart.h"
#include "string.h"

UsartRecData usartData;


void uart_hardware_init(void)
{

    fpioa_set_function(PIN_UART_USB_RX, FUNC_UART_USB_RX);
    fpioa_set_function(PIN_UART_USB_TX, FUNC_UART_USB_TX);

}

int uartCallBack(void *ctx)
{       
    char temp;
    while(uart_receive_data(UART_USB_NUM,&usartData.recData,1)){
       
    }
    
    return 0;
}

void usartInit(int uartNum,int baudRrate)
{

    uart_hardware_init();
     // 初始化串口,设置波特率为115200
    uart_init(uartNum);
    // 设置 uart 工作模式
    uart_set_work_mode (UART_USB_NUM , UART_NORMAL);
    // 初始化串口
    uart_configure(UART_USB_NUM,baudRrate,UART_BITWIDTH_8BIT, UART_STOP_1, UART_PARITY_NONE);
     // 初始化外部中断 
    uart_irq_register(UART_USB_NUM, UART_RECEIVE, uartCallBack,NULL,2);
    // 设置接收中断 触发 FIFO 深度
    uart_set_receive_trigger(UART_USB_NUM, UART_RECEIVE_FIFO_1);
    

}

void uartSendData(int uartNum,char *data,int size)
{

    uart_send_data(UART_USB_NUM, data, size);
  
}

bool waitForMessage(int uartNum)
{
    char rec = 0;
    while(uart_receive_data(uartNum,&rec,1)){
        if(1 == rec){
            return true;
        }else{
            return false;
        }
    }
}
    

mian.c

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "bsp.h"
#include "bsp_led_rgb.h"
#include "bsp_usart.h"


int core1TaskRun(void *ctx)
{
    char core1Log1[40] = "rgb state is opened\r\n";
    char core1Log2[40] = "wait for open rgb\r\n";

     while(1){
        if(usartData.recData == 1){
            rgbFlash(300);
            uartSendData(UART_USB_NUM,core1Log1,sizeof(core1Log1));
        }else{
           sleep(1);
           uartSendData(UART_USB_NUM,core1Log2,sizeof(core1Log2));
        }
        
    }
}

void core1Init()
{
    register_core1(core1TaskRun,NULL);
}


int main(void)
{

    char core0Log[50] = "this is core0 task!\r\n";
    
    plic_init();
    sysctl_enable_irq();
    ledInit();
    rgbInit();

    usartInit(UART_USB_NUM,115200);

    core1Init();

    while (1){
       
        ledFlash(1000);
        uartSendData(UART_USB_NUM,core0Log,sizeof(core0Log));       
    }
    
        
    
    return 0;
}

实验结果

编译烧录之后LED0和LED1会依次交替亮灭,串口助手上会打印任务0信息,当在串口助手上发送字符1时,任务1会开启RGB灯的交替亮灭并打印信息,若发送字符0后,任务1会关闭rgb的交替亮灭。

效果

发送 0 后(rgb停止闪烁)
发送字符0后
发送 1 后(rgb开始闪烁)
发送字符1后

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于亚博K210开发板——串口中断以及开启双核任务 的相关文章

  • antd Form表单给标题头添加图标或一些其他样式

    给表单标题旁添加一个Icon图标并设置一个提示信息 如果就一个icon图标和提示信息可以直接使用Form Item中的tooltip属性 tooltip title Tooltip with customize icon icon
  • 奇迹去掉400级限制的详细修改

    奇迹去掉400级限制的详细修改 我是艾西 今天分享的是奇迹mu如何去掉400级等级限制修改 对于懂技术的小伙伴可以作为参考 更多关于奇迹技术问题可以爱特我 下面我们直接进行操作 直接在scf common ini文件里设置 Common S
  • Python批量管理主机

    18 1 paramiko paramiko模块是基于Python实现的SSH远程安全连接 用于SSH远程执行命令 文件传输等功能 默认Python没有 需要手动安装 pip install paramiko 如安装失败 可以尝试yum安装
  • ReactNative 学习笔记Component 和createClass区别

    Component 更改默认state 中的成员变量 需要调用构造器 getInitialState函数是不会被调用的 pre class javascript class SearchPage extends Component cons
  • js正则匹配不能为空

  • termux怎么生成木马_Termux入侵安卓指南

    apt update 更新源 apt upgrade 升级软件包 pkg install vim curl wget git python nmap 安装基本工具 PS 如果有弹出选项 输入y然后回车即可 安装MSF 进入termux 逐步
  • 【华为OD机试真题2023B卷 JAVA&JS】统计射击比赛成绩

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 统计射击比赛成绩 时间限制 1秒 内存限制 65536K 语言限制 不限 题目描述 给定一个射击比赛成绩单 包含多个选手若干次射击的成绩分数 请对每个选手按其最高3个分数之和进行降序排

随机推荐

  • 运算放大器使用的六个经验

    文章目录 1 注意输入电压是否超限 2 不要在运放输出直接并接电容 3 不要在放大电路反馈回路并接电容 4 注意运放的输出摆幅 5 注意反馈回路的Layout 6 要重视电源滤波 2016 2017 小威 家 豫ICP备17018141号
  • Java web期末

    一 简答题 1 Servlet的体系结构 1 Servlet接口 规定了必须由Servlet类实现并且由Servlet引擎识别和管理的方法集 2 GenericServlet抽象类 提供了除service 方法之外其他有关Servlet生命
  • cpu的MMU

    MMU 内存管理单元 用于完成虚拟内存和物理内存的映射 位于CPU内部 我们知道 程序文件一般放在硬盘上 当把程序运行起来时 程序被放入内存中 通过内存放入cache 通过cache进入cpu 下图中预取器就是负责从cache取出指令 然后
  • H5 移动端 时间选择器

    本选择器 自己填充内容 li的文本 只是做了一个大概的样式 其它的有需要者自己去改
  • Ubuntu22.04密码忘记怎么办 Ubuntu重置root密码方法

    在Ubuntu 22 04 或其他更高版本上不小心忘记root或其他账户的密码怎么办 首先uname r查看当前系统正在使用的内核版本 记下来 前提 是你的本地电脑 有物理访问权限 其他如远程登录的不适用这套改密方法 通过以下步骤 无需输入
  • response.text和 response.content的区别:

    1 response content这个是直接从网络上面抓取的数据 没有经过任何解码 所以是一个 bytes类型 其实在硬盘上和在网络上传输的字符串都是 bytes类型 2 response text 这个是 requests 将 resp
  • 【数据结构】JavaScript栈实现

    栈是一种常见的数据结构 常用于app页面堆栈 括号匹配校验 中缀表达式转换 图的深度优先遍历等场景 本文参考java jdk源码 在JavaScript中实现这种数据结构 一 栈的定义 栈是限定仅在表尾进行插入和删除操作的线性表 允许插入和
  • 浅谈招标投标活动中质疑及投诉问题

    http www docin com p 608989637 html
  • 【研一小白的白话理解】pytorch-CycleGAN-and-pix2pix

    pytorch CycleGAN and pix2pix 博客简述 项目整体理解 GAN Cycle GAN CGAN DCGAN Pix2pix Pix2pix简介 Auto encoder U net Pix2pix结构 项目结构 文件
  • 贪心—To Fill or Not to fill

    0x00 题目地址 To Fill or Not to Fill 牛客网 nowcoder com 0x01 分析 符合最优子结构 无后效性 重复子问题三个条件 因此可以使用贪心求解 先按照距离排序 将加油站排成一条线 算法每一步的思路 1
  • vue全局组件注册、局部组件注册、全局方法注册

    一 全局组件注册有两种方法 1 在main js文件中引入组件 import UserData from components UserData vue vue component UserData UserData 就可以直接在vue文件
  • STM32F103学习笔记(六

    实验六 七 独立和窗口看门狗实验 看门狗 单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环 看门狗电路就是为了避免这种情况的发生 看门狗的作用就是在一定时间内 通过定时计数器实现 没有接收喂狗信号 表示 MCU 已经挂了 便实现处
  • js基础篇

    JavaScript语法 字面量 也叫直接量 就是程序中直接使用的 是变量后面的值 变量就是声明一个未知可变的量 变量声明符合unicode编码所有变量符合utf 8的编码都可以 标识符命名标准 1 必须是字母 数字 开头 2 以驼峰命名规
  • 手把手教你实操部署FISCO BCOS联盟链(附每一步代码)

    感谢FISCO BCOS社区贡献者 刘海锋 贡献此文 贡献无大小 分享永留传 谢谢你们的每一次贡献 最后 如果你也想成为Mr FISCO BCOS 一起干出点改变世界 到老了可以跟孙辈们吹吹牛的事 欢迎加入社区 经过尝试 我按以下操作顺序执
  • Spring框架远程命令执行复现(CVE-2022-22965)

    2022年3月30日 Spring框架曝出RCE 0day漏洞 国家信息安全漏洞共享平台 CNVD 已收录了Spring框架远程命令执行漏洞 CNVD 2022 23942 考虑到Spring框架的广泛应用 漏洞被评级为危险 通过该漏洞可写
  • 压测工具:jmeter

    衡量当前系统应对高并发的量 压测工具不能少 1 下载jmeter 进入官网 2 使用jmeter 进入bin目录 或者双击 2 1 添加测试计划 线程组的基本属性 2 2取样器 取样器是我们真正进行测试的内容 比如http ftp jdbc
  • 【项目经验】elementui--table表格自定义表头及bug

    一 思路 首先我们肯定得循环表头 我们原生js封装的表格的实现原理就是这样 其次我们要把自己循环的label显示出来 对应的prop也要和表格数据相对应 用div标签循环都会出现错误 div里面套column 大家不要踩坑 第一项会跑到最后
  • 23个可以免费学习编程的网站

    英文 https medium com javascript in plain english 22 ways to learn coding for free in 2021 87a9c171132c 翻译 web前端开发公众号 ID w
  • Vue2.0选中当前鼠标移入移除加样式

    本人写的小程序 功能还在完善中 欢迎扫一扫提出宝贵意见 效果如gif动态图所示 1 通过v for遍历数组 HTML代码 1
  • 基于亚博K210开发板——串口中断以及开启双核任务

    文章目录 开发板 实验目的 实验准备 硬件原理图 软件对应SDK 对应的头文件 uart h uart h接口函数 高速通用异步收发传输器 UARTHS 对应的头文件 uarths h uarths h接口函数 板级对应的头文件 bsp h