[嵌入式系统-37]:龙芯1B 开发学习套件 -6-协处理器CP0之CPU异常处理与外部中断控制器的中断处理

目录

一、CP0概述

1.1 CP0概述

1.2 龙芯异常exception与中断interrupt的区别

二、CPU协处理器的异常处理

三、外部中断与外部中断控制器

3.1 外部中断源

3.2 如何配置外部中断源

3.3 外部中断的中断向量表

3.2.1 软件中断向量表结构定义:ls1b_irq.c

3.2.2 软件中断向量表定义:ls1b_irq.c和ls1b_irq.h

3.3.3 默认的中断处理或中断服务程序:ls1b_irq.c

3.3.4 中断向量表的初始化

3.3.5 安装用户自定义的中断服务程序的安装与移除


一、CP0概述

1.1 CP0概述

龙芯1B协处理器CP0(Coprocessor 0)是龙芯处理器(Loongson)中的一个重要组成部分,主要用于管理处理器的系统级行为和状态信息。CP0是一个与主处理器CPU紧密集成的协处理器,它的功能主要有以下几个方面:

  1. 地址转换和虚拟存储管理MMU:CP0可以实现物理地址的解析和转换,支持虚拟存储管理,使得应用程序可以像访问物理内存一样方便地访问虚拟内存区域。

  2. 异常和中断处理(本文要深入讨论的部分):CP0是处理器内部异常exception和外部中断Interrupt处理的核心,它存储了异常和中断向量表、错误状态码等信息,并负责中断的响应和异常处理程序的执行

  3. 性能计数器和性能分析:CP0中还包括可编程的性能计数器和时钟戳记寄存器,可以用于对程序的性能分析和调优,并支持操作系统的性能监控功能。

  4. 系统控制寄存器:CP0中还包含了一些系统级别的控制寄存器,可以用于修改处理器的运行状态,如设置缓存策略、开/关写缓冲等。

总之,龙芯1B协处理器CP0是Loongson处理器的重要组成部分,它管理和控制处理器中的系统级行为和状态信息,为操作系统和应用程序提供了重要的支持和保障。

1.2 龙芯异常exception与中断interrupt的区别

龙芯处理器中的异常(exception)和中断(interrupt)在概念上是有区别的,它们分别代表了不同类型的事件和处理机制:

  1. 异常(Exception):异常是指在程序执行过程中出现的一种非正常事件,通常是由指令执行时产生的,可以看作是处理器内部的问题。异常可以是因为错误的操作码、内存访问冲突、算术错误等原因导致的,需要处理器暂停当前指令的执行并执行相应的异常处理程序。异常通常由处理器本身或者处理器内部逻辑主动触发,它跳转到异常处理程序,处理完异常后再恢复到正常指令流程。

  2. 中断(Interrupt):中断是指来自外部设备的一种请求要求处理器暂停当前正在执行的程序,转而执行与中断相关的处理程序。中断是处理器响应外部事件的一种方式,可以是来自设备的信号或者时钟,需要处理器打断当前执行的指令流程,执行相应的中断服务程序,处理完中断后再返回到被中断的程序继续执行。

        在龙芯处理器中,异常和中断的区别在于触发原因和处理方式上:异常通常是由指令执行过程中的内部错误或意外情况引发,需要处理器内部去处理;而中断是由外部事件触发,需要处理器响应外部设备的请求。处理器在接收到异常或中断信号后,会根据具体情况执行相应的处理程序,保证系统的稳定运行和正确性。

二、CPU协处理器的异常处理

三、外部中断与外部中断控制器

3.1 外部中断源

龙芯1B SOC芯片内置简单、灵活的中断控制器

1B芯片的中断控制器除了管理 GPIO输入的中断信号外,中断控制器还处理内部设备引起的中断。所有的中断寄存器的位域安排相同,一个中断源对应其中一位

SOC的中断控制器共四个中断线输出连接到CPU模块,分别对应 INT0, INT1, INT2, INT3

SOC芯片中断控制器本身能够支持 64个内部中断和 64个 GPIO的中断,最大一共128个硬件外部中断源,这128个中断源分为四组,每组最大支持32个中断源,分别归组为:INT0, INT1, INT2, INT3。

其中 INT0和 INT1分别对应于 64个内部中断的前后 32位,INT2和 INT3对应于 64个外部 GPIO中断。但龙芯1B的实现过程中,并非所有的中断源都被使用,部分中断源是保留未使用,

