当前位置:首页 > 单片机 > 单片机
[导读]一般采用的步骤:1.深入了解所采用的系统核心2.分析所采用的C语言开发工具的特点.3.编写移植代码.4.进行移植的测试5.针对项目的开发平台,封装服务函数.首先,是芯片的中断处理机制,如何开启,屏蔽中断,可否保存前一次中

一般采用的步骤:
1.深入了解所采用的系统核心
2.分析所采用的C语言开发工具的特点.
3.编写移植代码.
4.进行移植的测试
5.针对项目的开发平台,封装服务函数.
首先,是芯片的中断处理机制,如何开启,屏蔽中断,可否保存前一次中断状态,芯片是否有软中断或陷阱指令
已经将图片移植成功,是一件很快乐的事情.
现在要将网络也加进去,看一看,想什么办法能够办到.
将lwip组织起来:
lwipopts.h
cc.h
timer.h
Timer0_Init(void)
Timer1_Init(void)
Delay10ms(unsigned short T) ;
Undefine_Init(void) ;
volatile 跟const 相反,可能在外界的影响下改变.编译器不再对其进行优化.
关于时钟中断,可有对应的例子,没有什么关系,如果想把这两个合并在一起不太可能,
因为硬件不同罢了.
Timer0
Timer1 所有的都为了ucos-ii //time tick时钟激发.
SYSTEM CLOCK CONTROL ;
Main.c只是测试一个移植了,只能在串行口里输出测试结果,但并不能表示它已经完成了,对lwip移植任务.
/******************************************************************************/
/--------------------------------/
/最后发现这只是一个应用程序嘛:
/还没有到初始化硬件的地步吧.
/--------------------------------/
lwip_Main.c 其中只有一个函数,这个函数就可以完成你所要的lwip?
看看这个lwip_Main做了那些事情:
1.定义ip结构体 struct ip_addr,netmask ,gw ;
2.定义信号量:sys_sem_t sem ;
3. 初始化一些东西.
初始化 TCP/IP 之前为何还需要实始化系统?
IP4_ADDR(&gw,0,0,0,0) ;
IP4_ADDR(&ipaddr,0,0,0,0) ;
IP4_ADDR(&netmask,0,0,0,0) ;
netif = netif_add(&ipaddr,&netmask,&gw,ethernetif_init,tcpip_input) ;
netif_set_default(netit) ;
dhcp_start(netif) ;
或者形如如此的形式,其的IP地址可以设定的.
udpecho_init() ;
但是这里跟本就没有任务,
是否要把此lwip添加到任务里去?
this is for web page ;in httpd file
httpd.h:
httpd_init() ;
httpd_thread() ;
这里的函数很简洁,但是何时使用httpd_init(void) ;
到现在还没有发现,有那些东西需要做的,
没有步骤
App:应用程序没有必要在这里看,
因为其中一些东西,跟本就不必要的
而需要理解其中的实质,怎么把lwip移植成功?
另外可以借助原先一个例子,可以比较读取,看是否已经到了熟习,或者可以用上派场上.
如果说lwip里没有牵涉到硬件问题,那么我们可以把它当一个库来看待
现在要怎么去使用它的函数,
另一方面,怎么样来初始化其对应的网络接口:8019
问题关键不再放在这个上面,应该更有意义的是看LPC2284.h里是怎么去实现的,
然后我们再把它的实现过程移植s3c2440上去,可以看到结果的时候,就是照搬就快成功了.
而在lwip文件夹下的所有文件已经实现了
这里的代码一定是很比较稳定的,已经实现得比较好的.现在是实现它看看怎么样让调用起它来.
**************************************
如果目标板的初始化,
一:在main里可能就只用到那一个函数:
TargetInit() ---在图片例子里也已经完成了.不是必须的.
二:RTL8019
这个是网卡驱动:
要知道网卡的指针是怎么回事:
网卡的地址:
timer0_init()初始是什么事情?
现在关键问题在:s3c2440代替LPC2294
可不可以把这个封装更简单一些,以便使用更方便?
搞清里面的差别,另外看看,为什么要在LPC2294要用到Timer
原来有网卡驱动需要:
处理计时器:
timeout()函数按受两个参数:
第一指向变量的指针,存储了开始时间,
第二:保存了以秒计数的超时时间.当超过超时间时,该项函数触发一个事件,
开始时间中重新写入当前时间并返
并返回一个非0值.
------------------------------------
应该封闭起lwip,它已经跟其它任何初始硬件无,
只要保证调用它的函数能够起作用,正确使用它即可.
没有必要去读它里的任何一个文件,因为它是协议.
如果不对硬件初始化,那是不可能调用到lwip里的函数的.
注意:
1.可能要使用lwIP时,会做成一个任务,
还要给它分配优先级.Task.h
2.Target.c里去初始化网卡. 找出config.h,因为Target.c里只引用了它.但是好像在config.h里并不怎么实现它.
3.虽然Timer很重要,但是我想没有必要把它也拿出来细究,因为不涉及到lwip
4.
没有看到有那个函数调用汉字打点函数,
为何当你调用Lcd_printf()时也可以出现汉字?
Uart_SendString(pUartMsg) ;
lcd.c:一个向lcd里发送,
printf.c一个向串行端口发送.
Nand.c没有被使用到.
最好想法把所有无关的都剥离出来,然后把相关的分成块.
可以像其它一样:
1.初始化 :像 lcd,printf-Uart,[xxx_init()]
2.将那些相应的函数放到任务里.不停执行.
3.将在单独文件里实现函数.
4.函数里去调用lwip协议函数.
-----------------------------------------------------
分作两部分了.一部分是RTL8019,另一部分:lwip
-----------------------------------------------------
5.RTL8019对网卡的实现函数.
6.lwip实现栈,调用其中的函数实现--栈.
------------------------------------
dm9000已经在RTL8019实现,UBOOT已经有对dm9000实现,可以包装一下,
rtl8019_netif
最好就与主板上分离开,
只要网卡对应地址是
权衡那一种更容易达到效果:
rtl8019一般不是在ARM上,没有办法知道其驱动,
而dm9000是驱动,却又没有与lwip建立关系.
包装dm9000一下,
lwip需要的网络接口,初始化接口:
ethernetif_init()
low_level_output()
ethernetif_input()
ethernetif_init()负责网络的接口初始化.底层收发包函数,MAC地址和硬件初始化等.
low_level_output()负责将上层传来的网络包通过DM9000发送出去.
重新包装DM9000驱动
在UBoot 里有DM9000驱动即可用到.
需要以下几个函数:
int dm9000_eth_init(struct netif*db) ;
void dm9000_eth_send(volatile void *,int) ;
int dm9000_eth_send_done(int) ;
int dm9000_eth_rxlen(void);
int dm9000_eth_rx(U8*rdptr,U16 RxLen) ;
int dm9000_drop_frame(U16 RxLen) ;
其中,只有发送和接收两个函数需要改动,
LWIP上层传给low_level_output()的数据包,
将根据MSS和MTU等值切割成一个个的小包,分别填充到链表pbuf里。
**************************************
struct netif{
struct netif *next ;
struct ip_addr ip_addr ;
struct ip_addr netmask ;
struct ip_addr gw ;
err_t(*input)(struct pbuf *p , struct netif *inp) ;
err_t(*output)struct netif*netif,struct pbuf *p,struct ip_addr *ipaddr) ;
err_t(*linkoutput)(struct netif*netif,struct pbuf *p) ;
#if LWIP_DHCP
struct dhcp *dhcp;
#endif
/** number of bytes used in hwaddr */
unsigned char hwaddr_len;
/** link level hardware address of this interface */
unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
/** maximum transfer unit (in bytes) */
U16 mtu;
/** flags (see NETIF_FLAG_ above) */
U8 flags;
/** link type */
U8 link_type;
/** descriptive abbreviation */
char name[2];
/** number of this interface */
U8 num;
};
//alt_lwip_dev结构体描述了符合LWIP规范的网络端口设备
struct alt_lwip_dev
{
/* The netif pointer MUST be the first element in the structure */
struct netif* netif;
const char* name;
err_t (*init_routine)(struct netif*); //初始化函数
void (*rx_routine)(); //数据接收函数
};
//alt_lwip_dev_list:设备链表
typedef struct
{
alt_llist llist; /* for internal use */
alt_lwip_dev dev;
}alt_lwip_dev_list;
typedef struct alt_llist_s alt_llist;
struct alt_llist_s {
alt_llist* next; /* Pointer to the next element in the list. */
alt_llist* previous; /* Pointer to the previous element in the list. */
};
//在LWIP定义的这些结构体类型的基础上,DE2_WEB_SERVER定义了针对DM9000网络接口的一个结构体
typedef struct
{
alt_lwip_dev_list lwip_dev_list; //与之关联的设备链表
int base_addr; //寄存器的基地址
int irq; //中断编号
u_char hwaddr[6]; //MAC地址
int index_offset;
int data_offset;
int dm9k_tx_space;
int dm9k_linked;
sys_sem_t arp_semaphore;
sys_sem_t tx_semaphore;
} alt_avalon_dm9k_if;
先让驱动起来,移植s3c2440加到其它程序一起.
焦海波那个有可能考虑.因为那一些写的比较完整,但总是低估了它的难度.
果然,焦已经形成文档了
下载下来看看,或许有解的机会.
移植被LwIP到一个新的目标系统时,只需要修改这个接口艰险可,那个接口? sys_arch
操作系统模拟层(sys_arch) 它在底层操作系统和LwIP之间提供了一个接口?
sys_arch需要为LwIP提供信号量(sem)和邮箱(mailboxes)
信号量是可以计数信号量,也可以二值信号量,---LwIP都可以正常工作,
邮箱用于消息传递.
int sys_init()
sys_sem_t sys_sem_new() ;
sys_sem_freem() ;
sys_sem_signal()
sys_arch_sem_wait() ;
sys_mbox_t sys_mbox_new() ;
sys_mbox_free(sys_mbox_t mbox) ;
void sys_mbox_post(sys_mbox_t mbox,void *msg)
u32_t sys_arch_mbox_fetch(sys_mbox_t mbox,void **msg,u32_t timeout)
struct sys_timeouts *sys_arch_timeouts(void)
如果底层操作系统支持多线程并且LwIP中需要这样的功能,则一定要实现这个函数.
sys_thread_t sys_thread_new(void(*thread)(void*arg),void *arg,int prio) ;
sys_prot_t sys_arch_protect(void)
void sys_arch_unprotect(sys_prot_t pval) ;
以上是Lwip与操作系统关系.
----------------------------------------------------------------------------
OS支持的模拟层需要添加的头文件:
cc.h 与硬件平台以及编译器相关的环境变量及数据类型声明文件.或者一些移到sys_arch.h中.
与编译器相关的LwIP结构体
PACK_STRUCT_FILED(x)
PACK_STRUCT_STRUCT
PACK_STRUCT_BEGIN
PACK_STRUCT_END
与平台相关
LWIP_PLATFORM_DIAG(X)
memset() 如果编译器不提供,这个文件一定要包含它的定义,即memset()

