C#中TCP通讯的实现方法

C#中TCP通讯的实现方法
C#中TCP通讯的实现方法

C#中TCP通讯的实现方法

Socket就是套接字,它是网络编程中最常用遇到的概念和工具。在TCP/IP网络中,传送和接收数据就会经常使用到Socket,由于使用Socket能够在网络上处理复杂数据,所以在各种网络应用程序中,涉及到数据传送和接收,一般都会使用Socket,可见要掌握网络编程,精通Socket是非常重要。由于Socket本身的复杂性,决定了掌握它是比较困难的。Visual C#是微软公司推荐的开发.Net平台应用程序的主要语言,随着.Net 的深入人心,目前很多有远见的公司都把以前的软件转向了.Net平台。掌握网络编程始终是学习一种开发语言的重点,这一点对于Visual C#也同样如此。Visual C#实现网络功能其关键也是掌握托管Socket的使用方法。本文就来详细介绍Visual C#中利用托管Socket实现网络数据传送和接收的实现方法及其注意事项。

一.简介Socket:

Socket诞生于上个世纪80年代初,美国政府的高级研究工程机构(ARPA)给加利福尼亚大学伯克力(Berkeley)分校提供了资金,委托他们在UNIX操作系统下实现TCP/IP协议的开发接口。于是研发人员就为TCP/IP网络通信开发了一个API(应用程序接口)。这个API称为Socket接口(套接字)。所以有时候说,Socket是TCP/IP上的API。

到了上个世纪90年代,当时的一些网络开发商,包括现在地Sun和Microsoft公司等,共同制定了一套WINDOWS下的网络编程接口,即WindowsSockets规范,简称WinSock规范。WinSock规范是一套开放的、支持多种协议的Windows下的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun 等公司的大力支持下,已成为Windows网络编程的事实上的标准。目前,WinSock规范主要有1.1版和2.0版。两者的最重要区别是1.1版只支持TCP/IP协议,而2.0版可以支持多协议。2.0版有良好的向后兼容性,任何使用1.1版的源代码,二进制文件,应用程序都可以不加修改地在2.0规范下使用。

可见Socket接口其实是TCP/IP网络的API接口函数,Socket数据传输其实就是一种特殊的I/O。常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。

二.Visual C#中操作Socket:

虽然Visual C#可以使用NetworkStream来传送、接收数据,但NetworkStream在使用中有很大的局限性,利用NetworkStream只能传送和接收字符类型的数据,如果要传送的是一些复杂的数据如:二进制数据等,它就显得能力有限了。但使用NetworkStream在处理自身可操作数据时,的确要比Socket方便许多。Socket(套接字)几乎可以处理任何在网络中需要传输的数据类型。

我们知道Visual C#和Visual C++的区别之一,就是Visual C#没有属于自己的类库,而Visual C++却是有的,Visual C#使用的类库是.Net框架为所有开发.Net平台程序语言提供的一个公用的类库——.Net FrameWork SDK。Visual C#主要网络功能主要使用.Net FrameWork SDK中的提供的二个命名空间“https://www.360docs.net/doc/0314774721.html,.Sockets”和“https://www.360docs.net/doc/0314774721.html,”。而实现Socket使用的是命名空间“https://www.360docs.net/doc/0314774721.html,.Sockets”中的Socket类。Visual C#通过创建Socket类的实例来实现Socket的托管版本。在Visual C#中创建完Socket实例后,可以通过此Socket实例的Bind方法绑定到网络中指定的终结点,也可以通过其Connect方法向指定的终结点建立的连接。连接创建完毕,就可以使用其Send 或SendTo方法将数据发送到Socket;同样使用其的Receive或ReceiveFrom方法从Socket 中读取数据。在Socket使用完毕后,请使用其的Shutdown方法禁用Socket,并使用Close 方法关闭Socket。表01和表02是Socket类中的常用属性和方法及其简要说明。

表01:Socket类的常用属性及其说明

表02:Socket类的常用方法及其说明

其中“BeginAccept”和“EndAccept”、“BeginConnect”和“EndConnect”、

“BeginReceive”和“EndReceive”、“BeginReceiveFrom”和“EndReceiveFrom”、

“BeginSend”和“EndSend”、“BeginSendTo”和“EndSendTo”是六组异步方法,