具体中断源如下表所示: 

从上图可以看出:

(1)GPIO31、GPIO62、GPIO63都未使用,属于保留位,因此一个64-3=61个GPIO中断源。

(2)并非所有的INT0和INT1的外设中断都被使用上,实际上,龙芯1B SOC芯片,并没有那么多外设,因此,大量的位都是闲置的,属于保留为,未定义其行为。

3.2 如何配置外部中断源

3.3 外部中断的中断向量表

3.2.1 软件中断向量表结构定义:ls1b_irq.c

/* 中断向量表 */
typedef struct isr_tbl
{void (*handler)(int, void *);       // 中断句柄unsigned int arg;                   // 参数 
} isr_tbl_t;

3.2.2 软件中断向量表定义:ls1b_irq.c和ls1b_irq.h

定义龙芯1B实际支持的中断源(去除保留位)


/******************************************************************************
 * Interrupt Vector Numbers
 * MIPS_INTERRUPT_BASE should be 32 (0x20)
 ******************************************************************************/

/*
 * CP0 Cause ($12)  IP bit(15:8)=IP[7:0],

*       IP[1:0] is soft-interrupt
 *     Status($13)  IM bit(15:8) if mask interrupts
 *
 */
#define LS1B_IRQ_SW0            (MIPS_INTERRUPT_BASE + 0)   # 协处理器的软中断
#define LS1B_IRQ_SW1            (MIPS_INTERRUPT_BASE + 1)   # 协处理器的软中断
#define LS1B_IRQ0_REQ           (MIPS_INTERRUPT_BASE + 2)  # 协处理器的中断请求0
#define LS1B_IRQ1_REQ           (MIPS_INTERRUPT_BASE + 3)   # 协处理器的中断请求1
#define LS1B_IRQ2_REQ           (MIPS_INTERRUPT_BASE + 4)   # 协处理器的中断请求2
#define LS1B_IRQ3_REQ           (MIPS_INTERRUPT_BASE + 5)   # 协处理器的中断请求3
#define LS1B_IRQ_PERF           (MIPS_INTERRUPT_BASE + 6)   # 协处理器的性能统计中断
#define LS1B_IRQ_CNT            (MIPS_INTERRUPT_BASE + 7)    # 协处理器的计数或tick中断,操作系统调度使用

/*
 * Interrupt Control 0 Interrupts: 中断控制器0支持的外设中断数量:29个
 */
#define LS1B_IRQ0_BASE          (MIPS_INTERRUPT_BASE + 8)

#define LS1B_UART0_IRQ          (LS1B_IRQ0_BASE + 2)
#define LS1B_UART1_IRQ          (LS1B_IRQ0_BASE + 3)
#define LS1B_UART2_IRQ          (LS1B_IRQ0_BASE + 4)
#define LS1B_UART3_IRQ          (LS1B_IRQ0_BASE + 5)
#define LS1B_CAN0_IRQ           (LS1B_IRQ0_BASE + 6)
#define LS1B_CAN1_IRQ           (LS1B_IRQ0_BASE + 7)
#define LS1B_SPI0_IRQ           (LS1B_IRQ0_BASE + 8)
#define LS1B_SPI1_IRQ           (LS1B_IRQ0_BASE + 9)
#define LS1B_AC97_IRQ           (LS1B_IRQ0_BASE + 10)
#define LS1B_DMA0_IRQ           (LS1B_IRQ0_BASE + 13)
#define LS1B_DMA1_IRQ           (LS1B_IRQ0_BASE + 14)
#define LS1B_DMA2_IRQ           (LS1B_IRQ0_BASE + 15)
#define LS1B_PWM0_IRQ           (LS1B_IRQ0_BASE + 17)
#define LS1B_PWM1_IRQ           (LS1B_IRQ0_BASE + 18)
#define LS1B_PWM2_IRQ           (LS1B_IRQ0_BASE + 19)
#define LS1B_PWM3_IRQ           (LS1B_IRQ0_BASE + 20)
#define LS1B_RTC0_IRQ           (LS1B_IRQ0_BASE + 21)
#define LS1B_RTC1_IRQ           (LS1B_IRQ0_BASE + 22)
#define LS1B_RTC2_IRQ           (LS1B_IRQ0_BASE + 23)
#define LS1B_TOY0_IRQ           (LS1B_IRQ0_BASE + 24)
#define LS1B_TOY1_IRQ           (LS1B_IRQ0_BASE + 25)
#define LS1B_TOY2_IRQ           (LS1B_IRQ0_BASE + 26)
#define LS1B_RTC_IRQ            (LS1B_IRQ0_BASE + 27)
#define LS1B_TOY_IRQ            (LS1B_IRQ0_BASE + 28)
#define LS1B_UART4_IRQ          (LS1B_IRQ0_BASE + 29)
#define LS1B_UART5_IRQ          (LS1B_IRQ0_BASE + 30)

