Difference between revisions of "How to create a custom ESPRO BSP"
(→Tutorial) |
|||
Line 19: | Line 19: | ||
*SolutionDir = The SolutionDir means the folder that contains the emProject file. |
*SolutionDir = The SolutionDir means the folder that contains the emProject file. |
||
− | *ESPRODir = The ESPRO package folder, found in Embedded Studio under |
+ | *ESPRODir = The ESPRO package folder, found in Embedded Studio under File->Open Studio Folder->Packages Folder. |
#Start Embedded Studio |
#Start Embedded Studio |
||
− | #Install CPU support Package for your device family via |
+ | #Install CPU support Package for your device family via Tools->Package Manager. |
− | #Create new project via |
+ | #Create new project via <code>File->New Project-></code>Create the project in a new solution. |
− | #Select the "A C/C++ executable for..." from the corresponding package. Press Next, select your target device and keep pressing Next until your project is |
+ | #Select the "A C/C++ executable for..." from the corresponding package. Press Next, select your target device and keep pressing Next until your project is finished. |
#Now activate the embOS and SEGGER library in the project options: |
#Now activate the embOS and SEGGER library in the project options: |
||
− | #* |
+ | #*<code>Project Settings->ES PRO Cortex-M->embOS-></code>Add embOS = Yes. |
− | #* |
+ | #*<code>Project Settings->ES PRO Cortex-M->SEGGER-></code>Add SEGGER library = Yes. |
− | #After activating the libraries open the |
+ | #After activating the libraries open the <code>SolutionDir</code>. |
− | #Create two folders called |
+ | #Create two folders called <code>OS</code> and <code>SEGGER</code>, after that open the <code>OS</code> folder. |
− | #Create two more folders in it named |
+ | #Create two more folders in it named <code>Setup</code> and <code>Generic</code>.[[File:ESPRO_BareMetal_OS_Setup_Generic.PNG|400px|thumb|none]] |
− | #Go back to the |
+ | #Go back to the <code>SolutionDir</code> and open the <code>SEGGER</code> folder. |
− | #Create a folder named |
+ | #Create a folder named <code>Generic</code> in it.[[File:ESPRO_BareMetal_SEGGER_Generic.PNG|400px|thumb|none]] |
− | #Now open the |
+ | #Now open the <code>ESPRODir</code> and navigate to <code>SEGGER->Generic</code>. |
− | #Copy the following files into |
+ | #Copy the following files into <code>SolutionDir->SEGGER->Generic</code>: |
#*SEGGER_RTT.c |
#*SEGGER_RTT.c |
||
#*SEGGER_SYSVIEW.c |
#*SEGGER_SYSVIEW.c |
||
#*SEGGER_SYSVIEW_embOS.c |
#*SEGGER_SYSVIEW_embOS.c |
||
#*SEGGER_RTT_ASM_ARMv7M.S |
#*SEGGER_RTT_ASM_ARMv7M.S |
||
− | #Also copy SEGGER_SYSVIEW_CONF.h from |
+ | #Also copy SEGGER_SYSVIEW_CONF.h from <code>ESPRODir->SEGGER-></code>Inc to <code>SoluionDir->SEGGER->Generic</code>.[[File:ESPRO_BareMetal_SEGGER_Generic_Source.PNG|400px|thumb|none]] |
− | #Unzip the downloaded SystemView, Target Sources to any location |
+ | #Unzip the downloaded SystemView, Target Sources to any location. |
− | #Open the unzipped files and navigate to |
+ | #Open the unzipped files and navigate to <code>Sample->embOS->Config->Cortex-M</code>. |
− | #Copy SEGGER_SYSVIEW_Config_embOS.c into |
+ | #Copy SEGGER_SYSVIEW_Config_embOS.c into <code>SolutionDir->SEGGER->Generic</code> |
− | #Now navigate to |
+ | #Now navigate to <code>SolutionDir->OS->Generic</code> and copy the following files from <code>ESPRODir->OS->Generic</code>: |
#*JLINKMEM_Process.c |
#*JLINKMEM_Process.c |
||
#*OS_Error.c |
#*OS_Error.c |
||
#*OS_ThreadSafe.c[[File:ESPRO_BareMetal_OS_Generic_Source.PNG|400px|thumb|none]] |
#*OS_ThreadSafe.c[[File:ESPRO_BareMetal_OS_Generic_Source.PNG|400px|thumb|none]] |
||
− | #After that create a RTOS Init file in |
+ | #After that create a RTOS Init file in <code>SolutionDir->OS->Setup</code>, how to create a RTOS init file can be found here: https://www.segger.com/doc/UM01076_embOS_Ultra.html#Board_Support_Packages[[File:ESPRO_BareMetal_OS_Setup_Source.PNG|400px|thumb|none]] |
− | #Go back to Embedded Studio and open the project settings |
+ | #Go back to Embedded Studio and open the project settings. |
− | #Switch to the common build configuration and navigate to |
+ | #Switch to the common build configuration and navigate to <code>Code->Preprocessor->User Include Directories</code> |
#After that add the following User Include Directories: |
#After that add the following User Include Directories: |
||
#*$(ProjectDir)/ |
#*$(ProjectDir)/ |
||
Line 56: | Line 56: | ||
#*$(ProjectDir)/STM32F7xx/Device/Include |
#*$(ProjectDir)/STM32F7xx/Device/Include |
||
#*$(ProjectDir)/SEGGER/Generic[[File:ESPRO_BareMetal_includes.PNG|400px|thumb|none]] |
#*$(ProjectDir)/SEGGER/Generic[[File:ESPRO_BareMetal_includes.PNG|400px|thumb|none]] |
||
− | #Drag and Drop the SEGGER and OS Folder from your |
+ | #Drag and Drop the SEGGER and OS Folder from your <code>SolutionDir</code> into the project window of Embedded studio. |
− | #Activate in both folders |
+ | #Activate in both folders Recurse into subdirectories via <code>Right click on the folder->Code->Folder->Dynamic Folder Recurse->Recurse into subdirectories</code>. |
− | #Close the options window and synchronize both folder with disk via |
+ | #Close the options window and synchronize both folder with disk via <code>Right click->Synchronize with disk</code>. |
− | #Drag an Drop both files of the downloaded files on top of the article into your |
+ | #Drag an Drop both files of the downloaded files on top of the article into your SolutionDir. |
− | #Drag and Drop both files of the downloaded files on top of the article into your virtual source folder in Embedded Studio |
+ | #Drag and Drop both files of the downloaded files on top of the article into your virtual source folder in Embedded Studio. |
− | #*The |
+ | #*The SolutionDir should now look as follows[[File:ESPRO_BareMetal_folders.PNG|400px|thumb|none]] |
#*The ES project explorer should now look as follows:[[File:ESPRO_BareMetal_project_explorer.PNG|400px|thumb|none]] |
#*The ES project explorer should now look as follows:[[File:ESPRO_BareMetal_project_explorer.PNG|400px|thumb|none]] |
||
− | # |
+ | #Now build the project and start the debug session. |
− | If |
+ | If everything works fine, two console outputs will be printed successively. |
+ | [[File:2022-08-22_08-46.png|400px|thumb|none]] |
||
+ | |||
==How to add emNet to the custom BSP== |
==How to add emNet to the custom BSP== |
||
Line 70: | Line 72: | ||
This tutorial will be explain how to add emNet to your custom ESPRO BSP. |
This tutorial will be explain how to add emNet to your custom ESPRO BSP. |
||
− | *Make sure your Clock is initialized so that your peripherals can be used correctly. In this example it is Ethernet. |
+ | *Make sure, your Clock is initialized so that your peripherals can be used correctly. In this example it is Ethernet. |
===Tutorial=== |
===Tutorial=== |
||
*SolutionDir = The SolutionDir means the folder that contains the emProject file. |
*SolutionDir = The SolutionDir means the folder that contains the emProject file. |
||
− | *ESPRODir = The ESPRO package folder, found in Embedded Studio under |
+ | *ESPRODir = The ESPRO package folder, found in Embedded Studio under File->Open Studio Folder->Packages Folder. |
#Open Embedded Studio |
#Open Embedded Studio |
||
− | # |
+ | #Now activate the emNetlibrary in the project options: |
− | #* |
+ | #*<code>Project Settings->ES PRO Cortex-M->emNet-></code>Add emNet = Yes. |
− | #Open the SolutionDir and create a Folder called |
+ | #Open the SolutionDir and create a Folder called <code>IP</code> in it. |
− | #Open the IP folder an create two more folders called |
+ | #Open the IP folder an create two more folders called <code>Setup</code> and <code>Generic</code> in it.[[File:ESPRO_BareMetal_IP_Setup_Generic.PNG|400px|thumb|none]] |
− | #Open the ESPRODir and navigate into |
+ | #Open the ESPRODir and navigate into <code>IP->Generic</code> |
− | #Copy the following files into |
+ | #Copy the following files into <code>SolutionDir->IP->Generic</code> |
#*CM_IP_cksum.S |
#*CM_IP_cksum.S |
||
#*FTPC_Conf.h |
#*FTPC_Conf.h |
||
Line 98: | Line 100: | ||
#*WEBS_Conf.h |
#*WEBS_Conf.h |
||
#*WiFi_Callbacks.c[[File:ESPRO_BareMetal_IP_Generic_Source.PNG|400px|thumb|none]] |
#*WiFi_Callbacks.c[[File:ESPRO_BareMetal_IP_Generic_Source.PNG|400px|thumb|none]] |
||
− | #Navigate back to |
+ | #Navigate back to <code>SolutionDir->IP->Setup</code> |
#In this folder a BSP_IP.c and a IP Config file are required. You can find templates for these files in one of our many BSPs which are available on the SEGGER [https://www.segger.com/evaluate-our-software/ website]. |
#In this folder a BSP_IP.c and a IP Config file are required. You can find templates for these files in one of our many BSPs which are available on the SEGGER [https://www.segger.com/evaluate-our-software/ website]. |
||
− | #Drag and Drop the IP Folder from your SolutionDir into the project window of Embedded |
+ | #Now Drag and Drop the IP Folder from your SolutionDir into the project window of Embedded studio. |
− | #Activate in both folders Recurse into subdirectories via |
+ | #Activate in both folders Recurse into subdirectories via <code>Right click on the folder->Code->Folder->Dynamic Folder Recurse->Recurse into subdirectories</code>. |
− | #Close the options window and synchronize both folder with disk via |
+ | #Close the options window and synchronize both folder with disk via <code>Right click->Synchronize with disk</code>. |
#To test emNet create a new c source file with following content: |
#To test emNet create a new c source file with following content: |
||
#*<source lang=C> |
#*<source lang=C> |
||
Line 325: | Line 327: | ||
/****** End Of File *************************************************/ |
/****** End Of File *************************************************/ |
||
</source> |
</source> |
||
+ | #Now build the project and start the debug session. |
||
− | #Make sure to set define HOST_TO_PING to the IP address of your host PC for the sample to work correctly |
||
− | #Build the project and start the debug session |
||
#*The ES project explorer should now look as follows: [[File:ESPRO_BareMetal_project_explorer_IP.PNG|400px|thumb|none]] |
#*The ES project explorer should now look as follows: [[File:ESPRO_BareMetal_project_explorer_IP.PNG|400px|thumb|none]] |
||
− | # |
+ | #If everything works fine, you should see a console output like in the picture below:[[File:ConsoleOutpu.png|400px|thumb|none]] |
Latest revision as of 08:51, 22 August 2022
This article contains a guide that explains how to create a custom ESPRO Board Support Package based on a CPU Support Package. In this example we will create an embOS project, later other SEGGER software can be added as well.
Setup
The following tutorial will be based on the following Hardware and Software combinations:
- SEGGER Embedded Studio v6.32b or later
- SEGGER Embedded Studio Pro v2.58 or later
- SystemView, Target Sources v3.32 or later
- Example application and main.c for testing purpose
Tutorial
This tutorial will be explain how to create a custom embOS board support package. To make this tutorial easier, a few terms need to be defined first:
- SolutionDir = The SolutionDir means the folder that contains the emProject file.
- ESPRODir = The ESPRO package folder, found in Embedded Studio under File->Open Studio Folder->Packages Folder.
- Start Embedded Studio
- Install CPU support Package for your device family via Tools->Package Manager.
- Create new project via
File->New Project->
Create the project in a new solution. - Select the "A C/C++ executable for..." from the corresponding package. Press Next, select your target device and keep pressing Next until your project is finished.
- Now activate the embOS and SEGGER library in the project options:
Project Settings->ES PRO Cortex-M->embOS->
Add embOS = Yes.Project Settings->ES PRO Cortex-M->SEGGER->
Add SEGGER library = Yes.
- After activating the libraries open the
SolutionDir
. - Create two folders called
OS
andSEGGER
, after that open theOS
folder. - Create two more folders in it named
Setup
andGeneric
. - Go back to the
SolutionDir
and open theSEGGER
folder. - Create a folder named
Generic
in it. - Now open the
ESPRODir
and navigate toSEGGER->Generic
. - Copy the following files into
SolutionDir->SEGGER->Generic
:- SEGGER_RTT.c
- SEGGER_SYSVIEW.c
- SEGGER_SYSVIEW_embOS.c
- SEGGER_RTT_ASM_ARMv7M.S
- Also copy SEGGER_SYSVIEW_CONF.h from
ESPRODir->SEGGER->
Inc toSoluionDir->SEGGER->Generic
. - Unzip the downloaded SystemView, Target Sources to any location.
- Open the unzipped files and navigate to
Sample->embOS->Config->Cortex-M
. - Copy SEGGER_SYSVIEW_Config_embOS.c into
SolutionDir->SEGGER->Generic
- Now navigate to
SolutionDir->OS->Generic
and copy the following files fromESPRODir->OS->Generic
:- JLINKMEM_Process.c
- OS_Error.c
- OS_ThreadSafe.c
- After that create a RTOS Init file in
SolutionDir->OS->Setup
, how to create a RTOS init file can be found here: https://www.segger.com/doc/UM01076_embOS_Ultra.html#Board_Support_Packages - Go back to Embedded Studio and open the project settings.
- Switch to the common build configuration and navigate to
Code->Preprocessor->User Include Directories
- After that add the following User Include Directories:
- $(ProjectDir)/
- $(ProjectDir)/CMSIS_5/CMSIS/Core/Include
- $(ProjectDir)/STM32F7xx/Device/Include
- $(ProjectDir)/SEGGER/Generic
- Drag and Drop the SEGGER and OS Folder from your
SolutionDir
into the project window of Embedded studio. - Activate in both folders Recurse into subdirectories via
Right click on the folder->Code->Folder->Dynamic Folder Recurse->Recurse into subdirectories
. - Close the options window and synchronize both folder with disk via
Right click->Synchronize with disk
. - Drag an Drop both files of the downloaded files on top of the article into your SolutionDir.
- Drag and Drop both files of the downloaded files on top of the article into your virtual source folder in Embedded Studio.
- The SolutionDir should now look as follows
- The ES project explorer should now look as follows:
- Now build the project and start the debug session.
If everything works fine, two console outputs will be printed successively.
How to add emNet to the custom BSP
This tutorial will be explain how to add emNet to your custom ESPRO BSP.
- Make sure, your Clock is initialized so that your peripherals can be used correctly. In this example it is Ethernet.
Tutorial
- SolutionDir = The SolutionDir means the folder that contains the emProject file.
- ESPRODir = The ESPRO package folder, found in Embedded Studio under File->Open Studio Folder->Packages Folder.
- Open Embedded Studio
- Now activate the emNetlibrary in the project options:
Project Settings->ES PRO Cortex-M->emNet->
Add emNet = Yes.
- Open the SolutionDir and create a Folder called
IP
in it. - Open the IP folder an create two more folders called
Setup
andGeneric
in it. - Open the ESPRODir and navigate into
IP->Generic
- Copy the following files into
SolutionDir->IP->Generic
- CM_IP_cksum.S
- FTPC_Conf.h
- IP_COAP_Conf.h
- IP_Conf.h
- IP_ConfigIO.c
- IP_FIND.c
- IP_FIND.h
- IP_FTP_SERVER_Conf.h
- IP_MQTT_CLIENT_Conf.h
- IP_OS_embOS.c
- README_emNet.html
- SMTPC_Conf.h
- WEBS_Conf.h
- WiFi_Callbacks.c
- Navigate back to
SolutionDir->IP->Setup
- In this folder a BSP_IP.c and a IP Config file are required. You can find templates for these files in one of our many BSPs which are available on the SEGGER website.
- Now Drag and Drop the IP Folder from your SolutionDir into the project window of Embedded studio.
- Activate in both folders Recurse into subdirectories via
Right click on the folder->Code->Folder->Dynamic Folder Recurse->Recurse into subdirectories
. - Close the options window and synchronize both folder with disk via
Right click->Synchronize with disk
. - To test emNet create a new c source file with following content:
/********************************************************************* * (c) SEGGER Microcontroller GmbH * * The Embedded Experts * ********************************************************************** * * * (c) 2007 - 2022 SEGGER Microcontroller GmbH * * * * www.segger.com Support: www.segger.com/ticket * * * ********************************************************************** * * * emNet * TCP/IP stack for embedded applications * * * * * * Please note: * * * * Knowledge of this file may under no circumstances * * be used to write a similar product for in-house use. * * * * Thank you for your fairness ! * * * ********************************************************************** * * * emNet version: V3.42.6 * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : IP_Ping.c Purpose : Sample program for embOS & emNet Demonstrates use of the IP stack to PING a host and get notified about incoming ICMP (PING) packets. Notes : For compatibility with interfaces that need to connect in any way this sample calls connect and disconnect routines that might not be needed in all cases. This sample can be used for Ethernet and dial-up interfaces and is configured to use the last registered interface as its main interface. */ #include "RTOS.h" #include "BSP.h" #include "IP.h" /********************************************************************* * * Configuration * ********************************************************************** */ #define USE_RX_TASK 0 // 0: Packets are read in ISR, 1: Packets are read in a task of its own. // // PING sample. // #define HOST_TO_PING IP_BYTES2ADDR(192, 168, 5, 1) // IP addr. of host that will be periodically PINGed by this sample. // // Task priorities. // enum { TASK_PRIO_IP_TASK = 150 // Priority should be higher than all IP application tasks. #if USE_RX_TASK ,TASK_PRIO_IP_RX_TASK // Must be the highest priority of all IP related tasks. #endif }; /********************************************************************* * * Static const * ********************************************************************** */ static const char *_ICMPContent = "This is a PING"; /********************************************************************* * * Static data * ********************************************************************** */ static IP_HOOK_ON_STATE_CHANGE _StateChangeHook; static int _IFaceId; // // Task stacks and Task-Control-Blocks. // static OS_STACKPTR int _IPStack[TASK_STACK_SIZE_IP_TASK/sizeof(int)]; // Stack of the IP_Task. static OS_TASK _IPTCB; // Task-Control-Block of the IP_Task. #if USE_RX_TASK static OS_STACKPTR int _IPRxStack[TASK_STACK_SIZE_IP_RX_TASK/sizeof(int)]; // Stack of the IP_RxTask. static OS_TASK _IPRxTCB; // Task-Control-Block of the IP_RxTask. #endif /********************************************************************* * * Prototypes * ********************************************************************** */ #ifdef __cplusplus extern "C" { /* Make sure we have C-declarations in C++ programs */ #endif void MainTask(void); #ifdef __cplusplus } #endif /********************************************************************* * * Local functions * ********************************************************************** */ /********************************************************************* * * _OnStateChange() * * Function description * Callback that will be notified once the state of an interface * changes. * * Parameters * IFaceId : Zero-based interface index. * AdminState: Is this interface enabled ? * HWState : Is this interface physically ready ? */ static void _OnStateChange(unsigned IFaceId, U8 AdminState, U8 HWState) { // // Check if this is a disconnect from the peer or a link down. // In this case call IP_Disconnect() to get into a known state. // if (((AdminState == IP_ADMIN_STATE_DOWN) && (HWState == 1)) || // Typical for dial-up connection e.g. PPP when closed from peer. Link up but app. closed. ((AdminState == IP_ADMIN_STATE_UP) && (HWState == 0))) { // Typical for any Ethernet connection e.g. PPPoE. App. opened but link down. IP_Disconnect(IFaceId); // Disconnect the interface to a clean state. } } /********************************************************************* * * _OnRxICMP() * * Function description * Callback that will be notified once an ICMP packet has been * received. The packet is evaluated and the type of the message * will be output. * * Parameters * pPacket: Pointer to packet received. pData points to the IP header. * * Return value * 0 : Packet will be processed by the stack. * Other: Packet will be freed by the stack. */ static int _OnRxICMP(IP_PACKET* pPacket) { const U8* pData; pData = IP_GetIPPacketInfo(pPacket); if(*pData == IP_ICMP_TYPE_ECHO_REQUEST) { IP_Logf_Application("ICMP echo request received!"); } if(*pData == IP_ICMP_TYPE_ECHO_REPLY) { IP_Logf_Application("ICMP echo reply received!"); } return 0; } /********************************************************************* * * Global functions * ********************************************************************** */ /********************************************************************* * * MainTask() * * Function description * Main task executed by the RTOS to create further resources and * running the main application. */ void MainTask(void) { U16 SeqenceNumber; char ac[16]; SeqenceNumber = 0; IP_Init(); IP_AddLogFilter(IP_MTYPE_APPLICATION); _IFaceId = IP_INFO_GetNumInterfaces() - 1; // Get the last registered interface ID as this is most likely the interface we want to use in this sample. OS_SetPriority(OS_GetTaskID(), TASK_PRIO_IP_TASK); // For now, this task has highest prio except IP management tasks. OS_CREATETASK(&_IPTCB , "IP_Task" , IP_Task , TASK_PRIO_IP_TASK , _IPStack); // Start the IP_Task. #if USE_RX_TASK OS_CREATETASK(&_IPRxTCB, "IP_RxTask", IP_RxTask, TASK_PRIO_IP_RX_TASK, _IPRxStack); // Start the IP_RxTask, optional. #endif IP_ICMP_SetRxHook(_OnRxICMP); // Register hook to be notified of incoming ICMP packets. IP_AddStateChangeHook(&_StateChangeHook, _OnStateChange); // Register hook to be notified on disconnects. IP_Connect(_IFaceId); // Connect the interface if necessary. OS_SetPriority(OS_GetTaskID(), 255); // Now this task has highest prio for real-time application. This is only allowed when this task does not use blocking IP API after this point. while (IP_IFaceIsReadyEx(_IFaceId) == 0) { OS_Delay(50); } IP_PrintIPAddr(ac, HOST_TO_PING, sizeof(ac)); while (1) { //BSP_ToggleLED(1); OS_Delay(200); IP_Logf_Application("Sending PING to IP addr. %s .", ac); IP_SendPingEx(_IFaceId, htonl(HOST_TO_PING), (char*)_ICMPContent, strlen(_ICMPContent), SeqenceNumber++); } } /****** End Of File *************************************************/
- Now build the project and start the debug session.
- The ES project explorer should now look as follows:
- If everything works fine, you should see a console output like in the picture below: