以正點原子學習視頻為基礎的文章
LWIP帶freeRTOS系統移植
準備資料/工程
1、lwIP例程1 lwIP裸機移植? 工程? ,? ?作為基礎工程? 改名為LWIP_freeRTOS_yizhi工程
2、lwIP例程6 lwIP_FreeRTOS移植? 工程
3、freeRTO源碼??
?打開https://www.freertos.org/網址下載FreeRTOS源碼包
省出麻煩的細節移植,直接使用1、2? 兩個工程移植
? 在? ?lwIP例程6 lwIP_FreeRTOS移植?工程中? ?
1、取出 Middlewares\FreeRTOS? 把FreeRTOS系統源文件移植到
2、取出? Drivers\SYSTEM? ? delay、sys、usart.c文件? 移植到
3、取出?\User??FreeRTOSConfig.h文件? 移植到
LWIP_freeRTOS_yizhi工程中
在工程中新建分組
LWIP_freeRTOS_yizhi工程作為基礎工程
分組1:Middlewares/FreeRTOS_CORE
Middlewares\FreeRTOS 當前文件夾下的全部c文件
分組2:Middlewares/FreeRTOS_PORT
1、Middlewares\FreeRTOS\portable\MemMang? ?的?heap_4.c文件
2、Middlewares\FreeRTOS\portable\RVDS\ARM_CM4F 的port.c文件
添加頭文件路徑
1、Middlewares\FreeRTOS\include
2、Middlewares\FreeRTOS\portable\RVDS\ARM_CM4F
移植支持lwip的freeRTOS系統文件
http://savannah.nongnu.org/projects/lwip/
網址下載lwIP源碼包和contrib包
1、在 contrib-2.1.0\ports\freertos 取得sys_arch.c?/ .h??
2、移植到? LWIP_freeRTOS_yizhi工程中??Middlewares/lwip/arch
并在工程中,添加到分組和添加包含路徑
修改配置文件
?1,修改lwipopts.h
(目標:需要,符合帶操作系統的配置文件)
因為基礎工程是用的裸機移植作為基礎,所以這個文件是用在裸機上的;所以需要更改找到stm提供的庫文件相關文件
FW_F4_V1.26.0\Projects\STM32469I_EVAL\Applications\LwIP \LwIP_HTTP_Server_Netconn_RTOS\Inc\? 路徑下的lwipopts.h替換本實驗的Middlewares\lwip\arch? ?lwipopts.h文件
ps:FW_F4_V1.26.0? ?stm官方資料包? ? ? ? ?
修改TCPIP的優先級 此處沒有實際的定義,所以改成5 如下
2、修改cc.h
(目標:注釋掉重復的變量)
“typedef int sys_prot_t”代碼注銷
3,修改lwip_comm.c/.h
(目標:刪除lwip_periodic_handle函數和修改lwip_comm_init 函數)
1、刪除 lwIP 輪詢函數 lwip_periodic_handle
2、修改 lwip_comm_init 函數
?直接移植好的工程? 后期源碼分析;路徑:?Middlewares\lwip\arch
?4,修改ethernetif.c/h
(目標:修改為帶操作系統的網卡驅動)
?修改low_level_init函數
修改 ethernetif_input函數
??直接移植好的工程? 后期源碼分析;路徑:?Middlewares\lwip\arch
1、創建任務ethernetif_input任務;
該任務獲取二值信號量,判斷是否接收到數據
然后在中斷函數中釋放;
2、ethernetif_input? 的相關中斷? 信號量釋放
釋放二值信號量,就是為了重復的操作
?5,修改ethrnet.c?
(目標:修改中斷優先級;修改中斷優先級,必須歸FreeRTOS內核管理)
??直接移植好的工程? 后期源碼分析;路徑:?Drivers\BSP\ETHERNET
優先級為6? 子優先級0
相關中斷函數
6、修改文件stm32f407xx.h
此處是跟freeRTOS系統有關;
把無符號刪除,直接改為4
7、修改文件stm32f4xx_it.c
屏蔽如下函數,因為存在重復定義
1、SVC_Handler
2、PendSV_Handler
3、SysTick_Handler
8、修改文件malloc.h 修改SRAM內存大小
9、新建freertos_demo.c/.h文件:
在User分組下,新建freertos_demo.c/.h文件、
freertos_demo.c:創建任務
freertos_demo.h:聲明入口函數
現在直接從好完成的工程中 移植? ?路徑:\User? ? ?后續源碼解析
10、main文件
現在直接從好完成的工程中 移植? ?路徑:\User? ? ?后續源碼解析
探索者/電機板三處不一樣需要修改
1、PHY復位引腳不一樣? ? 探索者:PA? 8? ? ?電機開發板 PA4
2、探索者pyh芯片:YT8512C??? ? ? ? 電機開發板芯片:PHY_TYPE
3、mac地址不一樣
LWIP帶FreeRTOS操作系統的啟動流程
啟動流程的原理,基本上和裸機移植的啟動原理流程一樣;除了裸機只能使用RAW限制外;
只不過添加了系統,觸發不一樣而已。比如二值信號量、創建任務等
1、函數?void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
..\..\Middlewares\LWIP\src\api\tcpip.c??
/*** @ingroup lwip_os* Initialize this module:* - initialize all sub modules* - start the tcpip_thread** @param initfunc a function to call when tcpip_thread is running and finished initializing* @param arg argument to pass to initfunc*/
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{lwip_init();tcpip_init_done = initfunc;tcpip_init_done_arg = arg;if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) { //創建一個郵箱LWIP_ASSERT("failed to create tcpip_thread mbox", 0);}
#if LWIP_TCPIP_CORE_LOCKINGif (sys_mutex_new(&lock_tcpip_core) != ERR_OK) { //創建一個互斥鎖LWIP_ASSERT("failed to create lock_tcpip_core", 0);}
#endif /* LWIP_TCPIP_CORE_LOCKING */sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);//創建一個線程
}
2、函數tcpip_thread? 任務
..\..\Middlewares\LWIP\src\api\tcpip.c
/*** The main lwIP thread. This thread has exclusive access to lwIP core functions* (unless access to them is not locked). Other threads communicate with this* thread using message boxes.** It also starts all the timers to make sure they are running in the right* thread context.** @param arg unused argument*/
static void
tcpip_thread(void *arg)
{struct tcpip_msg *msg;LWIP_UNUSED_ARG(arg);LWIP_MARK_TCPIP_THREAD();LOCK_TCPIP_CORE();if (tcpip_init_done != NULL) {tcpip_init_done(tcpip_init_done_arg);}while (1) { /* MAIN Loop */LWIP_TCPIP_THREAD_ALIVE();/* wait for a message, timeouts are processed while waiting */TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg); //獲取一個消息 阻塞if (msg == NULL) {LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));LWIP_ASSERT("tcpip_thread: invalid message", 0);continue;}tcpip_thread_handle_msg(msg);//判斷消息類型 遞交網絡層 IP層 還是arp層}
}
3、添加網卡
..\..\Middlewares\LWIP\src\api\tcpip.c
函數一樣
4、tcpip_inpkt函數
/*** Pass a received packet to tcpip_thread for input processing** @param p the received packet* @param inp the network interface on which the packet was received* @param input_fn input function to call*/
err_t
tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
{
#if LWIP_TCPIP_CORE_LOCKING_INPUTerr_t ret;LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));LOCK_TCPIP_CORE();ret = input_fn(p, inp);UNLOCK_TCPIP_CORE();return ret;
#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */struct tcpip_msg *msg;LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);if (msg == NULL) {return ERR_MEM;}msg->type = TCPIP_MSG_INPKT;msg->msg.inp.p = p;msg->msg.inp.netif = inp;msg->msg.inp.input_fn = input_fn; //構建消息if (sys_mbox_trypost(&tcpip_mbox, msg) != ERR_OK) {//用郵箱發送消息memp_free(MEMP_TCPIP_MSG_INPKT, msg);return ERR_MEM;}return ERR_OK;
#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
}