/*
 * Interrupt Control 1 interrupts:中断控制器1支持的外设中断:4个
 */
#define LS1B_IRQ1_BASE          (MIPS_INTERRUPT_BASE + 40)

#define LS1B_EHCI_IRQ           (LS1B_IRQ1_BASE + 0)
#define LS1B_OHCI_IRQ           (LS1B_IRQ1_BASE + 1)
#define LS1B_GMAC0_IRQ          (LS1B_IRQ1_BASE + 2)
#define LS1B_GMAC1_IRQ          (LS1B_IRQ1_BASE + 3)

/*
 * Interrupt Control 2 interrupts (GPIO):中断控制器2支持的GPIO中断数:31个
 */
#define LS1B_IRQ2_BASE          (MIPS_INTERRUPT_BASE + 72)

#define LS1B_GPIO0_IRQ          (LS1B_IRQ2_BASE + 0)
#define LS1B_GPIO1_IRQ          (LS1B_IRQ2_BASE + 1)
#define LS1B_GPIO2_IRQ          (LS1B_IRQ2_BASE + 2)
#define LS1B_GPIO3_IRQ          (LS1B_IRQ2_BASE + 3)
#define LS1B_GPIO4_IRQ          (LS1B_IRQ2_BASE + 4)
#define LS1B_GPIO5_IRQ          (LS1B_IRQ2_BASE + 5)
#define LS1B_GPIO6_IRQ          (LS1B_IRQ2_BASE + 6)
#define LS1B_GPIO7_IRQ          (LS1B_IRQ2_BASE + 7)
#define LS1B_GPIO8_IRQ          (LS1B_IRQ2_BASE + 8)
#define LS1B_GPIO9_IRQ          (LS1B_IRQ2_BASE + 9)
#define LS1B_GPIO10_IRQ         (LS1B_IRQ2_BASE + 10)
#define LS1B_GPIO11_IRQ         (LS1B_IRQ2_BASE + 11)
#define LS1B_GPIO12_IRQ         (LS1B_IRQ2_BASE + 12)
#define LS1B_GPIO13_IRQ         (LS1B_IRQ2_BASE + 13)
#define LS1B_GPIO14_IRQ         (LS1B_IRQ2_BASE + 14)
#define LS1B_GPIO15_IRQ         (LS1B_IRQ2_BASE + 15)
#define LS1B_GPIO16_IRQ         (LS1B_IRQ2_BASE + 16)
#define LS1B_GPIO17_IRQ         (LS1B_IRQ2_BASE + 17)
#define LS1B_GPIO18_IRQ         (LS1B_IRQ2_BASE + 18)
#define LS1B_GPIO19_IRQ         (LS1B_IRQ2_BASE + 19)
#define LS1B_GPIO20_IRQ         (LS1B_IRQ2_BASE + 20)
#define LS1B_GPIO21_IRQ         (LS1B_IRQ2_BASE + 21)
#define LS1B_GPIO22_IRQ         (LS1B_IRQ2_BASE + 22)
#define LS1B_GPIO23_IRQ         (LS1B_IRQ2_BASE + 23)
#define LS1B_GPIO24_IRQ         (LS1B_IRQ2_BASE + 24)
#define LS1B_GPIO25_IRQ         (LS1B_IRQ2_BASE + 25)
#define LS1B_GPIO26_IRQ         (LS1B_IRQ2_BASE + 26)
#define LS1B_GPIO27_IRQ         (LS1B_IRQ2_BASE + 27)
#define LS1B_GPIO28_IRQ         (LS1B_IRQ2_BASE + 28)
#define LS1B_GPIO29_IRQ         (LS1B_IRQ2_BASE + 29)
#define LS1B_GPIO30_IRQ         (LS1B_IRQ2_BASE + 30)
 
