欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

標(biāo)題: 詳解STM32F7 TCPServer工程 [打印本頁(yè)]

作者: 51hei大小    時(shí)間: 2016-6-17 16:38
標(biāo)題: 詳解STM32F7 TCPServer工程
     STM32F7-Discovery資源豐富、外設(shè)眾多,除了最顯眼的那個(gè)觸摸屏外,估計(jì)關(guān)注比較多的就是網(wǎng)絡(luò)的功能了。網(wǎng)上有一些例程都是HTTP、FTP、Telnet的,卻沒(méi)有最基本的TCP的例子(也許我沒(méi)找到),所以用了一上午的時(shí)間來(lái)嘗試一下TCP的用法。TCPIP協(xié)議棧很復(fù)雜,我不會(huì)浪費(fèi)時(shí)間去深究這些東西,因?yàn)楫吘棺龅氖菓?yīng)用層的程序,經(jīng)過(guò)MDK的封裝,已經(jīng)完全可以?huà)侀_(kāi)具體的協(xié)議部分,只調(diào)用接口即可完成通訊。
    又提到了MDK的中間件的封裝,有了這個(gè)東西減少了我們很多很多工作,只需要鼠標(biāo)指指點(diǎn)點(diǎn)就可以完成眾多的配置選項(xiàng),所以我沒(méi)有理由去拒絕使用它,除非你反感MDK,那當(dāng)我沒(méi)說(shuō)。

    閑話(huà)少敘進(jìn)入正題,首先建立一個(gè)STM32F7的工程。建立的過(guò)程不再重復(fù),如果真的不會(huì),請(qǐng)參考《 【STM32F7】STM32F7開(kāi)發(fā)篇-超詳細(xì)操作步驟》進(jìn)行操作。
    下面開(kāi)始勾選各種支持庫(kù),也是MDK最大的特色。本來(lái)不想再抓圖了,無(wú)奈靠文字描述估計(jì)寫(xiě)這個(gè)帖子會(huì)累死,所以還是湊合看圖吧。
    打開(kāi)配置界面,F(xiàn)7的配置項(xiàng)比以往的多了很多很多,不過(guò)很清晰,一個(gè)一個(gè)來(lái)看。

***********************************************************************************************
    板級(jí)支持(Board Support),專(zhuān)門(mén)針對(duì)某種板子提供的驅(qū)動(dòng)。為了可以在任意的STM32F7開(kāi)發(fā)板上使用,這項(xiàng)選不選隨意。

    1.CMSIS部分,操作系統(tǒng)相關(guān),有了系統(tǒng)好辦事,而且包括了網(wǎng)絡(luò)硬件的驅(qū)動(dòng),所以此項(xiàng)必選。
    CORE是核心部分,不能少
    Keil RTX是操作系統(tǒng),可以開(kāi)線(xiàn)程
    Ethernet MAC是MAC驅(qū)動(dòng)
    LAN8742A是STM32F7-Discovery的物理收發(fā)器驅(qū)動(dòng)

    2.STM32F7的硬件層驅(qū)動(dòng)部分,可以選擇Classic,也可以用STM32CubeMX。如果選了STM32CubeMX,就要使用這個(gè)軟件來(lái)生成配置代碼再放到MDK里。Classic足夠了,是MDK自帶的。
    其中Startup必選,這個(gè)是啟動(dòng)文件
    其他的,如Common、Cortex都需要選上。這個(gè)圖不全,下面還有PWR、RCC都需要選上。當(dāng)然多選了沒(méi)有關(guān)系,少選的話(huà)這個(gè)配置窗體會(huì)實(shí)時(shí)顯示依賴(lài)關(guān)系,依賴(lài)項(xiàng)沒(méi)有選上會(huì)用橘黃色標(biāo)識(shí),提示應(yīng)該選擇。


    3.最后一部分,網(wǎng)絡(luò)庫(kù)的支持。這里就是封裝好的網(wǎng)絡(luò)相關(guān)的中間件了,省去了寫(xiě)代碼、調(diào)試的工作。
    CORE必選,ETH別忘了至少加一個(gè)網(wǎng)絡(luò)接口,TCP、UDP也要選上。即使不用UDP,不選的話(huà)編譯時(shí)會(huì)報(bào)錯(cuò)。
    在Service中,提供了HTTP、FTP、Telnet等支持包,這里沒(méi)有用上,所以沒(méi)選。如果開(kāi)發(fā)相關(guān)程序,可以自行選擇。


************************************************************************************************
    中間件選擇完了,會(huì)在工程中添加許多對(duì)應(yīng)的文件。展開(kāi)工程樹(shù),所有帶有黃鑰匙的文件都是不需要更改的,所以略過(guò)不看,只看各種配置文件。

    1.RTX_Conf_CM.c,操作系統(tǒng)相關(guān)的配置。雙擊該文件后代碼在右邊顯示,但是直接看代碼可沒(méi)那么好看,所以用MDK提供的功能:Configuration Wizard配置精靈就方便多了。
    這里面改動(dòng)的不多,主要是“RTOS Kernel Timer input clock frequency”,STM32F7是216MHz,改成216000000,216后面6個(gè)0,別寫(xiě)錯(cuò)了。
    另外“Defualt Thread stack size”和“Main Thread stack size”要改大一些,400和800。普通小程序無(wú)所謂用默認(rèn)的就行了,但是一旦用了某些協(xié)議;驁D形界面之類(lèi)的,默認(rèn)的就不夠了,如果不改會(huì)在運(yùn)行時(shí)進(jìn)入osError,然后就完蛋了。

    2.RTE_Device.h,這是STM32F7需要使用的外設(shè)的使能和引腳配置。這個(gè)工程只操作網(wǎng)絡(luò),所以其他的都沒(méi)有勾選。
    選擇之前應(yīng)該看看數(shù)據(jù)手冊(cè),不要選錯(cuò)了,或者從STM32CubeMX里看也可以,不需要深究,選對(duì)即可。



    3.Net_Config_ETH_0.h,這個(gè)就是剛才添加的那個(gè)ETH接口了。這個(gè)配置就簡(jiǎn)單多了,都是常用的,也就是地址、網(wǎng)關(guān)、DNS什么的,最下面的“Dynmic Host Configuration”是控制自動(dòng)獲取網(wǎng)絡(luò)還是使用配置項(xiàng)的,隨意吧。至于“MAC Address”,有默認(rèn)值了,但是為了便于在眾多的連接中區(qū)分,所以我改成了0x1234567890,一會(huì)兒就能看到。



    4.Net_Config.c,最后一個(gè)了,也是最簡(jiǎn)單的一個(gè)!癓ocal Host Name”就是用于顯示的主機(jī)名。更改后編譯燒寫(xiě)到板子中,已經(jīng)可以正常聯(lián)網(wǎng)了,因?yàn)锳RP的功能包括在里面了,跟路由通訊是正常的。打開(kāi)路由的界面,板子的名字、IP、MAC顯示出來(lái),連接正確。


