文档库 最新最全的文档下载
当前位置:文档库 › uip学习笔记

uip学习笔记

uip学习笔记
uip学习笔记

uip_buf:定义如下u8_t uip_buf[UIP_BUFSIZE + 2];所有的数据处理都是通过处理它来完成的。比如接受的数据存储在这里,要发送的数据有会放在这里。

uip_len:uip_buf有用数据的字节

uip_appdata:uip_buf第一个可用字节的指针

uip_conn:总是指向当前连接的指针,定义:struct uip_conn *uip_conn;

下面是TCP连接的结构,用来区别不同的TCP连接,uip_tcp_appstate_t appstate是可以读写的且在实践应用中需要重定义,其他项read-only。

struct uip_conn {

uip_ipaddr_t ripaddr; /**< The IP address of the remote host. 远程主机IP地址*/

u16_t lport; /**< The local TCP port, in network byte order. 本地TCP端口号,网络字节顺序*/

u16_t rport; /**< The local remote TCP port, in network byte order.本地远程连接主机TCP端口号*/

u8_t rcv_nxt[4]; /**< The sequence number that we expect to

receive next. */

u8_t snd_nxt[4]; /**< The sequence number that was last sent by

us. */

u16_t len; /**< Length of the data that was previously sent. */

u16_t mss; /**< Current maximum segment size for the

connection. */

u16_t initialmss; /**< Initial maximum segment size for the

connection. */

u8_t sa; /**< Retransmission time-out calculation state

variable. */

u8_t sv; /**< Retransmission time-out calculation state

variable. */

u8_t rto; /**< Retransmission time-out. */

u8_t tcpstateflags; /**< TCP state and flags. */

u8_t timer; /**< The retransmission timer. */

u8_t nrtx; /**< The number of retransmissions for the last

segment sent. */

/** The application state. */

uip_tcp_appstate_t appstate;

};

uip的应用事件:

1.接收数据:uip_newdata()为真,即远程连接的主机有发送新数据。uip_appdata指针指向实际数据。数据的大小通过uIP函数uip_datalen()获得。在数据不是被缓冲后,应用程序必须立刻启动。

2.发送数据:应用程序通过使用uIP函数uip_send()发送数据。uip_send()函数采用两个参数;一个指针指向发送数据和数据的长度。如果应用程序为了产生要发送的实际数据需要RAM 空间,包缓存(通过uip_appdata指针指向)可以用于这方面。在一个时间里应用程序只能在连接中发送一块数据。因此不可以在每个应用程序启用中调用uip_send()超过一次;只有上

一次调用的数据将会发出后才可以。注意,调用uip_send()以后会改变某些全局变量,在应用函数返回前它不能被调用。

3.重发数据:uip_rexmit()为真,应用程序要重发上一次发出的数据。重发就好像原来那样发送,也就是通过uip_send()。

4.关闭连接:应用程序通过调用uip_close()关闭当前连接。这会导致连接干净地关闭。为了指出致命的错误,应用程序可以中止连接,调用uip_abort()函数完成这个工作。如果连接已经被远端关闭,uip_closed()为真。应用程序接着可以做一些必要的清理工作。

5.报告错误:有两个致命的错误可以发生在连接中,不是连接由远程主机中止,就是连接多次重发上一数据和被中止。uIP通过调用函数报告这些问题。应用程序使用两个测试函数uip_aborted()和uip _timedout() 去测试那些错误情况。

6.轮询:当连接空闲时,uIP在每一个时候周期性地轮询应用程序。应用程序使用测试函数uip_poll()去检查它是否被轮询过。

7.监听端口IP维持一个监听TCP端口列表。通过uip_listen()函数(在应用程序的初始化调用),一个新的监听端口打开。当一个连接请求在一个监听端口到达,uIP产生一个新的连接和调用应用程序函数。如果一个新连接产生,应用程序被调用,测试函数uip_connected()为真。

8. 打开连接在uIP里面通过使用uip_connect()函数打开一个新连接。这个函数打开一个新连接到指定的IP地址和端口,返回一个新连接的指针到uip_conn结构。如果没有空余的连接槽,函数返回空值。为了方便,函数uip_ipaddr()可以

用于将IP地址打包进两个单元16位数组里,通过uIP去代表IP地址。

例子:

void connect_example1_app(void) {

if(uip_connect(uip_conn->ripaddr, 8080) == NULL) {

uip_abort();

}

}

void connect_example2(void) {

u16_t ipaddr[2];

uip_ipaddr(ipaddr, 192,168,0,1);

uip_connect(ipaddr, 8080);

}

9.数据流控制过函数uip_stop()和uip_restart(),uIP提供存取TCP数据流的控制途径。设想一个应用程序下载数据到一个慢速设备,例如磁盘驱动器。如果磁盘驱动器的作业队列满了,应用程序不会准备从服务器接收更多的数据,直到队列排出空位。函数uip_stop()可以用于维护流控制和停止远程主机发送数据。当应用程序准备好接收更多数据,函数

uip_restart()用于告知远程终端再次发送数据。函数uip_stopped()可以用于检查当前连接是否停止。

有了以上的知识,相信编写uip应用程序就简单多了。

有三个函数在编写程序时调用:uip_init()(系统初始化时调用)、uip_input()(接受到数据时调用)、

uip_periodic()(隔一段时间调用,0.5s)

当用到特定的功能时还需相应的调用如下函数:uip_udp_periodic()、uip_arp_timer()

以上具体函数的用法在uip代码注释中有详解。

移植uip时要编写三个底层函数:void tapdev_init(void)(特定底层网络芯片的初始化函数)、unsigned int tapdev_read(void)、void tapdev_send(void)

编写main()循环时可以参照unix文件夹下的main.c。

#define UIP_APPCALL你的应用函数名(不是上面所说的main函数,main函数只是调用uip的接口函数)(uip协议栈会调用这个函数,按照你的要求处理数据)

所有uIP提供的函数

1.ARP地址解析协议:ARP协议映射了IP地址和以太网MAC物理地址,它在以太网上的TCP/IP操作是需要的。ARP在uIP里实现的是包含一个IP到MAC地址的映射。当一个IP包要在以太网上发出,查询ARP表,去找出包要发送去的MAC地址。如果在表里找不到IP地址,ARP请求包就会发出。请求包在网络里广播和请求给出IP地址的MAC地址。主机通过发出一个ARP回应,响应请求IP地址。当uIP给出一个ARP回应,更新ARP表。

为了节省储存器,一个IP地址的ARP请求覆盖发出的请求输出IP包。它是假定上层将重新发送那些被覆盖了的数据。

每十秒表更新一次,旧的条目会被丢弃。默认的ARP表条目生存时间是20分钟。

2.IP网际协议:uIP的IP层代码有两个职责:验证输入包的IP头的正确性和ICMP 和TCP 协议之间多路复用。IP层代码是非常简单的,由9条语句组成。事实上,uIP的IP层极大地简化了,它没有实现碎片和重组。

3.ICMP因特网信息控制协议:在uIP里,只有一种ICMP信息实现了: ICMP回响信息。ICMP回响信息常常用于ping程序里的检查主机是否在线。在uIP里,ICMP回响处理在一个非常简单的方式。ICMP类型字段的改变是从 \echo"类型到 \echo reply"类型,从而 ICMP调整校验和。其次,IP地址里的IP头交换,包发回到原先的发送者。

4.TCP传输控制协议:为了减少储存器的使用,uIP里的TCP没有实现发送和接收数据的调整窗口。输入的TCP段不会通过uIP缓存,但必须立即由应用程序处理。注意这不能避免应用程序自己缓冲数据。输出数据时,uIP不能在每个连接有超过一个未解决的TCP段。