perf.h
sys_arch.h sys_arch.c的头文件
整个移植所依赖的操作系统平台.
OK 文件夹和文件指定的路建立后,
先去定数据类型定义.
cc.h:
typedef unsigned char u8_t
typedef signed char s8_t
typedef unsigned short u16_t ;
.......
允许它们定义,没关系,跟系统内其它的定义不相冲突,如果全部换成一致也不见得好使用.
因为分为不同的分块移植的.
信号量操作函数
邮箱操作函数:
特别注意:投递到邮箱中的消息只能是一个指针.
一:邮箱一次能够接收多条消息比仅接收一条消息更加有效.
二:邮箱中的消息是一个指针.
__ilvSetLwIP()
实现网络驱动与LwIP的接口,是网络系统得以顺利运转的源动力,它会告诉LwIP网络数据的发送出口,建立网络数据的接收入口并实现
接收入口与LwIP处理入口的对接.
当底层网络收发设备进入正常工作状态,网络数据能够正常流入流出LwIP后,这个函数进行的工作会结束.
我需要一款纯的Lwip源代码,可能都是别人移植了后,影响到我的思路.
下载一个原版的后,不用再去查看别人移植的,现在的工作是怎样先把这个lwip先移植到uCos-ii里去,
暂时还不让它跑起来,按照常规的想法是把其思路先移植上去再说.看看有什么效果.再实现驱动.
采用一个干净的lwip源码是很有用处的.
一:可以就此完全不用顾及别人的移植思路,
二:自己移植出错容易找出来,
三:用时会快一些.
实际上这些都是在这里操作.
LwIPEntry.c这个文件也像LwIP_main.c文件一样.是重中之重.
没有把硬件东西提取来,有点过失,
如果再把其中的东西提取来,就有点更直接的效果.
ethernetif_init()初始化底层接口:
Lwip作者已经帮我们完成大部分工作,我们只要把框架内完成与底层硬件相关的部分即可.
ethernetif 是一个结构体:用来描述网络硬件设备(通常说的网卡)
它唯一不可缺少的是网卡的MAC地址.
ethernetif->ethaddr ====指针指向netif中保存的网卡MAC地址.
low_level_output()
与硬件联系的函数,
指定任务优先级,最好定为最高优先级,如果确定存在更高优先级,一定要让更高优先级任务占用CPU使用权时间不能太长,
否则将严重影响网络性能.
ethernetif.c是硬件的抽象层.
实现了它,不一定可以,还需要硬件驱动.
lib_emac.c专门用来建立驱动函数:
硬件驱动:它不仅包括EMACInit()
EMACReadPacket() EMACSendPacket() 分别负责网络数据包的接收和发送.
这个已经在处理硬件了.
怎样使用硬件工人和顺利就得有这么一种慢慢使用的过程了.
所以网卡的实现也只有三个函数吗?
EMACInit()
EMACReadPacket()
EMACSendPacket()
怎样把问题简化:
1.lwip
2.dm9000
3.lwip->ucosii 这个可以暂时搞定: ---------------------返正先把这个搞定再说.-------------------
4.lwip->dm9000
lwip->dm9000详细问题,要解决几个问题:
1.EMAC发送和接收中断处理函数 --dm9000看看中断处理函数.
2.EMACSendPacket 发送
找来找去没有发现什么新的东西可以模仿,不如自己写一个.
首先把LwIP移植之后再说,其它的就不必太在意.
先把一步做完,
然后再考虑网络驱动的问题.
文件结构也很重要,不然可能有一些会搞混乱.
在此中间,焦海波采用了链表来构建邮箱,
而我将采用另一种方式:队列,让队列给uCOS-II去处理更好一些.
这样把LwIP实现了后,再就是硬件网卡驱动.
首先添加LwIPEntry.c文件,
看来我在dm9000 花费了太多心血,倒头来还只是一个linux版的,而且一点进展都没有,
怎么办?
我想把它搞掉.
算是移植完成了,但是没有调试,因为可能还有许多错误,要清除这些错误,得一段时间.
怎么把平台里的网络相关函数抽象出来?
直接用到一些函数,可以用来发送Ping Webpage 之类,看看,可不可以脱离硬件函数.
怎么办,ADS不可以直接加工程.
是否需要有更多了解.
我是怎么样把我所做的添加上去呢?
难道像昨晚那样一个一个添加?
其实文件夹跟本就不存于mcp工程里.
编译已经成功,但是一些应该使用的功能可能还没有达到你的要求,
现在的工作是怎样把相应的功能加进去,即是怎样把Lwip 栈协议加进去,
实现通信.
出现的另外一个问题,为何在外部的驱动,没法在lwip里调用,是否是因把dw9000加到了外面?
现在的问题只是:驱动出现了问题,如果把驱动处理好
可能一切都好办了.
但驱动如何才能添加上去.
因为其它的驱动看似很容易得到,但是不符乎我的芯片上的意思,
我决问自己写dm9000的驱动.
有文档,也有别人的例子,应该比较容易一些.
编写驱动程序:
注意处理器所用的C编译器使用"大端格式","小端格式"
只有两个可以直接被除数处理器访问的寄存器,
CMD 端口和DATA端口,
(DM9000中有许多控制和状态寄存器) 访问这些控制,状态寄存器的方法:
1.将寄存器的地址写到CMD端口
2.从DATA端口读写寄存器中的数据.
1-3
新建一个试一试:
全部用新的就可以了,自己新建一个即立成功.没有什么完成不了,
可能还是因为宏的问题,
所以从dm9000x.h里把不必要的东西都裁减掉.
高位片选地址:
DM9000地址端口= 高位片选地址+300H+0H
DM9000数据端口= 高位片选地址+300H+4H
DM9000的高位片选地址将是多少?
0x90000A46
现在已经编译通过,
基本的修改已经完成,怎么让OS启动
虽然已经移植完成了,但没有调试,没有看出来是否已经成功还没有定论
肯定还会有问题:
1.驱动dm9000虽然完成了,但没有测试,是否完备
2.LwIP栈协议还不一定移植成功,因为申请的空间还不明确.
3.添加的应用程序可能存在一定的问题,如果没有其它问题,应用程序都可以顺利执行.
4.是否还需要添加httpd.c文件,让其当服务,用来访问,如果可以,则应该一试,以防备其它的不成功,采取这个可以能过,
5.也算是网络通顺的一个实例.(但是有一个问题即是,这个是里面是否)
移植的方式很多,但要想成,得有一个章程.
如下是linux里的移植过程:
sys_arch.c里有另一种操作:
把有一些东西分开了,
初始化网卡与网卡数据接收中断:
extern void eth_init(void) ;
extern void eth_rx(int irq,void*devid) ;
而我自己移植里没有看到有那里初始化硬件,也没有看到那里调用其中的网卡接收中断数据函数
网卡初始化.
有low_level_init()是网卡初始化?不是,而网卡初始化是硬件文件里定义.
实际上都写到这个文件里了,sys_arch.c
1.初始化网卡和网络接口:
err_t init_ethernetif(struct netif*netif)
{
//初始化网卡
eth_init() ; //当然在硬件文件里实现
ethernetif_init(netif); //初始化网络接口,当然也会在硬件文件里实现,
return ERR_OK ;
}
2.初始化lwip
void sys_init(void)
{ //这里所做的一切都是一样的.没什么可以大作文件,看看即可.
netif_init() ;
mem_init() ;
memp_init() ;
pbuf_init() ;
.....
//这里把接收网卡数据的线程,创建起来.这里使用单独的线程执行ethernetif_input() ;
sys_thread_new(ethernet_rev,(void*)0,TCPIP_THREAD_PRIO) ;
}
//那我看看我的移植,没有初始化硬件.
我认为焦海波之做法不可靠,他把邮箱分成多个邮箱,再用链表链起来,
而其实可以采有和OS系统里创建队列,只建起队列即可,操作也在对队列实行
没有必要再去创建多个邮箱链表.
总感到别扭,为什么采用那种方式?
是否可以改革,把之前的所想的都改掉呢?
如果可以通了,就好.但关键是不知道是否能通啊.
dm9000.c里实际上也只是有三个函数:
重要的三个函数:
DM9000_init()
eth_rx()
eth_send()
而给出定义为外部变量时也采用了同样的方式:
extern DM9000_init()
extern eth_rx()
extern eth_send
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//一直没有bootloader ,所以重新找了一个.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
虽然移植完成了,但是测试时候,连lcd,com都没有成功,怎么办?
是否因为调用了OS里的sys_thread_new 之后,也把其中的任务破坏了?
是否还有一种可能是因为双重使用了ethernet.c而另一个只是用了一个名字为:
ethernetif.c
所以要么就此脱离移植笔录,
要么全部按移植笔录来操作,而不另外添加任务新东西.
怎样保持一个干净的东西,需要对此做一些修整.
可以把DM9000里的驱动先加进去,而不使用LwIP看结果如何.
在DM9000.c里设一些可以返回值Uart_printf() ; 这样的函数,让其运行过来,看看结果如何?
即调试一样的.如果DM9000驱动成功,再把LwIP加进去.
先让这个跑起来:myucos.rar
是否思路不清晰,造成了多加了一些任务?
只专门研究-lwip1.1.3
要不把驱动放到里去让其运行,看看结果,把它的每个函数都加进去试.
ADS1.2是否可以不需要平台调试呢?
先来看看模拟平台.模拟平台没办法测试丢弃.
再把LwIP移植工作做成功,做到最简单.
我让他全部是光光的,什么都没有,也不另添加什么新文件进去.
两个工程都基本完成,再烧到板子里试,看能不能跑起来,如果能,说明是两者都没破坏,

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2023年2月16日 /美通社/ -- 近日,诺华中国宣布与中国红十字基金会正式启动"中国地中海贫血救助项目"广西地区专项援助,将在当地定向资助困难家庭地中海贫血患儿,同时通过相关医生培...