/*
 * Interrupt Control 3 source bit (GPIO):中断控制器3支持的GPIO中断数:30个。
 */
#define LS1B_IRQ3_BASE          (MIPS_INTERRUPT_BASE + 104)

#define LS1B_GPIO32_IRQ         (LS1B_IRQ3_BASE + 0)
#define LS1B_GPIO33_IRQ         (LS1B_IRQ3_BASE + 1)
#define LS1B_GPIO34_IRQ         (LS1B_IRQ3_BASE + 2)
#define LS1B_GPIO35_IRQ         (LS1B_IRQ3_BASE + 3)
#define LS1B_GPIO36_IRQ         (LS1B_IRQ3_BASE + 4)
#define LS1B_GPIO37_IRQ         (LS1B_IRQ3_BASE + 5)
#define LS1B_GPIO38_IRQ         (LS1B_IRQ3_BASE + 6)
#define LS1B_GPIO39_IRQ         (LS1B_IRQ3_BASE + 7)
#define LS1B_GPIO40_IRQ         (LS1B_IRQ3_BASE + 8)
#define LS1B_GPIO41_IRQ         (LS1B_IRQ3_BASE + 9)
#define LS1B_GPIO42_IRQ         (LS1B_IRQ3_BASE + 10)
#define LS1B_GPIO43_IRQ         (LS1B_IRQ3_BASE + 11)
#define LS1B_GPIO44_IRQ         (LS1B_IRQ3_BASE + 12)
#define LS1B_GPIO45_IRQ         (LS1B_IRQ3_BASE + 13)
#define LS1B_GPIO46_IRQ         (LS1B_IRQ3_BASE + 14)
#define LS1B_GPIO47_IRQ         (LS1B_IRQ3_BASE + 15)
#define LS1B_GPIO48_IRQ         (LS1B_IRQ3_BASE + 16)
#define LS1B_GPIO49_IRQ         (LS1B_IRQ3_BASE + 17)
#define LS1B_GPIO50_IRQ         (LS1B_IRQ3_BASE + 18)
#define LS1B_GPIO51_IRQ         (LS1B_IRQ3_BASE + 19)
#define LS1B_GPIO52_IRQ         (LS1B_IRQ3_BASE + 20)
#define LS1B_GPIO53_IRQ         (LS1B_IRQ3_BASE + 21)
#define LS1B_GPIO54_IRQ         (LS1B_IRQ3_BASE + 22)
#define LS1B_GPIO55_IRQ         (LS1B_IRQ3_BASE + 23)
#define LS1B_GPIO56_IRQ         (LS1B_IRQ3_BASE + 24)
#define LS1B_GPIO57_IRQ         (LS1B_IRQ3_BASE + 25)
#define LS1B_GPIO58_IRQ         (LS1B_IRQ3_BASE + 26)
#define LS1B_GPIO59_IRQ         (LS1B_IRQ3_BASE + 27)
#define LS1B_GPIO60_IRQ         (LS1B_IRQ3_BASE + 28)
#define LS1B_GPIO61_IRQ         (LS1B_IRQ3_BASE + 29)

#define LS1B_MAXIMUM_VECTORS        (LS1B_GPIO61_IRQ+1)

#define BSP_INTERRUPT_VECTOR_MIN    0
#define BSP_INTERRUPT_VECTOR_MAX    LS1B_MAXIMUM_VECTORS

备注:中断向量表中一共支持8 + 29 + 4 + 31 + 30 = 8 + 33 + 61 = 102个中断。

中断向量表:

static isr_tbl_t isr_table[BSP_INTERRUPT_VECTOR_MAX];

3.3.3 默认的中断处理或中断服务程序:ls1b_irq.c

/** 默认中断 */
static void mips_default_isr(int vector, void *arg)
{unsigned int sr;unsigned int cause;mips_get_sr(sr);mips_get_cause(cause);printf("Unhandled isr exception: vector 0x%02x, cause 0x%08X, sr 0x%08X\n",vector, cause, sr);while (1);
}

3.3.4 中断向量表的初始化

/* * 初始化*/ 
void mips_init_isr_table(void)
{unsigned int i;for (i=0; i<BSP_INTERRUPT_VECTOR_MAX; i++) {isr_table[i].handler = mips_default_isr;isr_table[i].arg = i;}
}