其功能分别相当于“Accept”、“Connect”、“Receive”、“ReceiveFrom”、

“Send”和“SendTo”方法。

下面就通过一个具体的示例,来介绍Visual C#中如何通过托管Socket实现数据传送和接收的具体方法。

本文示例其实是由二部分组成,也可以看成是客户机程序和服务器程序。客户机程序功能是通过

Socket向服务器程序创建连接,并在连接完成后,向服务器发送数据;服务器程序通过侦听端口,接受网络的Socket的连接请求,并在连接完成后,接收从客户机发送来的数据,并显示出来。下面首先来介绍Visual C#通过托管Socket实现客户机程序的具体方法。

三.本文介绍程序的设计、调试、运行的软件环境:

(1).微软公司视窗2000服务器版

(2).Visual Studio .Net正式版,.Net FrameWork SDK版本号3705

四.利用Socket来传送数据:

Visual C#在使用Socket传送数据时要注意下列问题的解决方法:

1.创建Socket实例,使用此实例创建和远程终结点的连接,并判断连接是否成功建立。

2.发送数据到Socket,实现数据传送。

这些问题解决方法都可以在下面介绍代码中找到相对应的部分。由于下面的代码都有详细的注解,

这里就不详细介绍。下面是利用Socket传送数据的具体实现步骤:

1.启动Visual Studio .Net,并新建一个Visual C#项目,

项目名称为【利用Socket来发送数据】。

2.把Visual Studio .Net的当前窗口切换到【Form1.cs(设计)】窗口,

并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应操作:

二个TextBox组件,一个用以输入远程主机的IP地址,一个用以输入往远程主机传送的数据。

一个StausBar组件,用以显示程序的运行状况。

一个ListBox组件,用以显示程序已传送的数据信息。

三个Label组件。

二个Button组件,名称分别为button1、button2,并在这二个组件被拖入窗体后,分别

双击它们,则系统会在Form1.cs文件中自动产生这二个组件的Click事件对应的处理代码。

3.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。

4.以下面代码替代系统产生的InitializeComponent过程:

至此【利用Sokcet来传送数据】项目设计后的界面就完成了,具体如图01所示:

图01:【利用Sokcet来传送数据】项目的设计界面

5.在Form1.cs文件的开头的导入命名空间的代码区,添加下列代码,

下列代码是导入下面程序中使用到的类所在的命名空间:

6.在Form1的class代码区中加入下列代码,下列代码的作用是定义全局变量和创建全局使用的实例:

7.用下列代码替换Form1.cs中的button1组件的Click事件对应的处理代码,下列代码的功能是初始化以创建的Socket实例,并向远程终结点提出连接申请,并判断连接是否建立:

8.用下列代码替换Form1.cs中button2组件的Click事件对应的处理代码,下列代码的功能是通过已建立的连接,利用Socket来传送数据到远程主机。

9.用下列代码替换Form1.cs中“清理所有正在使用的资源。”对应的代码。其作用是在程序退出之前,判断连接状态,如果没有退出,则向远程主机发送控制码“STOP”,用以断开和远程主机的连接,并清除相应资源。所谓控制码就是网络应用程序之间彼此交换信息的一种自定义码子,应用程序通过接收、发送这些码子,可以明确网络应用程序的行为,保证执行的一致性,也就少了很多出错的几率。控制码在编写远程控制方面的应用程序时使用比较多。之所以要有这一步是因为在用Visual C#编写网络应用程序的时候,很多人都遇到这样的情况。当程序退出后,通过Windows的“资源管理器”看到的是进程数目并没有减少。这是因为程序中使用的线程可能并没有有效退出。虽然Thread类中提供了“Abort”方法用以中止进程,但并不能够保证成功退出。因为进程中使用的某些资源并没有回收。可见在某些情况下,依靠Visual C#的垃圾回收器也不能保证完全的回收资源,这时就需要我们自己手动回收资源的。下面就是手动回收资源采用的一种方法:

至此在上述步骤都正确执行后,【利用Socket来传送数据】就全部完成了。

五.利用Socket来接收数据:

Visual C#在使用Socket来介绍网络传送来的数据时,要解决下面三个问题,也是完成Visual C#使用Socket来接收数据的三个步骤:

1.侦听网络,接受网络连接申请;

2..获得用以接收数据的Socket实例,并以此实例接收远程主机发送来的数据;

3.根据远程主机发送来的控制码,断开网络连接,并清除资源。

此处接收接收数据,是上面介绍的【利用Socket来传送数据】传送来的数据。

下面就是利用Socket来接收数据的具体实现步骤:

1.启动Viisual Studio .Net,并新建一个Visual C#项目,项目名称为【利用Socket来接收数据】。

2.把Visual Studio .Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应操作:

一个ListBox组件,用以显示接收的数据。

一个StausBar组件,用以显示接收端程序的运行状况。

一个Button组件,名称为button1,并在这个组件被拖入窗体后,双击它,则系统会在Form1.cs 文件中自动产生其Click事件对应的处理代码。

3.【解决方案资源管理器】窗口中,双击Form1.cs文件,进入Form1.cs文件的编辑界面。

4.以下面代码替代系统产生的InitializeComponent过程::

private void InitializeComponent ( )

{

this.button1 = new System.Windows.Forms.Button ( ) ;

this.listBox1 = new System.Windows.Forms.ListBox ( ) ;

this.statusBar1 = new System.Windows.Forms.StatusBar ( ) ;

this.SuspendLayout ( ) ;

this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat ;

this.button1.Location = new System.Drawing.Point ( 96 , 16 ) ;

https://www.360docs.net/doc/0314774721.html, = "button1" ;

this.button1.Size = new System.Drawing.Size ( 80 , 34 ) ;

this.button1.TabIndex = 0 ;

this.button1.Text = "监听" ;

this.button1.Click += new System.EventHandler ( this.button1_Click ) ; this.listBox1.ItemHeight = 12 ;

this.listBox1.Location = new System.Drawing.Point ( 16 , 68 ) ;

https://www.360docs.net/doc/0314774721.html, = "listBox1" ;

this.listBox1.Size = new System.Drawing.Size ( 258 , 172 ) ;

this.listBox1.TabIndex = 1 ;

this.statusBar1.Location = new System.Drawing.Point ( 0 , 251 ) ; https://www.360docs.net/doc/0314774721.html, = "statusBar1" ;

this.statusBar1.Size = new System.Drawing.Size ( 292 , 22 ) ;

this.statusBar1.TabIndex = 2 ;

this.statusBar1.Text = "无连接" ;

this.AutoScaleBaseSize = new System.Drawing.Size ( 6 , 14 ) ;

this.ClientSize = new System.Drawing.Size ( 292 , 273 ) ;

this.Controls.AddRange ( new System.Windows.Forms.Control[] {

this.statusBar1 ,

this.listBox1 ,

this.button1} ) ;

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle ;

this.MaximizeBox = false ;

https://www.360docs.net/doc/0314774721.html, = "Form1" ;

this.Text = "利用Socket来接收数据" ;

this.ResumeLayout ( false ) ;

}

至此【利用Socket来接收数据】项目设计后的界面就完成了,具体如图02所示:

图02:【利用Socket来接收数据】项目的设计界面

5.把Visual Studio .Net的当前窗口切换到Form1.cs的代码编辑窗口,并在Form1.cs文件的开头,用下列导入命名空间代码替代系统缺省的导入命名空间代码。

using System ;

using System.Drawing ;

using System.Collections ;

using https://www.360docs.net/doc/0314774721.html,ponentModel ;

using System.Windows.Forms ;

using System.Data ;

using https://www.360docs.net/doc/0314774721.html,.Sockets ;

//使用到TcpListen类

using https://www.360docs.net/doc/0314774721.html, ;

using System.Threading ;

//使用到线程

7.在Form1.cs中的Main函数之后,添加下列代码,下列代码的作用是定义过程“Listen”,此过程的功能是监听“8000”端口号,接收网络中连接请求,建立连接,并获取接收数据时使用的Socket实例,并以Socket实例来接收客户机程序发送来的数据。并根据客户机发送

举例典型的任务间及ISR与任务间进行同步和通信的应用场景,说明何时应采用哪种机制。

嵌入式低功耗8位微控制器的设计的读书报告 这篇文章设计实现了一款嵌入式低功耗8位微控制器,采用了类精减指令集计算机(RISC)指令集、哈佛双总线体系和两级四段流水线结构。重点研究了微控制器的功耗分布,并从系统级、寄存器传输级(RTL)和逻辑级三个级别进行了功耗的优化。 一、体系结构设计与优化 文中采用了一种类精减指令集计算机(reduced instruction set computer,RISC)的指令体系,除了具有指令简洁、每条指令所需要的周期数(cycles per instruction,CPI)较小等优势外,还具有以下特点:①区别于Load/Store体系,采用了Register-Memory体系,运算指令可以直接访问存储器,这有效地提高了代码密度;②所有指令均等长,大大简化了解码和控制电路的设计,具有较低的功耗和结构尺寸。 二、低功耗实现技术 1、系统级的低功耗设计 包括休眠模式的设计、时钟网络的管理、存储器的低功耗设计三个方面。 休眠模式的功耗是决定芯片整体平均功耗的重要部分。执行SLEEP指令后,处理器会进入休眠工作状态,当发生外部中断或是看门狗溢出时,会从休眠模式返回,继续执行休眠指令之后的下一条指令。休眠模式设计存在的一个问题是,当微控制单元(micro control unit,MCU)进入休眠状态,主时钟已经关闭,当产生中断时,MCU如何从休眠状态中恢复。笔者设计了主时钟切换和同步电路。片内存在2种振荡电路,包括外接晶振的起振电路和极低频的RC振荡回路,分别为处理器提供主时钟频率和保持时钟频率。当处理器工作在休眠模式时,时钟网络并没有完全关闭,而是将主时钟切换成频率很低的RC振荡信号,在部分模块中仍然保留时钟,当出现中断时,能够及时将状态字置位,切换到主时钟,MCU继续取指工作。 时钟网络是数字系统中翻转率最高、驱动能力最大的网络,具有较大的电容和负载,通过关闭闲置模块的时钟,可以有效降低时钟网络的功耗。时钟网络管理模块根据指令译码器的输出和休眠模式来决定全局的功耗策略。 现代SOC系统中一般都要集成存储器,降低存储器的功耗对整个芯片的功耗优化会起很大作用。笔者对片内SRAM采用了分页访问和块寻址技术来降低功耗。 2、RTL级的低功耗设计 在系统级的优化中,主要从系统时序和模块的工作状态入手。而在寄存器传输级设计中,低功耗设计的主要手段是降低模块内部的组合电路和寄存器单元的规模和翻转频率。 3、逻辑综合的低功耗设计

进程同步与通信作业习题与答案

第三章 一.选择题(50题) 1.以下_B__操作系统中的技术是用来解决进程同步的。 A.管道 B.管程 C.通道 2.以下_B__不是操作系统的进程通信手段。 A.管道 B.原语 C.套接字 D.文件映射 3.如果有3个进程共享同一程序段,而且每次最多允许两个进程进入该程序段,则信号量的初值应设置为_B__。 4.设有4个进程共享一个资源,如果每次只允许一个进程使用该资源,则用P、V操作管理时信号量S的可能取值是_C__。 ,2,1,0,-1 ,1,0,-1,-2 C. 1,0,-1,-2,-3 ,3,2,1,0 5.下面有关进程的描述,是正确的__A__。 A.进程执行的相对速度不能由进程自己来控制 B.进程利用信号量的P、V 操作可以交换大量的信息 C.并发进程在访问共享资源时,不可能出现与时间有关的错误 、V操作不是原语操作 6.信号灯可以用来实现进程之间的_B__。 A.调度 B.同步与互斥 C.同步 D.互斥 7.对于两个并发进程都想进入临界区,设互斥信号量为S,若某时S=0,表示_B__。 A.没有进程进入临界区 B.有1个进程进入了临界区 C. 有2个进程进入了临界区 D. 有1个进程进入了临界区并且另一个进程正等待进入 8. 信箱通信是一种_B__方式 A.直接通信 B.间接通信 C.低级通信 D.信号量 9.以下关于临界区的说法,是正确的_C__。

A.对于临界区,最重要的是判断哪个进程先进入 B.若进程A已进入临界区,而进程B的优先级高于进程A,则进程B可以 打断进程A而自己进入临界区 C. 信号量的初值非负,在其上只能做PV操作 D.两个互斥进程在临界区内,对共享变量的操作是相同的 10. 并发是指_C__。 A.可平行执行的进程 B.可先后执行的进程 C.可同时执行的进程 D.不可中断的进程 11. 临界区是_C__。 A.一个缓冲区 B.一段数据区 C.一段程序 D.栈 12.进程在处理机上执行,它们的关系是_C__。 A.进程之间无关,系统是封闭的 B.进程之间相互依赖相互制约 C.进程之间可能有关,也可能无关 D.以上都不对 13. 在消息缓冲通信中,消息队列是一种__A__资源。 A.临界 B.共享 C.永久 D.可剥夺 14. 以下关于P、V操作的描述正确的是__D_。 A.机器指令 B. 系统调用 C.高级通信原语 D.低级通信原语 15.当对信号量进行V源语操作之后,_C__。 A.当S<0,进程继续执行 B.当S>0,要唤醒一个就绪进程 C. 当S<= 0,要唤醒一个阻塞进程 D. 当S<=0,要唤醒一个就绪 16.对临界区的正确论述是__D_。 A.临界区是指进程中用于实现进程互斥的那段代码 B. 临界区是指进程中用于实现进程同步的那段代码 C. 临界区是指进程中用于实现进程通信的那段代码 D. 临界区是指进程中访问临界资源的那段代码 17. __A__不是进程之间的通信方式。 A.过程调用 B.消息传递 C.共享存储器 D.信箱通信 18. 同步是指进程之间逻辑上的__A__关系。

实验2 uCOS-II任务间通讯和同步实验

嵌入式实时操作系统 实验报告1 实验名称:uC/OS-II任务间通讯和同步实验姓名: 班级:信科10-4班 学号:

uC/OS-II任务间通讯和同步实验 一、实验目的 1、掌握uC/OS-II操作系统下使用信号量解决任务之间的同步问题; 2、掌握uC/OS-II操作系统下任务间通讯的方法。 二、实验内容 1、使用信号量实现任务间同步(Eg2工程) 2、使用邮箱实现任务之间的通讯(Eg3工程) 三、基础知识 uC/OS-II任务之间的通讯与同步方式 1、利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断 2、利用函数OSSchedLock()和OSSchekUnlock()对μC/OS-II中的任务调度函数上锁和开锁 3、信号量 4、邮箱 5、队列 uC/OS-II中使用信号量进行任务之间同步 1、通过调用OSSemCreate()建立信号量 2、通过调用OSSemPost()函数发送一个信号量 3、通过调用OSSemPend()函数等待一个信号量 OSSemCreate 1、Sem1 = OSSemCreate(0); 2、参数为信号量的初始计数值赋值。该初始值为0到65,535之间的一个数。 3、如果信号量是用来表示一个或者多个事件的发生,那么该信号量的初始值应设为0。 4、如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1(例如,把它当作二 值信号量使用)。 5、如果该信号量是用来表示允许任务访问n个相同的资源,那么该初始值显然应该是n,并把 该信号量作为一个可计数的信号量使用。 OSSemPost和OSSemPend 1、如果信号量当前是可用的(信号量的计数值大于0),将信号量的计数值减1,然后函数将“无 错”错误代码返回给它的调用函数。如果信号量的计数值为0,而OSSemPend()函数又不是由中断服务子程序调用的,则调用OSSemPend()函数的任务要进入睡眠状态,等待另一个任务(或者中断服务子程序)发出该信号量。 两个任务之间的同步的实现 1、创建两个信号量Sem1和Sem2,信号量Sem2初始为可用状态,而信号量Sem1初始为不可 用状态。 Sem1 = OSSemCreate(0); Sem2 = OSSemCreate(1); uC/OS-II中使用邮箱实现任务之间的通讯 1、邮箱可使一个任务或者中断服务子程序向另一个任务发送一个指针型的变量 2、通过调用OSMboxCreate()函数来创建邮箱,并指定指针的初始值 3、如果用户用邮箱来共享某些资源,那么就要初始化该邮箱为一个非NULL的指针 4、通过OSMboxPost()函数发送一个消息到邮箱 5、通过OSMboxPend()函数等待一个邮箱中的消息,如果邮箱中没有可用的消息,OSMboxPend() 的调用任务就被挂起,直到邮箱中有了消息或者等待超时。

