- all laboratory practice tasks implemented and tested

This commit is contained in:
Wiesner András 2025-02-19 09:37:03 +01:00
parent 46ee3099a5
commit 48a180f89d
15 changed files with 569 additions and 76 deletions

View File

@ -13,6 +13,7 @@
#include "lwip/netif.h" #include "lwip/netif.h"
#include "lwip/snmp.h" #include "lwip/snmp.h"
#include "lwip/tcpip.h"
#include "mac_drv.h" #include "mac_drv.h"
#include "phy_drv/phy_common.h" #include "phy_drv/phy_common.h"
@ -36,7 +37,7 @@
// --------- Ethernet buffers ---------- // --------- Ethernet buffers ----------
// ------------------------------------- // -------------------------------------
#define ETH_BUFFER_SIZE (1536UL) #define ETH_BUFFER_SIZE (1528UL)
#define ETH_RX_BUF_SIZE (ETH_BUFFER_SIZE) #define ETH_RX_BUF_SIZE (ETH_BUFFER_SIZE)
#define ETH_TX_BUF_SIZE (ETH_BUFFER_SIZE) #define ETH_TX_BUF_SIZE (ETH_BUFFER_SIZE)
@ -92,7 +93,7 @@ static void fetch_link_properties() {
static void phy_thread(void *arg) { static void phy_thread(void *arg) {
while (true) { while (true) {
fetch_link_properties(); tcpip_callback(fetch_link_properties, NULL);
osDelay(500); osDelay(500);
} }
return; return;
@ -148,7 +149,7 @@ static void low_level_init(struct netif *netif) {
netif->hwaddr_len = ETHARP_HWADDR_LEN; netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */ /* set MAC hardware address */
memcpy(netif->hwaddr, &opts.mac, ETHARP_HWADDR_LEN); memcpy(netif->hwaddr, opts.mac, ETHARP_HWADDR_LEN);
/* maximum transfer unit */ /* maximum transfer unit */
netif->mtu = 1500; netif->mtu = 1500;
@ -208,15 +209,15 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
/* check if timestamping is demanded */ /* check if timestamping is demanded */
uint8_t opts = ETHHW_TXOPT_NONE; uint8_t opts = ETHHW_TXOPT_NONE;
bool tsEn = (p->tx_cb != NULL); // bool tsEn = (p->tx_cb != NULL);
ETHHW_OptArg_TxTsCap optArg; ETHHW_OptArg_TxTsCap optArg;
memset(&optArg, 0, sizeof(ETHHW_OptArg_TxTsCap)); memset(&optArg, 0, sizeof(ETHHW_OptArg_TxTsCap));
if (tsEn) { // if (tsEn) {
opts = ETHHW_TXOPT_CAPTURE_TS; // opts = ETHHW_TXOPT_CAPTURE_TS;
optArg.txTsCbPtr = (uint32_t)(p->tx_cb); // optArg.txTsCbPtr = (uint32_t)(p->tx_cb);
optArg.tag = (uint32_t)p->tag; // optArg.tag = (uint32_t)p->tag;
} // }
/* Pass the data to the MAC */ /* Pass the data to the MAC */
ETHHW_Transmit(ETH, concat_buf, concat_buf_level, opts, &optArg); ETHHW_Transmit(ETH, concat_buf, concat_buf_level, opts, &optArg);
@ -277,8 +278,8 @@ int ETHHW_ReadCallback(ETHHW_EventDesc *evt) {
} }
/* Copy the timestamp into the first pbuf */ /* Copy the timestamp into the first pbuf */
p->time_s = evt->data.rx.ts_s; // p->time_s = evt->data.rx.ts_s;
p->time_ns = evt->data.rx.ts_ns; // p->time_ns = evt->data.rx.ts_ns;
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1) { if (((u8_t *)p->payload)[0] & 1) {
@ -384,8 +385,8 @@ err_t ethernetif_init(struct netif *netif) {
netif_set_up(netif); netif_set_up(netif);
/* refresh and fetch PHY and link status */ /* refresh and fetch PHY and link status */
phy_refresh_link_status(); // phy_refresh_link_status();
fetch_link_properties(); // fetch_link_properties();
return ERR_OK; return ERR_OK;
} }

View File

@ -32,7 +32,7 @@ static void ETHHW_InitClocks() {
RMII_MII_CRS_DV -------------------> PA7 RMII_MII_CRS_DV -------------------> PA7
RMII_MII_RXD0 ---------------------> PC4 RMII_MII_RXD0 ---------------------> PC4
RMII_MII_RXD1 ---------------------> PC5 RMII_MII_RXD1 ---------------------> PC5
RMII_MII_RXER ---------------------> PB10) (RMII_MII_RXER ---------------------> PB10)
RMII_MII_TX_EN --------------------> PB11 RMII_MII_TX_EN --------------------> PB11
RMII_MII_TXD0 ---------------------> PB12 RMII_MII_TXD0 ---------------------> PB12
RMII_MII_TXD1 ---------------------> PB13 RMII_MII_TXD1 ---------------------> PB13
@ -116,10 +116,8 @@ static void ETHHW_InitPeripheral(ETH_TypeDef *eth, ETHHW_InitOpts *init) {
WRITE_REG(eth->MACCR, mode | ETH_MACCR_IPC); WRITE_REG(eth->MACCR, mode | ETH_MACCR_IPC);
/* ---- MTL initialization ---- */ /* ---- MTL initialization ---- */
WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF | WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF | (0b10 << 2)); // transmit store and forward ON and enable transmit queue
(0b10 << 2)); // transmit store and forward ON WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON
// and enable transmit queue
WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON
/* ---- DMA configuration ---- */ /* ---- DMA configuration ---- */
@ -213,8 +211,7 @@ __weak int ETHHW_ReadCallback(ETHHW_EventDesc *evt) {
return ETHHW_RET_RX_PROCESSED; return ETHHW_RET_RX_PROCESSED;
} }
ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n, ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n, ETHHW_DescFull *bd, int delta) {
ETHHW_DescFull *bd, int delta) {
int16_t index = (((uint32_t)(bd)) - ((uint32_t)(start))) / sizeof(ETHHW_DescFull); int16_t index = (((uint32_t)(bd)) - ((uint32_t)(start))) / sizeof(ETHHW_DescFull);
// int16_t startIndex = index; // int16_t startIndex = index;
index = ((int)index + delta) % n; index = ((int)index + delta) % n;
@ -334,7 +331,7 @@ static void ETHHW_PrintRingBufStatus(ETH_TypeDef *eth,
// process incoming packet // process incoming packet
void ETHHW_ProcessRx(ETH_TypeDef *eth) { void ETHHW_ProcessRx(ETH_TypeDef *eth) {
//ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX); // ETHHW_PrintRingBufStatus(eth, ETHHW_RINGBUF_RX);
ETHHW_DescFull *ring = (ETHHW_DescFull *)eth->DMACRDLAR; ETHHW_DescFull *ring = (ETHHW_DescFull *)eth->DMACRDLAR;
uint16_t ringLen = eth->DMACRDRLR + 1; uint16_t ringLen = eth->DMACRDRLR + 1;
@ -525,7 +522,7 @@ void ETHHW_Transmit(ETH_TypeDef *eth, const uint8_t *buf, uint16_t len, uint8_t
// ----------------- // -----------------
void ETHHW_SetLinkProperties(ETH_TypeDef * eth, bool fastEthernet, bool fullDuplex) { void ETHHW_SetLinkProperties(ETH_TypeDef *eth, bool fastEthernet, bool fullDuplex) {
// fetch register content // fetch register content
uint32_t reg = eth->MACCR; uint32_t reg = eth->MACCR;
@ -731,7 +728,7 @@ void ETHHW_SetPTPAddend(ETH_TypeDef *eth, uint32_t addend) {
} }
} }
uint32_t ETHHW_GetPTPAddend(ETH_TypeDef * eth) { uint32_t ETHHW_GetPTPAddend(ETH_TypeDef *eth) {
return eth->MACTSAR; return eth->MACTSAR;
} }
@ -785,7 +782,8 @@ uint8_t ETHHW_GetAuxTimestampCnt(ETH_TypeDef *eth) {
void ETHHW_StartPTPPPSPulseTrain(ETH_TypeDef *eth, uint32_t high_len, uint32_t period) { void ETHHW_StartPTPPPSPulseTrain(ETH_TypeDef *eth, uint32_t high_len, uint32_t period) {
ETHHW_StopPTPPPSPulseTrain(eth); ETHHW_StopPTPPPSPulseTrain(eth);
while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {}; while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {
};
// delayed start of pulse train with (at least) 1s to ensure, // delayed start of pulse train with (at least) 1s to ensure,
// target timestamps point always in the future on return from this function // target timestamps point always in the future on return from this function
@ -812,7 +810,8 @@ void ETHHW_StopPTPPPSPulseTrain(ETH_TypeDef *eth) {
if (!(eth->MACPPSCR & ETH_PTP_PPS_OUTPUT_MODE_SELECT)) { if (!(eth->MACPPSCR & ETH_PTP_PPS_OUTPUT_MODE_SELECT)) {
eth->MACPPSCR |= ETH_PTP_PPS_OUTPUT_MODE_SELECT; // switch to pulse-train mode eth->MACPPSCR |= ETH_PTP_PPS_OUTPUT_MODE_SELECT; // switch to pulse-train mode
} else { } else {
while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {}; while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {
};
} }
eth->MACPPSCR |= ETH_PTP_PPS_PULSE_TRAIN_STOP_IMM; eth->MACPPSCR |= ETH_PTP_PPS_PULSE_TRAIN_STOP_IMM;

View File

@ -222,7 +222,7 @@
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ #define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
/* ########################### Ethernet Configuration ######################### */ /* ########################### Ethernet Configuration ######################### */
#define ETH_TX_DESC_CNT 8 /* number of Ethernet Tx DMA descriptors */ #define ETH_TX_DESC_CNT 24 /* number of Ethernet Tx DMA descriptors */
#define ETH_RX_DESC_CNT 24 /* number of Ethernet Rx DMA descriptors */ #define ETH_RX_DESC_CNT 24 /* number of Ethernet Rx DMA descriptors */
#define UNIQUE_DEV_ID_BASE ((const uint8_t *)0x1FF1E800) #define UNIQUE_DEV_ID_BASE ((const uint8_t *)0x1FF1E800)

View File

@ -47,7 +47,7 @@
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1 #define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1 #define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( 550000000 ) #define configCPU_CLOCK_HZ ( 400000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) #define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 56 ) #define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )

View File

@ -56,4 +56,5 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
# flexptp # flexptp
# etherlib # etherlib
embfmt embfmt
lwipcore) lwipcore
lwipallapps)

View File

@ -6,6 +6,8 @@ target_sources(
sysmem.c sysmem.c
system_stm32h7xx.c system_stm32h7xx.c
board_support.c
board_support.h
cmds.c cmds.c
cmds.h cmds.h
) )
@ -18,4 +20,6 @@ target_include_directories(
add_subdirectory(standard_output) add_subdirectory(standard_output)
add_subdirectory(cliutils) add_subdirectory(cliutils)
add_subdirectory(ethernet) add_subdirectory(ethernet)
add_subdirectory(user)

73
Src/board_support.c Normal file
View File

@ -0,0 +1,73 @@
#include "board_support.h"
#include <stm32h7xx_hal.h>
void leds_init() {
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef init;
init.Mode = GPIO_MODE_OUTPUT_PP;
init.Pin = GPIO_PIN_2 | GPIO_PIN_3;
init.Pull = GPIO_NOPULL;
init.Alternate = 0;
init.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOC, &init);
HAL_GPIO_WritePin(GPIOC, init.Pin, GPIO_PIN_SET);
}
void leds_write(uint8_t idx, bool state) {
GPIO_TypeDef *gpio;
uint16_t pin;
switch (idx) {
case LEDS_USER1_GREEN:
gpio = GPIOC;
pin = GPIO_PIN_3;
break;
case LEDS_USER2_RED:
gpio = GPIOC;
pin = GPIO_PIN_2;
break;
default:
break;
}
HAL_GPIO_WritePin(gpio, pin, state ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
static EXTI_HandleTypeDef hEXTI13;
void btn_init() {
// pin initialization
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef init;
init.Mode = GPIO_MODE_INPUT;
init.Pin = GPIO_PIN_13;
init.Pull = GPIO_NOPULL;
init.Alternate = 0;
init.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOC, &init);
// EXTI13 initialization
EXTI_ConfigTypeDef extiConf;
extiConf.Line = EXTI_LINE_13;
extiConf.GPIOSel = EXTI_GPIOC;
extiConf.Trigger = EXTI_TRIGGER_RISING;
extiConf.Mode = EXTI_MODE_INTERRUPT;
HAL_EXTI_SetConfigLine(&hEXTI13, &extiConf);
// enable interrupt source
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 12, 0); // some medium-low priority
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
__weak void btn_cb() {
return;
}
void EXTI15_10_IRQHandler() {
HAL_EXTI_ClearPending(&hEXTI13, EXTI_TRIGGER_RISING); // clear interrupt
btn_cb();
}

15
Src/board_support.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef SRC_BOARD_SUPPORT
#define SRC_BOARD_SUPPORT
#include <stdbool.h>
#include <stdint.h>
#define LEDS_USER1_GREEN (0)
#define LEDS_USER2_RED (1)
void leds_init();
void leds_write(uint8_t idx, bool state);
void btn_init();
#endif /* SRC_BOARD_SUPPORT */

View File

@ -80,7 +80,7 @@ void init_ethernet() {
osTimerStart(checkDhcpTmr, 1000); osTimerStart(checkDhcpTmr, 1000);
} }
err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) { __attribute__((weak)) err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) {
pbuf_free(pbuf); pbuf_free(pbuf);
return ERR_OK; return ERR_OK;

View File

@ -31,9 +31,6 @@
****************************************************************************** ******************************************************************************
*/ */
#ifndef SRC_LWIPOPTS
#define SRC_LWIPOPTS
#ifndef __LWIPOPTS_H__ #ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__ #define __LWIPOPTS_H__
@ -51,7 +48,7 @@
/* MEM_SIZE: the size of the heap memory. If the application will send /* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */ a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE (12*1024) // (10*1024) #define MEM_SIZE (16*1024) // (10*1024)
#define LWIP_DECLARE_MEMORY_POSTFIX __attribute__((section(".lwIPHeapSection"))) #define LWIP_DECLARE_MEMORY_POSTFIX __attribute__((section(".lwIPHeapSection")))
@ -75,15 +72,15 @@ a lot of data that needs to be copied, this should be set high. */
timeouts. */ timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 10 #define MEMP_NUM_SYS_TIMEOUT 10
#define LWIP_PBUF_CUSTOM_DATA \ // #define LWIP_PBUF_CUSTOM_DATA \
/** Ingress/egress timestamp seconds part */ \ // /** Ingress/egress timestamp seconds part */ \
u32_t time_s; \ // u32_t time_s; \
/** Ingress/egress timestamp nanoseconds part */ \ // /** Ingress/egress timestamp nanoseconds part */ \
u32_t time_ns; \ // u32_t time_ns; \
/** Transmit callback pointer */ \ // /** Transmit callback pointer */ \
void (*tx_cb)(uint32_t, uint32_t, uint32_t); \ // void (*tx_cb)(uint32_t, uint32_t, uint32_t); \
/** Custom tag */ \ // /** Custom tag */ \
void * tag; // void * tag;
@ -134,7 +131,7 @@ a lot of data that needs to be copied, this should be set high. */
/* ---------- DHCP options ---------- */ /* ---------- DHCP options ---------- */
#define LWIP_DHCP 1 #define LWIP_DHCP 1
#define LWIP_DHCP_CHECK_LINK_UP 1
/* ---------- UDP options ---------- */ /* ---------- UDP options ---------- */
#define LWIP_UDP 1 #define LWIP_UDP 1
@ -146,6 +143,9 @@ a lot of data that needs to be copied, this should be set high. */
//#define LWIP_HTTPD_CGI_SSI 1 //#define LWIP_HTTPD_CGI_SSI 1
#define LWIP_HTTPD_SSI 1 #define LWIP_HTTPD_SSI 1
#define LWIP_HTTPD_CUSTOM_FILES 1 #define LWIP_HTTPD_CUSTOM_FILES 1
#define LWIP_HTTPD_DYNAMIC_HEADERS 1
#define LWIP_HTTPD_EXAMPLE_GENERATEDFILES 1
#define LWIP_HTTPD_FILE_EXTENSION 1
#define HTTPD_USE_MEM_POOL 0 #define HTTPD_USE_MEM_POOL 0
#define MEMP_NUM_PARALLEL_HTTPD_CONNS 8 #define MEMP_NUM_PARALLEL_HTTPD_CONNS 8
#define LWIP_HTTPD_SSI_MULTIPART 0 #define LWIP_HTTPD_SSI_MULTIPART 0
@ -222,7 +222,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums
/** /**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/ */
#define LWIP_NETCONN 1 #define LWIP_NETCONN 0
/* /*
------------------------------------ ------------------------------------
@ -241,7 +241,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums
*/ */
/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the /** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
* file system (to prevent changing the file included in CVS) */ * file system (to prevent changing the file included in CVS) */
#define HTTPD_USE_CUSTOM_FSDATA 1 #define HTTPD_USE_CUSTOM_FSDATA 0
/* /*
@ -251,7 +251,7 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums
*/ */
#define TCPIP_THREAD_NAME "TCP/IP" #define TCPIP_THREAD_NAME "TCP/IP"
#define TCPIP_THREAD_STACKSIZE 2048 #define TCPIP_THREAD_STACKSIZE 3072
#define TCPIP_MBOX_SIZE 6 #define TCPIP_MBOX_SIZE 6
#define DEFAULT_UDP_RECVMBOX_SIZE 6 #define DEFAULT_UDP_RECVMBOX_SIZE 6
#define DEFAULT_TCP_RECVMBOX_SIZE 6 #define DEFAULT_TCP_RECVMBOX_SIZE 6
@ -273,5 +273,3 @@ The STM32H7xx allows computing and verifying the IP, UDP, TCP and ICMP checksums
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#endif /* SRC_LWIPOPTS */

View File

@ -8,6 +8,7 @@
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
#include "board_support.h"
#include "cliutils/cli.h" #include "cliutils/cli.h"
#include "cmds.h" #include "cmds.h"
#include "ethernet/ethernet_lwip.h" #include "ethernet/ethernet_lwip.h"
@ -17,6 +18,8 @@
#include <cmsis_os2.h> #include <cmsis_os2.h>
#include "user/user.h"
void init_pll() { void init_pll() {
RCC_OscInitTypeDef osc; RCC_OscInitTypeDef osc;
RCC_ClkInitTypeDef clk; RCC_ClkInitTypeDef clk;
@ -39,7 +42,7 @@ void init_pll() {
osc.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // Wide-range VCO osc.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // Wide-range VCO
osc.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // input frequency between 8MHz and 16MHz osc.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // input frequency between 8MHz and 16MHz
osc.PLL.PLLM = 2; // 25MHz -> 12.5MHz osc.PLL.PLLM = 2; // 25MHz -> 12.5MHz
osc.PLL.PLLN = 44; // 12.5MHz -> 550MHz osc.PLL.PLLN = 32; // 12.5MHz -> 550MHz (44)
osc.PLL.PLLP = 1; // 550MHz -> 550MHz osc.PLL.PLLP = 1; // 550MHz -> 550MHz
osc.PLL.PLLQ = 5; // 550MHz -> 110MHz osc.PLL.PLLQ = 5; // 550MHz -> 110MHz
osc.PLL.PLLR = 5; // 550MHz -> 110MHz osc.PLL.PLLR = 5; // 550MHz -> 110MHz
@ -59,7 +62,7 @@ void init_pll() {
clk.APB3CLKDivider = RCC_APB3_DIV2; clk.APB3CLKDivider = RCC_APB3_DIV2;
clk.APB4CLKDivider = RCC_APB4_DIV2; clk.APB4CLKDivider = RCC_APB4_DIV2;
HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_3); // set a FLASH latency supporting maximum speed HAL_RCC_ClockConfig(&clk, FLASH_LATENCY_4); // set a FLASH latency supporting maximum speed
// --------------------- // ---------------------
} }
@ -94,21 +97,10 @@ void print_welcome_message() {
MSG(ANSI_COLOR_BGREEN "Greetings!" ANSI_COLOR_BYELLOW " Starting up... \n" ANSI_COLOR_RESET); MSG(ANSI_COLOR_BGREEN "Greetings!" ANSI_COLOR_BYELLOW " Starting up... \n" ANSI_COLOR_RESET);
} }
static void init_led() {
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef init;
init.Mode = GPIO_MODE_OUTPUT_PP;
init.Pin = GPIO_PIN_14;
init.Pull = GPIO_NOPULL;
init.Alternate = 0;
init.Speed = GPIO_SPEED_HIGH;
HAL_GPIO_Init(GPIOB, &init);
}
void task_startup(void *arg) { void task_startup(void *arg) {
// initialize on-board LED(s) // initialize on-board LEDs and buttons
init_led(); leds_init();
btn_init();
// initialize the CLI // initialize the CLI
cli_init(); cli_init();
@ -116,10 +108,6 @@ void task_startup(void *arg) {
// print greetings // print greetings
print_welcome_message(); print_welcome_message();
// #ifdef DEBUG
// osDelay(2000);
// #endif
// initialize Ethernet // initialize Ethernet
init_ethernet(); init_ethernet();
@ -128,6 +116,10 @@ void task_startup(void *arg) {
// ------------- // -------------
user_init();
// -------------
for (;;) { for (;;) {
osDelay(1000); osDelay(1000);
} }
@ -144,6 +136,10 @@ void init_randomizer() {
srand(LL_RNG_ReadRandData32(RNG)); srand(LL_RNG_ReadRandData32(RNG));
} }
void init_mpu() {
HAL_MPU_Disable();
}
int main(void) { int main(void) {
// initialize FPU and several system blocks // initialize FPU and several system blocks
SystemInit(); SystemInit();
@ -154,9 +150,12 @@ int main(void) {
// initialize oscillator and clocking // initialize oscillator and clocking
init_osc_and_clk(); init_osc_and_clk();
// make random a bit more undeterministic // make random a bit more less deterministic
init_randomizer(); init_randomizer();
// initialize MPU
init_mpu();
// initialize standard output // initialize standard output
serial_io_init(); serial_io_init();
@ -179,10 +178,6 @@ int main(void) {
} }
} }
// void SysTick_Handler() {
// HAL_IncTick();
// }
// ------------------------ // ------------------------
uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".FreeRTOSHeapSection"))); uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".FreeRTOSHeapSection")));

4
Src/user/CMakeLists.txt Normal file
View File

@ -0,0 +1,4 @@
target_sources(${CMAKE_PROJECT_NAME} PUBLIC
user.h
user.c
)

397
Src/user/user.c Normal file
View File

@ -0,0 +1,397 @@
#include "user.h"
#include "embfmt/embformat.h"
#include "lwip/apps/fs.h"
#include "lwip/apps/httpd.h"
#include "lwip/igmp.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "netif/ethernet.h"
#include "standard_output/standard_output.h"
#include <string.h>
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
// -----------------------------------
#define RECV_BUF_LEN (511)
static char recv_buf[RECV_BUF_LEN + 1];
static char *msg = "Üdvözlet a H735-ös kártyáról!";
// ----------- Custom EtherType client
// TODO: 0x9000 fölött kb. bármit lehet választani
#define CUSTOM_RX_ETHERTYPE (0x88F7)
err_t hook_unknown_ethertype(struct pbuf *pbuf, struct netif *netif) {
// aquire ethertype
uint16_t etherType = 0;
memcpy(&etherType, ((uint8_t *)pbuf->payload) + 12, 2);
etherType = ntohs(etherType);
uint8_t *shwa = ((uint8_t *)pbuf->payload) + 6; // get source hardware address
uint16_t len = pbuf->len - 14; // get payload length
uint8_t *payload = ((uint8_t *)pbuf->payload) + 14; // actual payload
// check for match
if (etherType == CUSTOM_RX_ETHERTYPE) {
// copy payload
uint16_t copy_len = MIN(RECV_BUF_LEN, len);
recv_buf[copy_len] = '\0';
memcpy(recv_buf, payload, copy_len);
// print it
MSG("[%02X:%02X:%02X:%02X:%02X:%02X] %u\n%s\n", shwa[0], shwa[1], shwa[2], shwa[3], shwa[4], shwa[5], len, recv_buf);
}
pbuf_free(pbuf);
return ERR_OK;
}
#define CUSTOM_TX_ETHERTYPE (0x9101)
static struct eth_addr dest_hwa = {.addr = {0x00, 0x1b, 0x21, 0x91, 0x9E, 0x64}};
void send_frame() {
uint16_t len = strlen(msg);
struct pbuf *p = pbuf_alloc(PBUF_LINK, len, PBUF_RAM);
if (p == NULL) {
MSG("Nem sikerült pbuf-ot foglalni az Ethernet-keret küldéséhez!\n");
return;
}
memcpy(p->payload, msg, len);
if (ethernet_output(netif_default, p, (struct eth_addr *)netif_default->hwaddr, &dest_hwa, CUSTOM_TX_ETHERTYPE) != ERR_OK) {
MSG("Sikertelen volt az Ethernet-keret küldése!\n");
return;
}
pbuf_free(p);
}
// ----------- UDP client ------------
static struct udp_pcb *udpc;
static ip4_addr_t dest_addr;
static uint16_t dest_port;
void udp_client_init() {
// create new PCB
udpc = udp_new();
if (udpc == NULL) {
MSG("Hiba az UDP-kliens létrehozásánál!\n");
}
// set destination IP address and port
IP4_ADDR(&dest_addr, 10, 42, 0, 1);
dest_port = 4000;
// TODO: connect?
}
void udp_client_send() {
uint16_t len = strlen(msg);
// allocate pbuf and fill with contents
struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (buf == NULL) {
MSG("Nem lehetett újabb pbuf-ot foglalni!\n");
return;
}
memcpy(buf->payload, msg, len);
// send UDP datagram to defined destination
if (udp_sendto(udpc, buf, &dest_addr, dest_port) != ERR_OK) {
MSG("Nem sikerült elküldeni az UDP datagramot!\n");
}
// decrease reference count of the buf
pbuf_free(buf);
}
// -----------------------------------
static struct udp_pcb *udps;
static uint16_t server_port;
static void udp_server_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
uint16_t copy_len = MIN(RECV_BUF_LEN, p->len);
recv_buf[copy_len] = '\0';
memcpy(recv_buf, p->payload, copy_len);
MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf);
pbuf_free(p);
}
void udp_server_init() {
// create new PCB
udps = udp_new();
if (udps == NULL) {
MSG("Hiba az UDP-szerver létrehozásánál!\n");
}
// set server port
server_port = 3000;
// bind it to a local address
if (udp_bind(udps, IP4_ADDR_ANY, server_port) != ERR_OK) {
MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", server_port);
udp_remove(udps);
}
// register receive callback
udp_recv(udps, udp_server_recv, NULL);
}
// -----------------------------------
static struct udp_pcb *udpmc;
static uint16_t mc_port;
static ip4_addr_t mc_group;
static void udp_mcast_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) {
uint16_t copy_len = MIN(RECV_BUF_LEN, p->len);
recv_buf[copy_len] = '\0';
memcpy(recv_buf, p->payload, copy_len);
MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(addr), port, p->len, recv_buf);
pbuf_free(p);
}
void udp_mcast_init() {
// create new PCB
udpmc = udp_new();
if (udps == NULL) {
MSG("Hiba a multicast UDP szolgáltatás létrehozásánál!\n");
}
// set multicast group's address and port
IP4_ADDR(&mc_group, 224, 0, 2, 5);
mc_port = 2000;
// join the relevant multicast group
igmp_joingroup(&netif_default->ip_addr, &mc_group);
// bind it to a local address
if (udp_bind(udpmc, &mc_group, mc_port) != ERR_OK) {
MSG("Nem sikerült az UDP-szervert felcsatolni a %u portra!\n", mc_port);
goto cleanup;
}
// connect to the IGMP group
if (udp_connect(udpmc, &mc_group, mc_port) != ERR_OK) {
MSG("Nem sikerült az UDP multicast szolgáltatást becsatlakoztatni a multicast-csoportba!\n");
goto cleanup;
}
// register receive callback
udp_recv(udpmc, udp_mcast_recv, NULL);
return;
// ---
cleanup:
udp_remove(udpmc);
return;
}
void udp_mcast_send() {
uint16_t len = strlen(msg);
// allocate pbuf and fill with contents
struct pbuf *buf = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (buf == NULL) {
MSG("Nem lehetett újabb pbuf-ot foglalni!\n");
return;
}
memcpy(buf->payload, msg, len);
// send UDP datagram to defined destination
if (udp_send(udpmc, buf) != ERR_OK) {
MSG("Nem sikerült elküldeni az UDP datagramot!\n");
}
// decrease reference count of the buf
pbuf_free(buf);
}
// -----------------------------------
static struct tcp_pcb *tcps;
static uint16_t tcps_port;
static ip_addr_t tcps_addr;
static err_t tcp_server_conn_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
if (p != NULL) {
uint16_t copy_len = MIN(RECV_BUF_LEN, p->len);
recv_buf[copy_len] = '\0';
memcpy(recv_buf, p->payload, copy_len);
MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf);
pbuf_free(p);
tcp_recved(tpcb, copy_len);
} else {
MSG("A kliens lekapcsolódott %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port);
}
return ERR_OK;
}
static void tcp_server_conn_err(void *arg, err_t err) {
MSG("TCP-kapcsolat hiba! (%u)\n", err);
}
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
tcp_recv(newpcb, tcp_server_conn_recv);
tcp_err(newpcb, tcp_server_conn_err);
MSG("Bejövő TCP-kapcsolat érkezett %s:%u!\n", ipaddr_ntoa(&newpcb->remote_ip), newpcb->remote_port);
return ERR_OK;
}
static void tcp_server_error(void *arg, err_t err) {
MSG("TCP-szerver hiba! (%u)\n", err);
}
void tcp_server_init() {
// create new TCP service
tcps = tcp_new();
if (tcps == NULL) {
MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n");
return;
}
// set port
tcps_port = 6000;
IP4_ADDR(&tcps_addr, 10, 42, 0, 137);
// bind to local port
if (tcp_bind(tcps, &tcps_addr, tcps_port) != ERR_OK) {
MSG("Nem sikerült a TCP-szervert a %u portra csatolni!\n", tcps_port);
goto cleanup;
}
// enable server functions
tcps = tcp_listen(tcps);
// assign error handling function
tcp_err(tcps, tcp_server_error);
// register accept callback
tcp_accept(tcps, tcp_server_accept);
return;
// -----
cleanup:
tcp_close(tcps);
return;
}
static struct tcp_pcb *tcpc;
static ip4_addr_t tcpc_remote_addr;
static uint16_t tcpc_remote_port;
static void tcp_client_error(void *arg, err_t err) {
MSG("TCP-kliens hiba! (%u)\n", err);
}
static err_t tcp_client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
if (p != NULL) {
uint16_t copy_len = MIN(RECV_BUF_LEN, p->len);
recv_buf[copy_len] = '\0';
memcpy(recv_buf, p->payload, copy_len);
MSG("[%s:%u] %ub\n%s\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port, p->len, recv_buf);
pbuf_free(p);
tcp_recved(tpcb, copy_len);
} else {
MSG("A szerver bontotta a kapcsolatot %s:%u\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port);
}
return ERR_OK;
}
static err_t tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) {
MSG("Sikeresen fölkapcsolódtunk a TCP-szerverre: %s:%u!\n", ipaddr_ntoa(&tpcb->remote_ip), tpcb->remote_port);
tcp_write(tcpc, msg, strlen(msg), 0);
tcp_close(tcpc);
return ERR_OK;
}
void tcp_client_init() {
// create new TCP service
tcpc = tcp_new();
if (tcpc == NULL) {
MSG("Nem sikerült létrehozni a TCP szerver szolgáltatást!\n");
return;
}
// set remote address and port
IP4_ADDR(&tcpc_remote_addr, 10, 42, 0, 1);
tcpc_remote_port = 9000;
// assign error handling function
tcp_err(tcpc, tcp_client_error);
// assign reception callback
tcp_recv(tcpc, tcp_client_recv);
// connect to remote host
tcp_connect(tcpc, &tcpc_remote_addr, tcpc_remote_port, tcp_client_connected);
}
// -----------------------------------
#define GENDATA_LEN (31)
static char generated_data[GENDATA_LEN + 1];
int fs_open_custom(struct fs_file *file, const char *name) {
/* this example only provides one file */
if (!strcmp(name, "/generated.html")) {
/* generate a random number */
uint32_t random = rand();
embfmt(generated_data, GENDATA_LEN, "%u is random!", random);
/* initialize fs_file correctly */
memset(file, 0, sizeof(struct fs_file));
uint32_t len = strlen(generated_data);
file->pextension = mem_malloc(len);
if (file->pextension != NULL) {
/* instead of doing memcpy, you would generate e.g. a JSON here */
memcpy(file->pextension, generated_data, len);
file->data = (const char *)file->pextension;
file->len = len; /* don't send the trailing 0 */
file->index = file->len;
/* allow persisting connections */
file->flags = FS_FILE_FLAGS_HEADER_PERSISTENT;
return 1;
}
}
return 0;
}
void fs_close_custom(struct fs_file *file) {
if (file && file->pextension) {
mem_free(file->pextension);
file->pextension = NULL;
}
}
// -----------------------------------
void btn_cb() {
MSG("Küldés!\n");
//udp_client_send();
// send_frame();
// udp_mcast_send();
tcp_client_init();
}
void user_init() {
udp_client_init();
// udp_server_init();
// udp_mcast_init();
tcp_server_init();
httpd_init();
}

6
Src/user/user.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef USER_USER
#define USER_USER
void user_init();
#endif /* USER_USER */

View File

@ -176,12 +176,12 @@ SECTIONS
.FreeRTOS_sec (NOLOAD) : .FreeRTOS_sec (NOLOAD) :
{ {
*(.FreeRTOSHeapSection) *(.FreeRTOSHeapSection)
} >ITCMRAM } >RAM_D1
.lwIP_sec (NOLOAD) : .lwIP_sec (NOLOAD) :
{ {
*(.lwIPHeapSection) *(.lwIPHeapSection)
} > DTCMRAM } >RAM_D1
/* Remove information from the standard libraries */ /* Remove information from the standard libraries */
/DISCARD/ : /DISCARD/ :