使用默认的中断服务程序mips_default_isr初始化中断向量表。

3.3.5 安装用户自定义的中断服务程序的安装与移除

void ls1x_install_irq_handler(int vector, void (*isr)(int, void *), void *arg)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = isr;isr_table[vector].arg = (unsigned int)arg;mips_interrupt_enable();}
}void ls1x_remove_irq_handler(int vector)
{if ((vector >= 0) && (vector < BSP_INTERRUPT_VECTOR_MAX)){mips_interrupt_disable();isr_table[vector].handler = mips_default_isr;isr_table[vector].arg = vector;mips_interrupt_enable();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/270552.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将ppt里的视频导出来

将ppt的后缀从pptx改为zip 找到【media】里面有存放图片和音频以及视频&#xff0c;看文件名后缀可以找到&#xff0c;mp4的即为视频&#xff0c;直接复制粘贴到桌面即可。 关闭压缩软件把ppt后缀改回&#xff0c;不影响ppt正常使用。

C++对象模型剖析(六)一一Data语义学(三)

Data 语义学&#xff08;三&#xff09; “继承” 与 Data member 上期的这个继承的模块我们还剩下一个虚拟继承&#xff08;virtual inheritance&#xff09;没有讲&#xff0c;现在我们就来看看吧。 虚拟继承&#xff08;Virtual Inheritance&#xff09; 虚拟继承本质就是…

leetcode 3.6

Leetcode hot 100 一.矩阵1.旋转图像 二.链表1. 相交链表2.反转链表3.回文链表4.环形链表5.环形链表 II 一.矩阵 1.旋转图像 旋转图像 观察规律可得&#xff1a; matrix[i][j] 最终会被交换到 matrix [j][n−i−1]位置&#xff0c;最初思路是直接上三角交换&#xff0c;但是会…

SpringCloud(20)之Skywalking Agent原理剖析

一、Agent原理剖析 使用Skywalking的时候&#xff0c;并没有修改程序中任何一行 Java 代码&#xff0c;这里便使用到了 Java Agent 技术&#xff0c;我 们接下来展开对Java Agent 技术的学习。 1.1 Java Agent Java Agent 是从 JDK1.5 开始引入的&#xff0c;算是一个比较老的…

深入理解 Vuex:从基础到应用场景

前言 在之前的文章中&#xff0c;我们已经对 Vue.js 有了一定的了解。今天我们要对Vue官方的状态共享管理器Vuex进行详细讲解&#xff0c;将其基本吃透&#xff0c;目标是面对大多数业务需求&#xff1b; 一、介绍 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用…

C++——string类

前言&#xff1a;哈喽小伙伴们&#xff0c;从这篇文章开始我们将进行若干个C中的重要的类容器的学习。本篇文章将讲解第一个类容器——string。 目录 一.什么是string类 二.string类常见接口 1.string类对象的常见构造 2.string类对象的容量操作 3. string类对象的访问及遍…

代码随想录第51天|● 300.最长递增子序列 ● 674. 最长连续递增序列 ● 718. 最长重复子数组

文章目录 ● 300.最长递增子序列思路代码&#xff1a; ● 674. 最长连续递增序列思路&#xff1a;代码&#xff1a; ● 718. 最长重复子数组思路&#xff1a;代码一&#xff1a;dp二维数组代码二&#xff1a;滚动数组 ● 300.最长递增子序列 思路 dp[i]表示i之前包括i的以nums…

从 Language Model 到 Chat Application:对话接口的设计与实现

作者&#xff1a;网隐 RTP-LLM 是阿里巴巴大模型预测团队开发的大模型推理加速引擎&#xff0c;作为一个高性能的大模型推理解决方案&#xff0c;它已被广泛应用于阿里内部。本文从对话接口的设计出发&#xff0c;介绍了业界常见方案&#xff0c;并分享了 RTP-LLM 团队在此场景…

MySQL下实现纯SQL语句的递归查询

需求 有一个部门表&#xff0c;部门表中有一个字段用于定义它的父部门&#xff1b; 在实际业务中有一个『部门中心』的业务&#xff1b; 比如采购单&#xff0c;我们需要显示本部门及子部门的采购单显示出来。 结构 数据如下&#xff1a; 实现方式如下&#xff1a; WITH RECUR…

Vue点击切换组件颜色

例如我有一个这样的组件&#xff0c;我希望在点击组件之后由蓝色变成橙色 先把原来的代码附上(简化掉了叉号&#xff09;&#xff1a; <div v-for"(item, index) in words" :key"index" class"scrollbar-demo-item"><span>{{ item …

Unreal 5打开Windows虚拟键盘的权限问题

可以通过以下代码打开Windows虚拟键盘 void UMouseSimulatorBPLibrary::ShowVirtualKeyboard() {TCHAR* OskPath L"C:\\Program Files\\Common Files\\microsoft shared\\ink\\TabTip.exe";if (!FPaths::FileExists(OskPath)){OskPath L"C:\\windows\\system…

比较 2 名无人机驾驶员:借助分析飞得更高

近年来&#xff0c;越来越多的政府和执法机构使用无人机从空中鸟瞰。为了高效执行任务&#xff0c;无人机必须能够快速机动到预定目标。快速机动使它们能够在复杂的环境中航行&#xff0c;并高效地完成任务。成为认证的无人机驾驶员的要求因国家/地区而异&#xff0c;但都要求您…

数字人民币钱包(二)

文章目录 前言一 什么是数字人民币钱包&#xff1f;二 怎么开通数字人民币钱包&#xff1f;三 数字人民币钱包有哪些&#xff1f;四 数字人民币钱包升级 前言 上篇文章梳理了什么是数字人民币&#xff0c;及其特征和相关概念&#xff0c;这篇文章来整理下数字人民币钱包。数字人…

Redis线程模型解析

引言 Redis是一个高性能的键值对&#xff08;key-value&#xff09;内存数据库&#xff0c;以其卓越的读写速度和灵活的数据类型而广受欢迎。在Redis 6.0之前的版本中&#xff0c;它采用的是一种独特的单线程模型来处理客户端的请求。尽管单线程在概念上似乎限制了其扩展性和并…

【笔记】Android ServiceStateTracker 网络状态变化逻辑及SPN更新影响

业务简介 在网络状态变化的时候&#xff08;数据或WiFi&#xff09;&#xff0c;会更新SPN。 基于Android U的代码分析。 分类&#xff1a;SPN Data_Dic-的博客-CSDN博客 功能逻辑 状态说明 飞行模式下注册上WFC的话&#xff0c;注册状态MD上报 regState: NOT_REG_MT_NOT…

【注意】宽泛负载!

放大器输出摆幅会限制可测量的负载电流范围。例如&#xff0c;从 100mV 至 4.9V 的输出摆幅相当于频程约 15 倍的线性输出范围。那么如果要测量 30 倍频程的负载电流&#xff0c;应该怎么做&#xff1f;调节增益&#xff01; 在TIE2E 论坛上为客户提供支持时&#xff0c;我遇到…

CUDA学习笔记05:卷积(sobel)

参考资料 CUDA编程模型系列四(卷积 or sobel边缘检测)_哔哩哔哩_bilibili 强推 ! ! 代码片段 主函数: #include <stdio.h> #include <iostream> #include <math.h> #include <opencv2/opencv.hpp> #include <opencv2/core.hpp> #include &l…

Java设计模式:建造者模式之经典与流式的三种实现(四)

本文将深入探讨Java中建造者模式的两种实现方式&#xff1a;经典建造者与流式建造者。建造者模式是一种创建型设计模式&#xff0c;它允许你构建复杂对象的步骤分解&#xff0c;使得对象的创建过程更加清晰和灵活。我们将通过示例代码详细解释这两种实现方式&#xff0c;并分析…

十:套接字和标准I/O,以及分离I/O流

1 标准I/O函数的优点 C语言标准IO整理 1.1 标准I/O函数的两个优点 标准I/O函数具有良好的移植性。 标准I/O函数可以利用缓冲提高性能 从图中可以看出&#xff0c;使用标准I/O函数传输数据时&#xff0c;经过两个缓冲。例如&#xff0c;使用fputs函数传输字符串 “Hello” 时…

安卓游戏开发之图形渲染技术优劣分析

一、引言 随着移动设备的普及和性能的提升&#xff0c;安卓游戏开发已经成为一个热门领域。在安卓游戏开发中&#xff0c;图形渲染技术是关键的一环。本文将对安卓游戏开发中常用的图形渲染技术进行分析&#xff0c;比较它们的优劣&#xff0c;并探讨它们在不同应用场景下的适用…