关键字: BSP 控制 移植 大众

北京2022年12月7日 /美通社/ -- 2022年12月3日,由高博医学(血液病)广东研究中心南方春富(儿童)血液病研究院、南方医科大学南方医院共同主办的高博医学论坛·华南造血干细胞移植论坛通过线下线上...

关键字: 移植 HD PID 血细胞

捐款近4000万 上海2022年12月7日 /美通社/ -- 2022年12月7日下午,中芯国际"芯肝宝贝计划"十年纪念暨2022年度捐赠仪式在上海仁济医院举行。十年来,该项目捐赠善款总额近4000...

关键字: 中芯国际 移植

北京2022年11月14日 /美通社/ -- 2022年10月,高博医学(血液病)北京研究中心北京高博博仁医院造血干细胞移植科迎来了五周岁"生日"。在吴彤主任带领下,移植科于2017年从无到有,历经五...

关键字: 移植 OS MT CD

上海2022年11月6日 /美通社/ -- 在第五届中国国际进口博览会期间,武田制药携5款创新产品亮相武田罕见遗传与血液疾病领域专场发布会。用于移植后抗巨细胞病毒(CMV)感染或疾病治疗[1]的马立巴韦[2]迎来&quo...

关键字: 移植 BSP CD FDA

亘喜生物科技集团宣布正在中国开展的、旨在全面评估GC007g治疗复发/难治性急性B淋巴细胞白血病效果的1/2期注册性临床试验顺利进入2期研究阶段,首例入组患者已给药。GC007g是亘喜生物旗下的一款靶向CD19的供者来源...

关键字: 移植 CD

北京2022年9月9日 /美通社/ -- 诺诚健华(香港联交所代码:09969)今天宣布,tafasitamab (Minjuvi®)联合来那度胺治疗不适合自体干细胞移植 (ASCT) 条件的复发/难治弥漫性大B...

关键字: VI NJU BSP 移植

苏州2022年8月19日 /美通社/ -- 近日,华中科技大学同济医学院附属协和医院心外科董念国教授团队运用与心擎医疗联合研发的短中期体外全磁悬浮心室辅助装置MoyoAssist®,成功救治三例危重的终...

关键字: 磁悬浮 移植 IC 静脉

上海2022年8月17日 /美通社/ -- 2022年8月16日,聚焦于基因和细胞治疗的上海邦耀生物科技有限公司(以下简称"邦耀生物")宣布,其...

关键字: CD 移植 BSP ISP

苏州2022年6月28日 /美通社/ -- 2022年6月23日,首都医科大学附属北京安贞医院(以下简称安贞医院)与苏州心擎医疗技术有限公司(以下简称心擎)在北京、苏州两地线上连线,隆重召开体外心室辅助系统临床...

关键字: BSP 磁悬浮 创始人 移植
关闭
关闭