ucos II 任务通信与同步

任务的同步与一个通信初解 操作系统就像就像一个好的家长,控制着资源的公平分配 应用程序中的各个任务,必须通过彼此之间的有效合作,才能完成一项大规模的工作。因为这些任务在运行时,经常需要相互无冲突地访问一个共享资源,或者需要相互支持和 依赖,甚至有时候还需要互相加以必要的制约,才能保证任务的顺利进行。因此操作系统 必须具有对任务运行进行协调的能力,从而使任务之间可以无冲突,流畅的同步运行,而 不致导致灾难性的后果。 这与人们依靠通信来相互沟通,从而使人际关系和谐,工作顺利的做法是一样的,计算机系统依靠任务间的良好通信来保证任务与任务的同步。 任何为任务所占用的实体都可以称为资源。资源可以是输入输出设备,比如打印机,键 盘显示器,资源也可以是一个变量,一个结构或者是一个数组。 1任务的同步和事件 嵌入式系统中的各个任务是为同一个大的任务服务的子任务,他们不可避免的要共同使 用一些资源,并且在处理一些需要多个任务共同协同来完成的工作时,还需要相互的支持和限制。因此,对一个完善的多任务操作系统来说,系统必须具有完备的同步和通信机制任务的同步: 为了实现各个任务之间的合作和无冲突的运行,在各个任务之间必须建立一些制约关系。其中一种制约关系叫做直接制约关系,另一种制约关系叫做间接制约关系 直接制约关系来自任务的合作:例如,有任务A和任务B两个任务,他们需要通过访 问同一个数据缓冲区合作完成一项工作,任务A负责向缓冲区写入数据,任务B负责向缓 冲区读取该数据。显然,当任务A还未向缓冲区写入数据时(缓冲区为空时),任务B因 不能从缓冲区得到有效地数据而应处于等待状态;只有等任务A向缓冲区写入了数据之后,才应该通知任务B去读取数据。相反,当缓冲区的数据还未被任务B读取时(缓冲区为满时),任务A就不能向缓冲区写入新的数据而应该处于等待状态;只有当任务B自缓冲区读取数据后,才应该通知任务A写入数据。显然,如果这两个任务不能如此协调工作,将势必造成严重的后果。 间接制约关系源于对资源的共享:例如:任务A和任务B共享一台打印机,如果系统已经把打印机分配给了任务A,则任务B因不能获得打印机的使用权而应该处于等待状态; 只有当任务A把打印机释放后,系统才能唤醒任务B使其获得打印机的使用权。如果这两 个系统不这样做,那么也会造成严重的后果。

实验二uCOS-II任务间通讯和同步实验

实验二uC/OS任务间通讯和同步实验 一、实验目的: 1)掌握uC/OS-II操作系统下使用信号量解决任务之间的同步问题; 2)掌握uC/OS-II操作系统下任务间通讯的方法。 二、实验内容: 1)uC/OS任务间通讯和同步实验,建立一个工程,应用程序含两个任务,一个任务不断显示跑马灯,另外一个任务不断显示数码管 2)使用信号量实现任务间同步(Eg2工程) 3)使用邮箱实现任务之间的通讯(Eg3工程) 三、程序清单: 1)eg2程序清单: */ #include "Includes.h" /* uC/OS interface */ #include "option.h" #include "2410lib.h" #include "uhal.h" char*s; INT8U y=0; /* 任务栈*/ OS_STK StackLED[STACKSIZE]= {0, }; // 任务LED任务栈 OS_STK StackSEG[STACKSIZE]= {0, }; // 任务SEG任务栈 /* 任务ID */ char IdLED = '1'; // 任务LED ID char IdSEG = '2'; // 任务SEG ID /* 任务处理函数*/ void TaskLED(void *Id); // 任务LED任务处理函数 void TaskSEG(void *Id); // 任务SEG任务处理函数 /* 信号量*/ OS_EVENT *Sem1; // 信号量Sem1 OS_EVENT *Sem2; // 信号量Sem2 /* * 跑马灯闪烁函数,调用一次,四个跑马灯由亮变灭或者由灭变亮 */ void User_LED_Blink(void) { static int led_status = 0; led_status += 1; if(led_status % 2 == 0)

相关文档
最新文档