连接状态

在uIP,每个TCP连接的完全态包含当地和远端的TCP端口编号,远程主机的IP地址,重发时间值,上一段重发的编号,和连接的段的最大尺寸。除此之外,每个连接也可以保持一些应用状态。三个序列号是,期望接收的下一个字节的序列号,上一发送段第一字节的序列号,下一发送字节的序列号。连接的状态由uip_conn结构表现,可以在图5看到。一个uip_conn结构数组用于在uIP里保持所有的连接。数组的大小等于同时的最大数量的连接,它在编译时间里设置。struct uip_conn {

u8_t tcpstateflags; /* TCP状态和标志. */

u16_t lport, rport; /*当地和远端端口. */

u16_t ripaddr[2]; /*同等远端的IP地址. */

u8_t rcv_nxt[4]; /* 我们期待接收的下一个序列号. */

u8_t snd_nxt[4]; /*上一个发送的序列号. */

u8_t ack_nxt[4]; /* 通过从远端的下一个应答去应答序列号. */

u8_t timer; /* 重发时间r. */

u8_t nrtx; /*计算特殊段的重发数量. */

u8_t mss; /* 连接的最大段大小. */

u8_t appstate[UIP_APPSTATE_SIZE];

};

图5: uip_conn 结构

输入处理

TCP输入处理和检验TCP校验和一起开始。如果校验和是对的,在当前活动的TCP连接之间,源、目的端口号和IP地址复用包。没有活动的连接符合输入包时,如果包不是一个监听端口的连接请求,包丢弃。如果包是一个关闭端口的请求,uIP 发一个 RST包回应。

如果发现了一个监听端口,uip_conn结构数组扫描任何一个非活动连接。如果发现一个,数组由新连接的端口号和IP地址填充。如果连接请求携带一个TCP MSS (最大段大小)选择,它会分析,再次检查当前最大段大小MSS去决定当前连接的MSS,前后者的最小值会被选择。最后,一个回应包发去确应开启连接。

应该将输入包送去一个已经活跃的连接,包的序列号和从远端主机来的期望的下一个序列号一起被检查 (uip_conn结构里的rcv_nxt 变量显示于图5)。如果序列号不是期望得到的下一个,包会被丢掉和发一个ACK去指出期望得到的下一个序列号。紧接着,检查输入包里的确应号,看看是否确应连接的所有输出数据。它做了后,应用程序会知道这个事实的。

当序列号和确应号被检测过,依靠当前TCP状态,包将会被不同地处理。如果连接在

SYN-RCVD状态和输入包确应先前发送的SYNACK包,连接将会输入ESTABLISHED状态,调用应用函数去通知已经完全连接。在连接的建立状态,如果有新数据由远端主机发送或者远端主机确应之前发送的数据,就调用应用函数。

当应用函数返回,TCP检查应用程序是否还有数据要发。如果有,一个TCP/IP包会形成在包缓存里。

输出处理

输出处理过程比输入处理直接和简单得多。基本上,所有TCP和IP头字段由uip_conn 结构里的值充满,计算TCP和IP的校验和。当uip_process()函数返回,包通过网络设备驱动发出去。

重发

当uIP通过periodic_timer被调用时,重发就进入运作。连接里有些特殊的数据(也就是数据发出了去但仍没有确应的)通过UIP_OUTSTANDING位在uip_conn结构里的TCP状态标志变量标记。那个连接,时间变量减少。当时间到达零,上一段必须重发和调用应用函数去做真正的重发。如果一个特殊段重发编号超出一个可设置的界限,连接会结束和发一个RST段到远端连接结束,调用应用函数去通知它连接超时。

重置TCP

TCP规格要求如果TCP头里的序列号和确应号在当前连接的接收窗口失去了,有RST (复位)标志设置的包必须断开连接。为了减少代码的大小,uIP不严格遵守这个规定。相反,如果一个有

RST标志设置的包在连接里到达,连接会消灭那些不重要的序列号和确应号值。这个行为将会在将来的uIP版本修订

配置uIP:

uIP的设置隐藏在一个叫uipopt.h的单独头文件里。这个文档不仅包含了那些项目特性的设置选项 (例如uIP网点的IP地址和同时发生连接的最大值),而且有结构和C编译器的特殊选项。文档是独立的和有注释说明的。

应用例子

这节提供一些简单的u IP应用例子

一个简单的应用例子

第一个例子非常简单。应用程序监听输入连接的端口1234。当一个连接建立了,应用程序通过说“OK”回应所有发送给它的数据。

图6 显示了应用程序的实现。应用程序调用example1_init()初始化,uIP的回叫函数是example1_app(),在这个例子里,可设置的变量UIP_APPCALL应该要定义在example1_app。初始化函数调用uIP函数uip_listen()去注册一个监听端口。实际的应用函数example1_app()使用测试函数uip _newdata()和uip_rexmit()去确定为什么调用它。如果调用应用程序是因为最远端发了数据给它,它回应一个"ok"。如果调用应用函数是因为数据在网络里丢失和需要重发,它也发送一个 "ok"。

注意,这个例子显示了一个完全的uIP应用。应用程序不需要处理所有类型事件例

如:uip _connected()或uip_timedout()。

void example1_init(void) {

uip_listen(1234);

}

void example1_app(void) {

if(uip_newdata() || uip_rexmit()) {

uip_send("ok\n", 3);

}

}

图6: 一个非常简单的应用程序

一个更高级的应用

第二个例子只是稍微比第一个高级一点,显示了程序中状态段怎样在uip_conn结构中使用。

这个应用程序和第一有些相似,它监听一个输入连接的端口和回应发送给它的数据一个"ok"。最大的不同是当连接建立时,这个程序打印输出一个欢迎信息"Welcome!"。

程序怎样实现,表面上是操作上的小改动产生效果上很大的不同。复杂性增加的原因是如果数据在网络里丢失,程序必须知道那个数据需要重发。如果"Welcome!"信息丢失了,程序必须重发欢迎信息,如果其中一个"ok"信息丢失,程序必须发一个新的"ok"。

程序知道只要"Welcome!"信息没有被远程主机确应,它就可能在网络里丢失了。但一旦远程主机已发了一个确应回来,程序可以应为欢迎信息已经被接收,知道一些丢失的数据是一个"ok"信息。因此程序可以在两个之中的一个状态:在WELCOME-SENT状态,"Welcome!"已经发出但没有被确应,或者WELCOME-ACKED状态,"Welcome!"已被确应。

当远程主机连接到应用程序时,程序发一个"Welcome!"信息和发它的状态去

WELCOME-SENT。当欢迎信息被确应了,程序进入WELCOME-ACKED状态。如果程序从远程主机收到任何新数据,它回应一个"ok" 。

如果应用程序被请求重发上一条信息,它看程序在那个状态。如果程序在WELCOME-SENT 状态,它知道先前的欢迎信息没有被确应,它再发一个"Welcome!"信息。如果程序在WELCOME-ACKED状态,它知道上一条信息是 "ok" ,只发一条信息。

应用的实现可以在图7看到。图8显示了应用的设置

struct example2_state {

enum {WELCOME_SENT, WELCOME_ACKED} state;

};

void example2_init(void) {

uip_listen(2345);

}

void example2_app(void) {

struct example2_state *s;

s = (struct example2_state *)uip_conn->appstate;

if(uip_connected()) {

s->state = WELCOME_SENT;

uip_send("Welcome!\n", 9);

return;

}

if(uip_acked() && s->state == WELCOME_SENT) {

s->state = WELCOME_ACKED;

}

if(uip_newdata()) {

uip_send("ok\n", 3);

}

if(uip_rexmit()) {

switch(s->state) {

case WELCOME_SENT:

uip_send("Welcome!\n", 9);

break;

case WELCOME_ACKED:

uip_send("ok\n", 3);

break;

}

}

}