************************************************************************************************
    所有的配置項(xiàng)完成,接下來(lái)該寫(xiě)程序了。大部分功能已經(jīng)完成,代碼量相對(duì)少了很多,節(jié)省了不少時(shí)間。



    系統(tǒng)時(shí)鐘配置,可以使用各種工具自動(dòng)生成代碼拷過(guò)來(lái),自己寫(xiě)的話(huà)就麻煩多了,我才不會(huì)去寫(xiě)。

    MPU設(shè)置和Cache設(shè)置。MPU也就是內(nèi)存保護(hù)單元,設(shè)置起始地址、長(zhǎng)度、讀寫(xiě)權(quán)限以及緩存等,然后再打開(kāi)I-Cache、D-Cache,用于提高性能。

    程序入口點(diǎn),這里我開(kāi)了個(gè)主線(xiàn)程,沒(méi)什么用,習(xí)慣罷了。while里要調(diào)用net_main函數(shù),用于處理網(wǎng)絡(luò)的各種事件,具體的執(zhí)行內(nèi)容可以參考手冊(cè)。MDK提供的中間件沒(méi)有開(kāi)放源碼,所以怎樣實(shí)現(xiàn)的是看不到的,不過(guò)可以看看lwip的源碼,大同小異。



    真正自己的代碼來(lái)了,就這么一點(diǎn)點(diǎn),還包括了接口函數(shù)在內(nèi)。
    首先執(zhí)行的是net_initialize,初始化函數(shù),只要執(zhí)行一次就行了,這個(gè)必須在所有操作前調(diào)用一次。
    然后就是Listen了,首先get一個(gè)socket,其實(shí)就是綁定過(guò)程,然后再按照指定的端口監(jiān)聽(tīng)。監(jiān)聽(tīng)過(guò)程中的事件都在回調(diào)函數(shù)里處理。
    回調(diào)函數(shù),處理Client的連接、斷開(kāi)、數(shù)據(jù)傳輸?shù)仁录,一個(gè)switch解決。
    發(fā)送數(shù)據(jù),我又創(chuàng)建了一個(gè)線(xiàn)程,不過(guò)單純是為了代碼好寫(xiě),可以精確定時(shí)、而且方便啟動(dòng)停止,代碼量最少,否則還要再去配置SysTick,太麻煩了。
   
    整個(gè)代碼的作用就是監(jiān)聽(tīng)端口,當(dāng)有Client連接進(jìn)來(lái)后,每秒發(fā)送一次字符串“abcdern”,沒(méi)了。

    看效果,功能實(shí)現(xiàn)。沒(méi)有加上各種容錯(cuò)機(jī)制,畢竟只是為了實(shí)現(xiàn)功能,不是做產(chǎn)品。

    全文完。發(fā)現(xiàn)寫(xiě)帖子的時(shí)間和寫(xiě)代碼的時(shí)間差不多,一天就過(guò)去了,我暈。
  1. #include "cmsis_os.h"
  2. #include "stm32f7xx_hal.h"

  3. #ifdef ServerTCP
  4.         #include "ServerTCP.hpp"
  5. #endif

  6.         extern uint32_t os_time;

  7. /*****************************************************************************/
  8. /**
  9.   * System Clock Configuration
  10.   *   System Clock source            = PLL (HSE)
  11.   *   SYSCLK(Hz)                     = 216000000
  12.   *   HCLK(Hz)                       = 216000000
  13.   *   AHB Prescaler                  = 1
  14.   *   APB1 Prescaler                 = 4
  15.   *   APB2 Prescaler                 = 2
  16.   *   HSE Frequency(Hz)              = 25000000
  17.   *   PLL_M                          = 25
  18.   *   PLL_N                          = 432
  19.   *   PLL_P                          = 2
  20.   *   PLL_Q                          = 9
  21.   *   VDD(V)                         = 3.3
  22.   *   Main regulator output voltage  = Scale1 mode
  23.   *   Flash Latency(WS)              = 7
  24.   */
  25. static void SystemClock_Config (void) {
  26.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  27.   RCC_OscInitTypeDef RCC_OscInitStruct;

  28.   /* Enable HSE Oscillator and activate PLL with HSE as source */
  29.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  30.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  31.   RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  32.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  33.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  34.   RCC_OscInitStruct.PLL.PLLM = 25;
  35.   RCC_OscInitStruct.PLL.PLLN = 432;  
  36.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  37.   RCC_OscInitStruct.PLL.PLLQ = 9;
  38.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  39.   /* Activate the OverDrive to reach the 216 MHz Frequency */
  40.   HAL_PWREx_EnableOverDrive();
  41.   
  42.   /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
  43.   RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  44.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  45.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  46.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
  47.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
  48.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
  49. }

  50. /**
  51.   * Configure the MPU attributes as Write Through for SRAM1/2
  52.   *   The Base Address is 0x20010000 since this memory interface is the AXI.
  53.   *   The Region Size is 256KB, it is related to SRAM1 and SRAM2 memory size.
  54.   */
  55. static void MPU_Config (void) {
  56.   MPU_Region_InitTypeDef MPU_InitStruct;
  57.   
  58.   /* Disable the MPU */
  59.   HAL_MPU_Disable();

  60.   /* Configure the MPU attributes as WT for SRAM */
  61.   MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  62.   MPU_InitStruct.BaseAddress = 0x20010000;
  63.   MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
  64.   MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  65.   MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  66.   MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  67.   MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  68.   MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  69.   MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  70.   MPU_InitStruct.SubRegionDisable = 0x00;
  71.   MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  72.   HAL_MPU_ConfigRegion(&MPU_InitStruct);

  73.   /* Enable the MPU */
  74.   HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
  75. }

  76. /**
  77.   * CPU L1-Cache enable
  78.   */
  79. static void CPU_CACHE_Enable (void) {

  80.   /* Enable I-Cache */
  81.   SCB_EnableICache();

  82.   /* Enable D-Cache */
  83.   SCB_EnableDCache();
  84. }


  85. /*****************************************************************************/
  86.         osThreadId hMain;
  87.         
  88. void Thread_Main(void const *argument)
  89. {
  90.         while (1)
  91.         {
  92.                 net_main();
  93.         }
  94. }
  95. osThreadDef(Thread_Main, osPriorityNormal, 1, NULL);

  96. int main(void)
  97. {
  98.         MPU_Config();                             /* Configure the MPU              */
  99.   CPU_CACHE_Enable();                       /* Enable the CPU Cache           */

  100.   HAL_Init();                               /* Initialize the HAL Library     */
  101.   SystemClock_Config();                     /* Configure the System Clock     */
  102.         
  103.         ServerTCP_Init();
  104.         ServerTCP_Listen(80);
  105.         
  106.         osKernelInitialize();
  107.         hMain = osThreadCreate(osThread(Thread_Main), NULL);
  108.   osKernelStart();
  109. }
復(fù)制代碼


    最后附上工程文件:
STM32F7_TCP.rar (54.26 KB, 下載次數(shù): 36)






歡迎光臨 (http://m.raoushi.com/bbs/) Powered by Discuz! X3.1