图7: 一个高级应用

#define UIP_APPCALL example2_app

#define UIP_APPSTATE_SIZE sizeof(struct example2_state)

图8: 应用程序设置

区分应用程序

如果系统要运行多个应用程序,区分它们的其中一个技术是使用连接的远程终端或当地终端的TCP端口编号。图9 显示了怎样将上面的例子结合在一个应用程序里。

void example3_init(void) {

example1_init();

example2_init();

}

void example3_app(void) {

switch(uip_conn->lport) {

case htons(1234):

example1_app();

break;

case htons(2345):

example2_app();

break;

}

}

图9: 两个应用程序组合和使用不同的当地端口

接收大量数据

这个例子显示了一个简单的程序连接主机,发一个文件的HTTP请求和从慢速设备如磁盘驱动器下载文件。这个显示了怎样使用uIP的流控制函数。程序显示在图10。

当连接已经建立,一个HTTP请求发去服务器。这是唯一的发送数据,应用程序知道是否需要重发数据,那么请求要重发。所以要合理的将两个事件结合在例子里。

当应用程序从远程主机接收数据,它通过使用函数device_enqueue()发这些数据去设备。要注意的是这个例子假设这个函数复制数据去它自己的缓存。因为在uip_appdata缓存的数据将会被下一个输入数据覆盖。

如果等待设备的队列满了,应用程序通过调用uIP函数uip_stop()停止来之远程主机的数据。应用程序确保它不接收任何数据,直到调用uip_restart()。应用程序轮询事件,用于检查队列是否不在满,如果没满,通过uip_restart()数据流重新开始。

void example4_init(void) {

u16_t ipaddr[2];

uip_ipaddr(ipaddr, 192,168,0,1);

uip_conn(ipaddr, 80);

}

void example4_app(void) {

if(uip_connected() || uip_rexmit()) {

uip_send("GET /file HTTP/1.0\r\nServer:192.186.0.1\r\n\r\n",48);

return;

}

if(uip_newdata()) {

device_enqueue(uip_appdata, uip_datalen());

if(device_queue_full()) {

uip_stop();

}

}

if(uip_poll() && uip_stopped()) {

if(!device_queue_full()) {

uip_restart();

}

}

}

图10: 一个接收大量数据的应用程序

一个简单的网络服务器

这个例子显示了一个非常简单的文件服务器程序和使用端口编号去决定发送那个文档。如果文档适当格式化一下,这个简单的程序可以作为一个有静态网页的网络服务器。图11 显示了实现方法。

应用程序的状态包括一个指向要发送数据的指针和剩下发送数据的大小。当一个远程主机连接去应用程序,当地端口编号用于决定那个文档要发送。第一块数据使用uip_send()发送。由于有监管,至多的最大段字节数据发送了。

应用程序由肯定应答驱动。当数据被确应,新数据可以发送。如果没有数据要发送了,连接使用uip_close()关闭。

struct example5_state {

char*adaptor;

unsigned int dataleft;

};

void example5_init(void) {

uip_listen(80);

uip_listen(81);

}

void example5_app(void) {

struct example5_state *s;

s = (struct example5_state)uip_conn->appstate;

if(uip_connected()) {

switch(uip_conn->lport) {

case htons(80):

s->dataptr = data_port_80;

s->dataleft = datalen_port_80;

break;

case htons(81):

s->dataptr = data_port_81;

s->dataleft = datalen_port_81;

break;

}

uip_send(s->dataptr,uip_mss() < s->dataleft? uip_mss(): s->dataleft);

return;

}

if(uip_acked()) {

if(s->dataleft < uip_mss()) {

uip_close();

return;

}

s->dataptr += uip_mss();

s->dataleft -= uip_mss();

uip_send(s->dataptr,uip_mss() < s->dataleft? uip_mss(): s->dataleft); }

}

图11: 一个简单的文件服务器

以太网及TCPIP通俗理解

1 以太网------EtherNet: ---------------------------参考图解 以太网最早由Xerox(施乐)公司创建,于1980年DEC、lntel和Xerox三家公司联合开发成为一个标准。以太网是应用最为广泛的局域网,包括标准的以太网(10Mbit/s)、快速以太网(100Mbit/s)和10G(10Gbit/s)以太网,采用的是CSMA/CD访问控制法,它们都符合IEEE802.3。 IEEE 802.3标准 IEEE802.3规定了包括物理层的连线、电信号和介质访问层协议的内容。以太网是当前应用最普遍的局域网技术,它很大程度上取代了其他局域网标准。如令牌环、FDDI和ARCNET。历经100M以太网在上世纪末的飞速发展后,目前千兆以太网甚至10G以太网正在国际组织和领导企业的推动下不断拓展应用范围。 常见的802.3应用为: 10M: 10base-T (铜线UTP模式) 100M: 100base-TX (铜线UTP模式) 100base-FX(光纤线) 1000M: 1000base-T(铜线UTP模式) 2 UIP协议: uIP由瑞典计算机科学学院(网络嵌入式系统小组)的Adam Dunkels 开发。其源代码由C 语言编写,并完全公开,uIP 的最新版本是1.0 版本,本指南移植和使用的版本正是此版本。uIP协议栈去掉了完整的TCP/IP中不常用的功能,简化了通讯流程,但保留了网络通信 必须使用的协议,设计重点放在了IP/TCP/ICMP/UDP/ARP这些网络层和传输层协议上,保证了其代码的通用性和结构的稳定性。 由于uIP协议栈专门为嵌入式系统而设计,因此还具有如下优越功能: 1)代码非常少,其协议栈代码不到6K,很方便阅读和移植。 2)占用的内存数非常少,RAM 占用仅几百字节。 3)其硬件处理层、协议栈层和应用层共用一个全局缓存区,不存在数据的拷贝,且发送和接收都是依靠这个缓存区,极大的节省空间和时间。 4)支持多个主动连接和被动连接并发。 5)其源代码中提供一套实例程序:web 服务器,web 客户端,电子邮件发送程序(SMTP 客户端),Telnet服务器,DNS主机名解析程序等。通用性强,移植起来基本不用修改就可以通过。 6)对数据的处理采用轮循机制,不需要操作系统的支持。 由于uIP对资源的需求少和移植容易,大部分的8位微控制器都使用过uIP 协议栈,而且很多的著名的嵌入式产品和项目(如卫星,Cisco 路由器,无线传感器网络)中都在使用uIP 协议栈。 3 TCP/IP协议: TCP/IP是(Transmission Control Protocol/Internet Protocol)的简写,中译名为传输控制协

uip移植笔记

本笔记适用于uIP1.0。 移植平台介绍:MSP430F149+cs8900a+IAR 1、阅读The uIP Embedded TCP/IP Stack The uIP 1.0 Reference Manual. 2、建立一个文件夹,起名myport,将uip-1.0下的uIP和lib两个文件夹拷贝过去,然后再在myport下建立app文件夹。 3、将unix子文件夹下的clock-arch.c、clock-arch.h拷贝到myport下,这个文件实现协议栈所用的时钟,由430的定时器完成,有三个函数: clock_time_t clock_time(void) { return ticks; } void clock_init(void) { 定时器的初始化工作 } __interrupt void timer_interrupt(void)/*定时器中断函数*/ { ++ticks; }。 4、将unix子文件夹下的uip-conf.h拷贝到myport下,这个文件实现协议栈所用的配置,按照需要修改之。 5、写cs8900a的驱动函数,这里采用8位、查询模式,替换tapdev.c 或slipdev.c。 6、将unix子文件夹下的main.c函数拷贝到myport下,这个是主调度流程,按照需要修改。 7、建立自己的工程,将以上文件包含。 8、调试,改错。 其中,uip的缓冲区是以字节数组的形式产生,为了保证它的起始地址是偶数,必须指定地址。 UDP的初始化如下 void myudp_init(void) { uip_ipaddr_t ipaddr;//定义IP类型变量 uip_ipaddr(ipaddr, 210,29,104,88); //远程IP为210.29.104.88 if(myudp_conn != NULL) { uip_udp_remove(myudp_conn);//如果连接已经建立,则删除之 } myudp_conn = uip_udp_new(&ipaddr, HTONS(1000));//建立到远程ipaddr,端口为1000的连接 if(myudp_conn != NULL) {

2012.11.6战略智慧笔记 陈果

N 《战略智慧》 --陈果 如何建立战略思维? 你现在最需要解决的是什么问题? 1、未来老百姓的健康生活方式? 2、房产中介的人力资源 3、企业做到一定程度,如何把规模缩小? 4、如何使用90后? 5、外贸出口利润越来越低,公司成本越来越大,如何突破?需要经营的: 1、原始积累(财富) 2、内部团队(精神共同体) 团队是利润,是巨大财富 3、忠实客户(了解客户需求) 企业一定要战略升级,为谁请命? 老板需要经营“空手套白狼”的本领。 企业做大的因素: 1、政府的力量 2、资金对你的加持 3、消费者对你的关注 4、优秀的人才向你靠齐

利润 (如:外婆家) 如:宋城集团,通过做“宋城千古情”项目,获得政府的支持 大老板:看似很傻,实际很厉害,用一年的时间赚10年的钱 如:王志纲老师用三十年的时间做中国最好的“战略思想智库”,一转身获得无数的财富 经营企业就是经营人,经营企业就是经营价值。 企业、产品都是媒介,关键是你想到哪里去。 战略思维思考的问题是:我要到哪里去? 老板必须为战略负责! 战略是唯一不能让职业经理人去做的事情。 没有战略就没有人追随,如果成功也是偶然的。 如:王建林(万达集团),当初做商业地产,所有人都反对如:吴亚军,(南湖地产,温州人)当初做战略十几人的核心团队全部走掉,但今天成为中国女首富。 老板不是所有事情都需要你来做,而是那些事情是你必须要做的。

如:华为,力排众议做最适合当下的战略 这是一场越来越激烈的商战,不要妄想今天的困难明天就过去了,要有打战的思维 如:微软 在战争当中总结经验,这是老板需要修炼的 战略智慧金三角: 找定位 定打法 开模具 战略之道的根本是定位。 打法和模具的关系: 模具是企业超级杀伤力的武器 如:工作室:帮企业找魂,帮企业开模具书院班:帮企业开模具,寻找战略突破打法:合适的发射装置 打法与模具的关系是炮弹和炮筒的关系 孵化人的板块: 从老板到老师的智慧

关于uCGUI移植详解

关于uCGUI在STM32上的移植移详解 首先我们得知道啥是μC/GUI: 它是一种用于嵌入式应用的图形支持软件。它被设计用于为任何使用一个图形LCD的应用提供一个有效的不依赖于处理器和LCD 控制器的图形用户接口。它能工作于单任务或多任务的系统环境下。 μC/GUI 适用于使用任何LCD 控制和CPU 的任何尺寸的物理和虚拟显示。 它的设计是模块化的,由在不同的模块中的不同的层组成。一个层,称作LCD 驱动程序,包含了对LCD 的全部访问。因为它100%由ANSI 的C 语言编写的,μ所以C/GUI 适用于所有的CPU。 我们知道windowsXP的操作界面,是通过窗口、按钮、等来对计算机进行操作,同样,我们所讲的uC/GUI也能实现类似效果。 在网上找了些教程,但是讲述的不够详细,导致我在移植过程中遇到了很多问题,自己重头开始自己一点点移植,遇到的问题也只能靠自己解决,终于在忙活了一天后把它搞定了。希望对初次进行移植的同学能有所帮助。下面是我的吐血总结: 所需工具:1、uC/GUI v3.90 尽量找到没有修改的源码 2、一个硬件开发平台、LCD底层驱动程序,我使用的是STM32F103ZE+TFT3.2寸LCD 3、MDK开发软件(就是Keil) 4、一个编译无误的工程模板 4、uC/GUI相关的中文手册 移植步骤:

第一步:首先,得把你的LCD底层驱动写好,既在裸机下,可以正常显示。 通常只需3个底层驱动函数: LCD_SetPoint(u16 x,u16,y,int color);//设置某点,及颜色 LCD_GetPoint(u16 x,u16 y); //读取某点及颜色返回 LCD_Init(); //LCD初始化硬件函数,这里改成其他名字如LCD2_Init();防止和 uC/GUI冲突 第二步:向事先准备好的工程中加入uC/GUI文件夹,在工程设置中包含相应头文件 工程目录如下: 第三步:配置LCDConf.h、GUIConf.h、GUITouchConf.h(由于我没使用触摸功能,此配置在此不讲。) 配置LCDConf.h文件如下:LCD的设置 #ifndef LCDCONF_H #define LCDCONF_H #define LCD_XSIZE (320) //配置TFTLCD的水平分辨率 #define LCD_YSIZE (240) //配置TFTLCD的垂直分辨率 #define LCD_CONTROLLER (-1) //为什么是-1?接下来讲 #define LCD_BITSPERPIXEL (16) //每个像素的位数

ucos操作系统在ARM上的移植

UC/OS-II 嵌入式系统在ARM 上的移植 UC/OS-II 操作系统是一款完全公开的源代码,它非常精简,整个操作系统的代码只有几千行,是专门针对于嵌入式开发而产生的一款代码。它有几个特点,分别是可移植性(Portable )、可固化(ROMable )、可裁剪(Scalable )、多任务、可确定性、任务栈、系统服务、中断管理、稳定性可靠性。 UC/OS-II 主要就是一个内核,由ANSIC 语言编写而成。负责任务管理和任务调度,没有文件系统和界面系统。它的代码是公开的,系统的实时性强、移植性好、可多任务。 UC/OS-II 作为基于优先级的抢占式多任务的实时操作系统,包含了实时内核、任务管理、时间管理、任务间通信同步和内存管理的功能。它使得任务的独立性,不相互干涉,非常的准时和高效,且易于设计和扩展。 UO/OS-II 共有16个内核文件,11个与CPU 类型无关,就是说可以直接使用不需要修改。还有3个内核文件与CPU 有关系,要根据需要作出相应的改动。剩下的两个内核文件和具体的应用有关。如图所示UC/OS-II 的16个内核文件的层次。 μC/OS -II 内核文件 软件 硬件

多任务操作的核心是系统调度器,利用TCB来管理任务调度功能。它的主要功能是保存任务的当前态、优先级、等待事件、代码起始地址、初始堆栈指针等。程序的设计关键就是确定划分多任务的问题,以及任务优先级和任务通信。 优先级的意思是每个任务都是无限循环的,有运行态度、就绪态、休眠态、挂起态和中断五种状态。当有高一级优先级的任务就绪后,低优先级立即停止运行,转为挂起态或就绪态。这就是可剥夺型的内核。当中断一个高优先级任务,中断时 挂起,中断结束后任务继续运行,并立即剥夺低优先级的任务。 对于这种可剥夺型内核,CPU的使用时可以确定的,可优化任务级响应。在很多单片机或ARM板上很容易就可以移植UC/OS-II。当然本次设计使用的TQ2440,也可以完美的移植它。移植程序在网上都可以找得到,所以设计中就不做解释了。 本次设计实现的是串口协议和网口协议组合成的一个数据网关。其主要的流程图如下所示:

UCGUI移植教程

UCGUI在STM32上移植教程 1说明 ●开发板芯片型号STM32F103VET6 ●板载液晶型号ILI9341 ●所需准备资料UCGUI3.90源码 ●一个工程模板 为了节约时间,此处所用模板为野火M3工程模板(3.5.0) 制作时间---2013-08-07 By NUAA---Kylin 2移植过程讲解 2.1首先打开工工程模板,页面如下,这个模板工程很简单

2.2在工程模板中新建两个文件夹 2.2.1命名为GUI与Mylib 2.2.2在GUI文件夹下添加以下内容 ●上述图片为UCGUI3.90源码中的一些文件夹 ●进入UCGUI3.90源码文件夹/Start,将Config文件夹原封不动的拷过来 ●进入UCGUI3.90源码文件夹/Start/GUI文件夹,将其中所有文件夹拷过来 ●在GUI文件夹下新建GUI_X文件夹,进入UCGUI3.90源码文件夹/ Sample/ GUI_X文件夹 中,如果带操作系统应该拷贝GUI_X_uCOS.c,如果不带操作系统拷贝GUI_X.c,在这里我们将将GUI_X.c拷贝到新建GUI_X文件夹。

2.2.3各文件夹说明 1)AntiAlias:9个C文件,主要用于抗锯齿的显示效果。 2)ConvertColor:彩色显示的色彩转换支持。 3)ConvertMono:(b/w)和灰度显示的色彩转换支持。 4)Core:核心文件,提供了GUI基本的功能。 5)Font:字库。 6)JPEG:图片操作函数。 7)LCDDriver:LCD驱动程序 8)MenDev:Memorydevice 支持。这个东西可用在很多情况下,但最主要的功能是防止在 项目重叠时,防止屏幕的闪烁。 9)Widget:窗体控件库。 10)WM:窗口管理库。 11)Config:配置文件。 12)GUI:源代码。 13)GUI_X:操作系统接口函数。 2.3添加组及源文件 2.3.1将GUI文件夹下的所有文件夹添加到GROUP 右键工程工程项目名选择manage components将这些组全部添加上如图

uCGUI 汉字显示技巧及总结

UCGUI的基础应用 汉字显示 在uC/GUI中显示汉字,必要的一个步骤就是汉字取模。通常有两种方法: 一、单个字模法:使用字模取模软件,进行单个字的取模。此方法可应用于显示汉字字 数较少的情况下。其优点是:占用存储空间小,无冗余。但当显示汉字字数较多时,该方法则非常繁琐。 二、字模库法:该方式需要移植整个汉字字库,若项目要求需显示多种汉字字体,则需 移植多种字体的字库。其优点是:操作方便。若嵌入式系统的FLASH存储容量够大时,该方式可行。 根据作者多年的项目实践,找到一个兼具上述两种方式优点的显示方案:利用UCGUIFontTool软件,提取windows自带的字模库。该方法的使用步骤: 1、将项目中所要显示的汉字根据字体进行分类并汇总。 2、使用UCGUIFontTool软件分别提取上述字模。 3、将所产生的.C文件添加到工程中。 4、更改gui.h中的配置,添加该汉字的宏定义,如图 5、显示汉字前更改需显示的字体,如图 6、利用函数进行显示。 该方法移植方便,易实现同时显示多种字体,无字模冗余,占用存储空间最小。图片显示 uC/GUI提供了位图的解决方案,在GUI显示图片时,需先将其他格式的图片转换为bmp格式。可利用windows系统自带的画图软件打开一个图片,再另存为bmp格式,继而转换为.c 格式文件加入到工程中。其操作步骤如下: 1、将其他格式的图片另存为bmp格式。 2、打开UCGUI源码自带的工具uC-GUI-BitmapConvert,选择相应参数,并转换为.c文件。 3、将该.c文件加入到工程中。 4、添加外部变量,并调用相应函数进行显示。如图 5、也可UCGUI提供的缩放函数可对图片进行缩放显示。如图

基于STM32的uCGUI移植和优化

基于STM32的uCGUI移植和优化 移植篇 首先,我们需要准备的东西有uCGUI3.90,这个版本是大家现在用的比较多的,效率也比较高,别人都是这么评论的,至于其他版本的,我没有接触很多,所以 不能过多评论. uCGUI有三个文件夹,一个是tool,这个文件夹是用来使用一些uCgui的上位机程序,基本都是字体和模板查看之类的.在sample文件夹下面是已经别人帮你写好了很多有用的东西,像跟操作系统有关的GUI_X或者一些模板(后面我们会用到的自己定义的Demo),或者是gui配置.后面再一一详细叙说这个文件夹的功能.在Start文件夹里面,这是我们最主要的文件夹.里面就包含了uCGUI的源代码,uCGUI的作者把源代码放进vc里面进行编译了(当然,这是用标准C语言写的程序,所以我们可以放在任何C语言平台下编译而不会担心兼容性问题,这个uCGUI在这方面做的算是完美了),所以,我们可以在vc平台下写界面,然后再把代码拷进我们的下位机编译器进行编译,这样子效率就会非常高了.(像51 那时候写界面就是疯狂的一次一次的烧,真是纠结..). 然后这里放的就是uCGUI的源代码了,在GUI文件夹下面. 这则是每个文件夹的功能(参考uCGUI中文手册,https://www.wendangku.net/doc/374700423.html,翻译). 大概看一下就可以了,这个跟我们移植的关系不大,关键点是带*的可以不包含进去(待会配置会讲到.).然后其他的都要包含进去. 接着我们要把我们的文件包含进我们已经搭建好的工程,这里说明下我们的工程要求. 一般来说,我们要画一个图形,最基本的就是从点开始,从点到线,从点到面...,所以在已经建好的工程里面你要能点亮你的屏幕,能点出最基本的点,能填充出 最基本矩阵(这是uCGUI最包含的函数),反正我移植的时候涉及到的包括三个函 数,LCD_Init();LCD_Draw_Point(x,y,color),LCD_Fillcircuit(x1,x2,y1,y 2).这三个函数是必须的,后面也会说明如何把这三个函数进行填充. 当我们把文件复制进去的时候,再加上我们一开始已经创建好的工程的时候,文件结构差不多就是这个样子了,截图如下 user包括,main函数就是我们初始化和函数调用,绘图用的文件,另外那几个文件相信大家都明白了把,tft_lcd.c就是你在,没有移植uCGUI的情况下,纯液晶屏驱动,这里建议把液晶屏的API和最底层驱动(API就是画圆啊,画椭圆啊,清除屏幕之类的,底层驱动就是驱动液晶屏的管脚运作,fsmc初始化,时钟配置之类的),不过我这里也是集成在一起了,比较懒,大家别学.

uip协议栈

uIP协议栈分析 uIP特性 uIP协议栈往掉了完整的TCP/IP中不常用的功能,简化了通讯流程,但保存了网络通讯必须使用的协议,设计重点放在了IP/TCP/ICMP/UDP/ARP这些网络层和传输层协议上,保证了其代码的通用性和结构的稳定性。 由于uIP协议栈专门为嵌进式系统而设计,因此还具有如下优越功能: (1)代码非常少,其协议栈代码不到6K,很方便阅读和移植。 (2)占用的内存数非常少,RAM占用仅几百字节。 (3)其硬件处理层、协议栈层和应用层共用一个全局缓存区,不存在数据的拷贝,且发送和接收都是依靠这个缓存区,极大的节省空间和时间。 (4)支持多个主动连接和被动连接并发。 (5)其源代码中提供一套实例程序:web服务器,web客户端,电子邮件发送程序(SMTP 客户端),Telnet服务器,DNS主机名解析程序等。通用性强,移植起来基本不用修改就可以通过。 (6)对数据的处理采用轮循机制,不需要操纵系统的支持。 由于uIP对资源的需求少和移植轻易,大部分的8位微控制器都使用过uIP协议栈, 而且很多的著名的嵌进式产品和项目(如卫星,Cisco路由器,无线传感器网络)中都在使用uIP协议栈。 uIP架构 uIP相当于一个代码库,通过一系列的函数实现与底层硬件和高层应用程序的通讯,对于整个系统来说它内部的协议组是透明的,从而增加了协议的通用性。uIP协议栈与系统底层和高层应用之间的关系如图2-1所示。 从上图可以看出,uIP协议栈主要提供了三个函数供系统底层调用。即uip_init(), uip_input() 和uip_periodic()。其与应用程序的主要接口是UIP_APPCALL( )。 uip_init()是系统初始化时调用的,主要初始化协议栈的侦听端口和默认所有连接是封闭的。当网卡驱动收到一个输进包时,将放进全局缓冲区uip_buf中,包的大小由全局变量uip_len

基于uCOSⅡ的LCD驱动编写

天津电子信息职业技术学院 课程设计 课题名称基于uCOSⅡ的LCD驱动编写姓名王浩 学号35 班级电信S10-1 专业电子信息工程 成绩 完成日期2012-06-01

基于uCOSII的LCD驱动编写 摘要 LCD是嵌入式操作系统的重要组成部分,是系统和用户之间进行交互和信息交换的媒介,它实现信息的内部形式与人类可以接受形式之间的转换。用户可以只通过LCD监测系统内部运行状态,然后作出相应的处理。因而具有良好的人机界面的嵌入式操作系统能过很好的完成系统开发、生产生活的需要。 S3C44B0X 中具有内置的LCD 控制器,它能将显示缓存(在SDRAM存储器中)中的LCD 图像数据传输到外部的LCD驱动电路上的逻辑功能。它支持单色、4级、16级灰度LCD显示,以及256彩色LCD显示。在显示灰度时,它采用时间抖动算法(time-based dithering algorithm)和帧率控制 (Frame Rate Control)方法,在显示彩色时,它采用RGB的格式,即RED、GREEN、BLUE,三色混合调色。通过软件编程,可以实现233或332的RGB调色的格式。对于不同尺寸的LCD显示器,它们会有不同的垂直和水平象素点、不同的数据宽度、不同的接口时间及刷新率,通过对LCD 控制器中的相应寄存器写入不同的值,来配置不同的LCD 显示板。 LCD能够正常工作得益于软硬件的协同工作,S3C44B0X集成了LCD的控制器,即不带驱动电路的LCD显示模块,驱动程序需要根据用户需要来自行添加。 u C / O S 是一种免费公开源代码、结构小巧、具有可剥夺实时内核的实时操作系统,在具体应用中稳定可靠,并且支持uIP TCP/IP协议栈、ucGUI等,可扩展性强,功能强大。因此,在uC/OS II下写的LCD驱动具有较好的实时性和稳定性,功能强大。 关键词:嵌入式系统;LCD显示;驱动电路;

uip学习笔记

uip_buf:定义如下u8_t uip_buf[UIP_BUFSIZE + 2];所有的数据处理都是通过处理它来完成的。比如接受的数据存储在这里,要发送的数据有会放在这里。 uip_len:uip_buf有用数据的字节 uip_appdata:uip_buf第一个可用字节的指针 uip_conn:总是指向当前连接的指针,定义:struct uip_conn *uip_conn; 下面是TCP连接的结构,用来区别不同的TCP连接,uip_tcp_appstate_t appstate是可以读写的且在实践应用中需要重定义,其他项read-only。 struct uip_conn { uip_ipaddr_t ripaddr; /**< The IP address of the remote host. 远程主机IP地址*/ u16_t lport; /**< The local TCP port, in network byte order. 本地TCP端口号,网络字节顺序*/ u16_t rport; /**< The local remote TCP port, in network byte order.本地远程连接主机TCP端口号*/ u8_t rcv_nxt[4]; /**< The sequence number that we expect to receive next. */ u8_t snd_nxt[4]; /**< The sequence number that was last sent by us. */ u16_t len; /**< Length of the data that was previously sent. */ u16_t mss; /**< Current maximum segment size for the connection. */ u16_t initialmss; /**< Initial maximum segment size for the connection. */ u8_t sa; /**< Retransmission time-out calculation state variable. */ u8_t sv; /**< Retransmission time-out calculation state variable. */ u8_t rto; /**< Retransmission time-out. */ u8_t tcpstateflags; /**< TCP state and flags. */ u8_t timer; /**< The retransmission timer. */ u8_t nrtx; /**< The number of retransmissions for the last segment sent. */ /** The application state. */ uip_tcp_appstate_t appstate; }; uip的应用事件: 1.接收数据:uip_newdata()为真,即远程连接的主机有发送新数据。uip_appdata指针指向实际数据。数据的大小通过uIP函数uip_datalen()获得。在数据不是被缓冲后,应用程序必须立刻启动。 2.发送数据:应用程序通过使用uIP函数uip_send()发送数据。uip_send()函数采用两个参数;一个指针指向发送数据和数据的长度。如果应用程序为了产生要发送的实际数据需要RAM 空间,包缓存(通过uip_appdata指针指向)可以用于这方面。在一个时间里应用程序只能在连接中发送一块数据。因此不可以在每个应用程序启用中调用uip_send()超过一次;只有上

UCOS-II ucGUI的完美移植

stm32 UCGUI 完美移植 作者:Changing发表时间:09-16 04:13分类:电子相关1 Comment 前一篇:stm32 DA 数模转换 后一篇:Stm32 SWD 下载 调试配置 UCGUI是一种嵌入式应用中的图形支持系统。它设计用于为任何使用LCD图形显示的应用提供高效的独立于处理器及LCD控制器的图形用户接口,它适用单任务或是多任务系统环境, 并适用于任意LCD控制器和CPU下任何尺寸的真实显示或虚拟显示。 它的设计架构是模块化的,由不同的模块中的不同层组成,由一个LCD驱动层来包含所有对LCD的具体图形操作。UCGUI可以在任何的CPU上运行,因为它是100%的标准C代码编写的。 类似程序还有国产的一个MINIGUI (https://www.wendangku.net/doc/374700423.html,/zhcn/),MiniGUI 是一个自由软件项目。其目标是提供一个快速、稳定、跨操作系统的图形用户界面(GUI)支持系统,尤其是基于 Li nux/uClinux、eCos 以及其他传统 RTOS(如 VxWorks、ThreadX、uC/OS-II、Nucleus 等)的实时嵌入式操作系统。有机会尝试下,支持下国产,毕竟国内这样的公司不多。。 这里移植的UCGUI3.90a版本,虽然已经有更新的版本,比如UCGUI3.98、甚至4.04版本。但是目前来说只有这个版本的代码是最全的,包括了JPEG , MULTILAYER , MEMDEV ,AntiAlias等模块。一直想尝试做一个数码相册,JEPG模块自然少不了,所以移植了这个版本。 UCGUI390a 下载 整个移植过程,让LCD显示图案倒是没花多少时间,资料也比较多,但是在移植触摸屏的时候卡了好几天,然后又是 UCGUI 指针图标 移动有重影(LCD读取像素颜色函数有问题)。。。总之移植是个累人的活 首先需要保证你的LCD驱动和触摸屏驱动是有效的,如果你的LCD也是ili93xx 控制器 XPT2046控制器的触摸屏可以参考 stm32 驱动 T F T LCD stm32 驱动 触摸屏 两篇文章 UCGUI的文件数量很大,主要用到UCGUI390a/Start/Con f ig 和 UCGUI390a/Start/GUI两个文件夹下文件,不过文件数量也已经很多了 。。。 相关文件介绍如下:

ucGUI移植笔记-完善版

ucGUI移植笔记完善版 最近在弄ucGUI的移植,网上搜了不少资料,也问了同学,总算把简单的一个程序弄好了,也感谢openedv论坛和hua290565456的网友,看了他的贴子,才恍然大悟弄好。 该程序是直接用的原子大哥的TFTLCD显示的例子,直接拿过来移植的,感谢原子大哥的程序,在我学习STM32的旅途上帮助我不少。 所用到的是原子大哥TFTLCD例子(库函数版本)和ucGUI3.90源码。 建工程就不说了,附件里有,相信大家也看到别人建的工程了,下面直接说重点。 补充说明:如果你移植的时候怎么也不成功,大部分原因是GUI无法初始化LCD。考虑两方面的原因: 一、你写的底层驱动程序; 二、底层驱动程序与GUI系统的接口,即GUI的配置。 所有的问题几乎都是出现在这两方面,造成GUI无法成功调用正确的底层初始化程序。 所以: 1.确保你的底层驱动在没有移植GUI之前,能顺序驱动LCD成功。 2.然后,确保你的底层驱动接口没有与上层GUI有相同的公共的变量。可以有同名的变 量,但所有的变量都必须是私有的。也就是原子哥的那个结构体LCD不能在.h中定义。 如果LCD驱动文件是lcd.c和lcd.h,最好改为别的名字,比如ili93xx.c和ili93xx.h。然后还要把LCD_Init()初始化函数改为LCDx_Init();因为GUI系统已经有名为LCD.c的文件和LCD_Init()的函数。总而言之,确保你的底层的接口文件(xx.h)没有与上层同名的公共变量。 3.修改GUI系统与底层的接口: A.LCDConf.h中按照下面的图就行,其余的可以删除掉,一定要删除其他的,因为有 相同的LCD_CONTROLLER定义,会造成硬件出错而进入硬件出错中断死循环。注意红框中是刚刚改过的LCD初始化函数,改为刚刚更改的初始化函数就行。 B.接下来是GUIConf.h中的设置,目前只是用到简单的一个现实函数,多以就全部设

基于FPGA的IP核8051上实现TCPIP的设计

基于FPGA的IP核8051上实现TCP/IP的设计引言 随着芯片规模的越来越大、资源的越来越丰富, 芯片的设计复杂度也大大增加。事实上, 在芯片设计完成后, 有时还需要根据情况改变一些控制, 这在使用过程中会经常遇到。这时候如果再对芯片设计进行改变将是很不可取的, 因为需要设计人员参与这种改变, 这无论是对设计者还是用户都是不能接受的。于是就有必要让这种可以改变的简单控制在芯片设计时就存在, 而且同时还应该使这种改变相对容易, 比较通用, 并且与芯片的其它设计部分尽量不相关。为了满足上述的要求, 在FPGA中嵌入一个比较理想的选择, 而这个即通用又控制简单的IP核最好选择8051微处理器。 在FPGA中植入8051后, 还可在上面实现简单的TCP/IP协议, 以支持远程访问或进行远程调试, 这只是在嵌入FPGA的8051上的一个应用。为了保证用户能够对8051实现不同的控制操作,设计时也可以采用一个外部flash对8051进行加载, 这样, 用户只需要将编译好的汇编语言代码加到flash就可以控制8051的工作, 而此时用户完全不需要对FPGA进行操作就能实现简单的控制,而这需要的仅仅只是keil的编译环境。 1 IP核8051的FPGA实现 现在有许多免费的8051核可以利用, 这些核都可通过硬件描述语言来实现, 并且基本上都可综合, 也就是直接拿来就能用, 需要的只是根据自身的具体需求做一些简单修改即可。总的说来, IP核8051的移植是比较简单的。 本系统的设计与实现可以采用oregano system的mc8051内核, 并且加入定时计数的和串口模块, 8051单片机的设计结构框图如图1所示。

ucgui液晶显示深度优化篇

UCGUI液晶显示深度优化篇 Author:wzt 2012年7月21日10:55:12 前一段进行了ucgui的移植,但是移植后续还是存在很多问题,比如液晶刷新速率慢,横竖屏切换不支持等,所以针对这些问题进行了一次彻底的优化,现在刷新能够达到20帧的速度对于50mhz的io口来说已经相当可以了。下面就进行一次彻底的剖析,看究竟是那些问题占用了宝贵的百万分之一秒: 一、速度优化篇: 1.我用的是stm32的处理器,stm32公司为了让使用者加快项目开发速度 和便于日后对整个软件部分的维护管理编写了一套标准库。这个库用 起来确实很方便也另学习简化了很多,但是它也有缺点所在:就是效 率问题。我之前用的液晶屏驱动就是基于库函数编写的,所以第一步 就是液晶驱动全部换为直接对寄存器操作,经实践确实刷新率成好几 倍的增长。这个代码比较长,这里就不贴出来的,这里仅仅指点下思 路,具体请看源代码。 代码下载地址:https://www.wendangku.net/doc/374700423.html,/icview-357489-1-1.html 2.深入液晶驱动内部:液晶屏刷新可不是像我们眼睛看到的一样瞬间整 个屏幕同时更新。实际上一个一个像素更新的:也就是说我的屏幕分 辨率是320*240就要更新320*240=76800个点。每一个点更新时都要 调用一个写数据函数。所以接下来要做的就是提高调用这个函数的速 度。有两种解决办法:使用宏定义函数或者内敛函数。我使用的是内 敛函数:如下定义: __inline void LCD_WR_DATA(u16 data) { LCD_RS_SET; LCD_CS_CLR; DATAOUT(data); LCD_WR_CLR; LCD_WR_SET; LCD_CS_SET; }可以看到和普通函数区别就在于前面增加了__inline关键字。它有什么 作用?为什么可以提高速度?下面讲解一下它是如何起作用的:假如现 在我们定义了两个函数A,函数B,函数A调用函数B:正常情况下如

奋斗STM32开发板uIP1.0 以太网例程讲解

奋斗版 STM32 开发板例程文档———uIP1.0 ENC28J60 以太网例程
https://www.wendangku.net/doc/374700423.html,
uIP1.0 ENC28J60 以太网例程
实验平台:奋斗版STM32开发板V2、V2.1、V3 实验内容:本例程演示了在奋斗STM32开发板上完成ARP,ICMP,TCP服务器、WEB 服务器以及UDP服务器,该实验学习了基于uIP1.0网络协议栈的程序编制。
预先需要掌握的知识
1.ENC28J60
ENC28J60是MICROCHIP公司的带SPI 接口的独立以太网控制器, 以太网控制器特性 ? IEEE 802.3 兼容的以太网控制器 ? 集成MAC 和10 BASE-T PHY ? 接收器和冲突抑制电路 ? 支持一个带自动极性检测和校正的10BASE-T 端口 ? 支持全双工和半双工模式 ? 可编程在发生冲突时自动重发 ? 可编程填充和CRC 生成 ? 可编程自动拒绝错误数据包 ? 最高速度可达10 Mb/s 的SPI 接口 缓冲器 ? 8 KB 发送/ 接收数据包双端口SRAM ? 可配置发送/ 接收缓冲器大小 ? 硬件管理的循环接收FIFO ? 字节宽度的随机访问和顺序访问(地址自动递增) ? 用于快速数据传送的内部DMA ? 硬件支持的IP 校验和计算 介质访问控制器(MAC)特性 ? 支持单播、组播和广播数据包 ? 可编程数据包过滤,并在以下事件的逻辑“与” 和“或”结果为真时唤醒主机: - 单播目标地址 - 组播地址 广播地址 - Magic Packet - 由64 位哈希表定义的组目标地址 - 多达64 字节的可编程模式匹配(偏移量可由用户定义)
淘宝店铺:https://www.wendangku.net/doc/374700423.html,
1

如何学习TCPIP(基于51单片机)

如何学习TCPIP(基于51单片机) 总体说来,TCPIP并不是一件十分神秘的事情,尤其是基于MCU的应用,不要求进行特别复杂的处理,很多情况下只需要实现最最基本的功能就行了。在实现MCU的TCPIP移植之前,必须对TCPIP有一定程度的了解,可以找一本合适的书籍来翻阅一下,《TCP/IP详解,卷1:协议》https://www.wendangku.net/doc/374700423.html,/display.aspx?did=510是一本完整而详细的TCP/IP协议指南。描述了属于每一层的各个协议以及它们如何在不同操作系统中运行。 对于TCPIP在MCU上的应用并不要求对协议的所有部分都了解的那么清楚,重点需要了解TCPIP的各个层次的关系,链路层,有时也称作数据链路层或网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。网络层,有时也称作互联网层,处理分组在网络中的活动,例如分组的选路。在T C P / I P协议族中,网络层协议包括I P协议(网际协议),I C M P协议(I n t e r n e t互联网控制报文协议),以及I G M P协议(I n t e r n e t组管理协议)。运输层主要为两台主机上的应用程序提供端到端的通信。在T C P / I P协议族中,有两个互不相同的传输协议:T C P(传输控制协议)和U D P(用户数据报协议)。T C P为两台主机提供高可靠性的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端的通信,因此应用层可以忽略所有这些细节。而另一方面,U D P则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必需的可靠性必须由应用层来提供。这两种运输层协议分别在不同的应用程序中有不同的用途。应用层负责处理特定的应用程序细节。几乎各种不同的T C P / I P实现都会提供Telnet,FTP,SMTP 简单邮件传送协议,SNMP简单网络管理协议这些通用的应用程序。 各种类型的数据报格式也是需要了解的重点,使用Sniffer软件可以十分方便的在电脑上查看各种数据报的收发状态.同时Sniffer也是以后调试TCPIP协议寨的一个很有用的工具,Sniffer的使用方式可以在https://www.wendangku.net/doc/374700423.html,上很方便的搜索到. TCP/IP的分层,以太网封装,IP首部,子网寻址和子网掩码,ARP地址解析协议,ICMP控制报文协议中的ECHO(Ping程序),UDP用户数据报协议,TFTP简单文件传送协议,特别是TCP传输控制协议是TCPIP在MCU上应用所必需掌握的关键知识. 在对TCPIP有了一定程度的了解之后,如何具体的实现就成了问题的关键,我在学习TCPIP 的过程中前后一共使用或阅读了下面的3中TCPIP协议寨,这里有对3个协议寨的比较和下载地址. uIP,适合8bit单片机上使用,但是结构比较复杂,不适宜进行移植,也不是一份很适合阅读的代码.下载地址http://www.sics.se/~adam/uip/ Lwip,适合16/32bit单片机上使用,是嵌入式系统开发人员最好的学习TCPIP的代码,下载地址http://www.sics.se/~adam/lwip/ zLip,南开大学电子应用实验室编写的一个协议寨,有uip和lwip的优点,推荐初学者学习https://www.wendangku.net/doc/374700423.html,/display.aspx?did=859 在了解了具体实现之后,就有需要在MCU上具体的运行一下了,这里提供一个我做的硬件电路,但是其中我使用了GAL16V8芯片进行地址分配,所以需要有一个支持16V8的烧写器了,同时,如果将at89c55芯片换成sst89c58,并从https://www.wendangku.net/doc/374700423.html,公司网站上下载一个monitor 51的仿真监控程序,使用烧写器写入sst89c58中,就可以通过串口和Keil软件配合进行硬件仿真了.(市场上的那些100多元的51仿真器就是这个样子的). Gal的代码如下(abel hdl语言编写),使用猜测的方式都应该明白什么意思了把?!

emWin522(uCGUI)图形用户接口移植详细实例_STM32_2013_12_30

emWin 5.22 (uCGUI) 图形用户接口移植实例——STM32 作者:Ach 日期:2013年12月29日 联系方式:ox000008@https://www.wendangku.net/doc/374700423.html, 1.概要 移植图形用户接口的好处是不言而喻的。本文图文并茂地介绍了一个emWin 5.22(uCGUI)的移植实例。文章具体分为emWin简介,硬件平台简介,开发环境及项目简介,移植过程以及总结几个部分。 2.emWin简介 emWin是一种高效的而图形用户界面,是我们能够摆脱处理器和显示控制器而更专注于GUI的设计。这里借用STemWin的一幅图来说明emWin的作用和结构。它通过LCD及GUI的配置来驱动底层硬件,而应用程序又是通过调用emWin来实现各种GUI。5.22版的emWin带有许多常用的显示控制器的驱动(在参考手册Display Driver一章中有详细介绍),因此为我们移植带来了诸多方便。emWin的更详细的内容可参照它的参考手册。 图1. emWin在项目中的结构 3.硬件平台简介 笔者使用的是一块以STM32F103VET6为核心的ARM开发板,没有外部的SRAM及Flash。显示屏为2.8”320*240的彩色液晶屏,屏的驱动芯片为ILI9341(emWin 5.22带有它的驱动)。屏与CPU 的连接方式为该ARM核心所特有的FSMC_SRAM方式,访问LCD内容时操作就如同读写SRAM一样方便。 如果你想使用其它硬件平台来移植emWin,本文亦有一定的参考价值。希望本文能助你成功移植emWin。

图2. 硬件平台 4.开发环境简介 笔者所使用的开发软件为MDK-ARM 4.70。项目模板使用的是STemWin库中的(可从ST官方下载)。 图3. 项目截图 如图,项目下面有3个文件夹,其中Appli存放的是应用层的程序,第二个文件夹就如文件名,存放了emWin5.22所有部件,第三个文件夹存放了一些STM32及其它的库。具体见附件。 5.移植过程 有了MDK-ARM以及STemWin库,整个移植过程应该比较简单。STemWin中有4个文件夹,第一个可以不用看了,Libraries中包含所有需要的库(其中包含emWin5.22),Project中存放工程文件,Utilities中是一些应用文件。为了保持代码及工程结构的格式统一,我们尽量套用原有的格式。下面开始一步步的移植工作。 5.1 项目配置 打开Project文件夹,看到众多STM32的开发板文件夹。如果你有相应的板子,就不用修改直接用。我使用的是STM32F103核心的板子,因此我选了STM3210E-EVAL为模板,取名TEST(自取)。打开该文件夹,里面有2个文件夹,分别为RTOS和Standalone,RTOS是带操作系统的。我们打开Standalone,其中有6个文件夹,分别为Config、Demo、EWARM、MDK-ARM、TrueSTUDIO及User,具体的不一一介绍了。打开MDK-ARM,我们要的工程文件就在其中了。 打开工程,先点击如图左边红圈处编译一下,工程应该是没有错误的。然后根据你所使用的硬

相关文档
相关文档 最新文档