- all laboratory practice tasks implemented and tested
This commit is contained in:
parent
46ee3099a5
commit
48a180f89d
@ -13,6 +13,7 @@
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/snmp.h"
|
||||
|
||||
#include "lwip/tcpip.h"
|
||||
#include "mac_drv.h"
|
||||
#include "phy_drv/phy_common.h"
|
||||
|
||||
@ -36,7 +37,7 @@
|
||||
// --------- Ethernet buffers ----------
|
||||
// -------------------------------------
|
||||
|
||||
#define ETH_BUFFER_SIZE (1536UL)
|
||||
#define ETH_BUFFER_SIZE (1528UL)
|
||||
#define ETH_RX_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) {
|
||||
while (true) {
|
||||
fetch_link_properties();
|
||||
tcpip_callback(fetch_link_properties, NULL);
|
||||
osDelay(500);
|
||||
}
|
||||
return;
|
||||
@ -148,7 +149,7 @@ static void low_level_init(struct netif *netif) {
|
||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
|
||||
/* set MAC hardware address */
|
||||
memcpy(netif->hwaddr, &opts.mac, ETHARP_HWADDR_LEN);
|
||||
memcpy(netif->hwaddr, opts.mac, ETHARP_HWADDR_LEN);
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1500;
|
||||
@ -208,15 +209,15 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
|
||||
|
||||
/* check if timestamping is demanded */
|
||||
uint8_t opts = ETHHW_TXOPT_NONE;
|
||||
bool tsEn = (p->tx_cb != NULL);
|
||||
// bool tsEn = (p->tx_cb != NULL);
|
||||
ETHHW_OptArg_TxTsCap optArg;
|
||||
memset(&optArg, 0, sizeof(ETHHW_OptArg_TxTsCap));
|
||||
|
||||
if (tsEn) {
|
||||
opts = ETHHW_TXOPT_CAPTURE_TS;
|
||||
optArg.txTsCbPtr = (uint32_t)(p->tx_cb);
|
||||
optArg.tag = (uint32_t)p->tag;
|
||||
}
|
||||
// if (tsEn) {
|
||||
// opts = ETHHW_TXOPT_CAPTURE_TS;
|
||||
// optArg.txTsCbPtr = (uint32_t)(p->tx_cb);
|
||||
// optArg.tag = (uint32_t)p->tag;
|
||||
// }
|
||||
|
||||
/* Pass the data to the MAC */
|
||||
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 */
|
||||
p->time_s = evt->data.rx.ts_s;
|
||||
p->time_ns = evt->data.rx.ts_ns;
|
||||
// p->time_s = evt->data.rx.ts_s;
|
||||
// p->time_ns = evt->data.rx.ts_ns;
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
|
||||
if (((u8_t *)p->payload)[0] & 1) {
|
||||
@ -384,8 +385,8 @@ err_t ethernetif_init(struct netif *netif) {
|
||||
netif_set_up(netif);
|
||||
|
||||
/* refresh and fetch PHY and link status */
|
||||
phy_refresh_link_status();
|
||||
fetch_link_properties();
|
||||
// phy_refresh_link_status();
|
||||
// fetch_link_properties();
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ static void ETHHW_InitClocks() {
|
||||
RMII_MII_CRS_DV -------------------> PA7
|
||||
RMII_MII_RXD0 ---------------------> PC4
|
||||
RMII_MII_RXD1 ---------------------> PC5
|
||||
RMII_MII_RXER ---------------------> PB10)
|
||||
(RMII_MII_RXER ---------------------> PB10)
|
||||
RMII_MII_TX_EN --------------------> PB11
|
||||
RMII_MII_TXD0 ---------------------> PB12
|
||||
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);
|
||||
|
||||
/* ---- MTL initialization ---- */
|
||||
WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF |
|
||||
(0b10 << 2)); // transmit store and forward ON
|
||||
// and enable transmit queue
|
||||
WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON
|
||||
WRITE_REG(eth->MTLTQOMR, (0b111 << 16) | ETH_MTLTQOMR_TSF | (0b10 << 2)); // transmit store and forward ON and enable transmit queue
|
||||
WRITE_REG(eth->MTLRQOMR, ETH_MTLRQOMR_RSF); // receive store and forward ON
|
||||
|
||||
/* ---- DMA configuration ---- */
|
||||
|
||||
@ -213,8 +211,7 @@ __weak int ETHHW_ReadCallback(ETHHW_EventDesc *evt) {
|
||||
return ETHHW_RET_RX_PROCESSED;
|
||||
}
|
||||
|
||||
ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n,
|
||||
ETHHW_DescFull *bd, int delta) {
|
||||
ETHHW_DescFull *ETHHW_AdvanceDesc(ETHHW_DescFull *start, uint16_t n, ETHHW_DescFull *bd, int delta) {
|
||||
int16_t index = (((uint32_t)(bd)) - ((uint32_t)(start))) / sizeof(ETHHW_DescFull);
|
||||
// int16_t startIndex = index;
|
||||
index = ((int)index + delta) % n;
|
||||
@ -334,7 +331,7 @@ static void ETHHW_PrintRingBufStatus(ETH_TypeDef *eth,
|
||||
|
||||
// process incoming packet
|
||||
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;
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
@ -785,7 +782,8 @@ uint8_t ETHHW_GetAuxTimestampCnt(ETH_TypeDef *eth) {
|
||||
void ETHHW_StartPTPPPSPulseTrain(ETH_TypeDef *eth, uint32_t high_len, uint32_t period) {
|
||||
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,
|
||||
// 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)) {
|
||||
eth->MACPPSCR |= ETH_PTP_PPS_OUTPUT_MODE_SELECT; // switch to pulse-train mode
|
||||
} else {
|
||||
while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {};
|
||||
while (eth->MACPPSCR & ETH_PTP_PPSCMD_MASK) {
|
||||
};
|
||||
}
|
||||
|
||||
eth->MACPPSCR |= ETH_PTP_PPS_PULSE_TRAIN_STOP_IMM;
|
||||
|
||||
@ -222,7 +222,7 @@
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################### 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 UNIQUE_DEV_ID_BASE ((const uint8_t *)0x1FF1E800)
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_IDLE_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 configMAX_PRIORITIES ( 56 )
|
||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )
|
||||
|
||||
@ -56,4 +56,5 @@ target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
# flexptp
|
||||
# etherlib
|
||||
embfmt
|
||||
lwipcore)
|
||||
lwipcore
|
||||
lwipallapps)
|
||||
|
||||
@ -6,6 +6,8 @@ target_sources(
|
||||
sysmem.c
|
||||
system_stm32h7xx.c
|
||||
|
||||
board_support.c
|
||||
board_support.h
|
||||
cmds.c
|
||||
cmds.h
|
||||
)
|
||||
@ -18,4 +20,6 @@ target_include_directories(
|
||||
|
||||
add_subdirectory(standard_output)
|
||||
add_subdirectory(cliutils)
|
||||
add_subdirectory(ethernet)
|
||||
add_subdirectory(ethernet)
|
||||
|
||||
add_subdirectory(user)
|
||||
73
Src/board_support.c
Normal file
73
Src/board_support.c
Normal 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
15
Src/board_support.h
Normal 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 */
|
||||
@ -80,7 +80,7 @@ void init_ethernet() {
|
||||
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);
|
||||
|
||||
return ERR_OK;
|
||||
|
||||
@ -31,9 +31,6 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef SRC_LWIPOPTS
|
||||
#define SRC_LWIPOPTS
|
||||
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
@ -51,7 +48,7 @@
|
||||
|
||||
/* 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. */
|
||||
#define MEM_SIZE (12*1024) // (10*1024)
|
||||
#define MEM_SIZE (16*1024) // (10*1024)
|
||||
|
||||
#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. */
|
||||
#define MEMP_NUM_SYS_TIMEOUT 10
|
||||
|
||||
#define LWIP_PBUF_CUSTOM_DATA \
|
||||
/** Ingress/egress timestamp seconds part */ \
|
||||
u32_t time_s; \
|
||||
/** Ingress/egress timestamp nanoseconds part */ \
|
||||
u32_t time_ns; \
|
||||
/** Transmit callback pointer */ \
|
||||
void (*tx_cb)(uint32_t, uint32_t, uint32_t); \
|
||||
/** Custom tag */ \
|
||||
void * tag;
|
||||
// #define LWIP_PBUF_CUSTOM_DATA \
|
||||
// /** Ingress/egress timestamp seconds part */ \
|
||||
// u32_t time_s; \
|
||||
// /** Ingress/egress timestamp nanoseconds part */ \
|
||||
// u32_t time_ns; \
|
||||
// /** Transmit callback pointer */ \
|
||||
// void (*tx_cb)(uint32_t, uint32_t, uint32_t); \
|
||||
// /** Custom tag */ \
|
||||
// void * tag;
|
||||
|
||||
|
||||
|
||||
@ -134,7 +131,7 @@ a lot of data that needs to be copied, this should be set high. */
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
#define LWIP_DHCP 1
|
||||
|
||||
#define LWIP_DHCP_CHECK_LINK_UP 1
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#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_SSI 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 MEMP_NUM_PARALLEL_HTTPD_CONNS 8
|
||||
#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)
|
||||
*/
|
||||
#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
|
||||
* 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_STACKSIZE 2048
|
||||
#define TCPIP_THREAD_STACKSIZE 3072
|
||||
#define TCPIP_MBOX_SIZE 6
|
||||
#define DEFAULT_UDP_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****/
|
||||
|
||||
|
||||
#endif /* SRC_LWIPOPTS */
|
||||
|
||||
45
Src/main.c
45
Src/main.c
@ -8,6 +8,7 @@
|
||||
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
#include "board_support.h"
|
||||
#include "cliutils/cli.h"
|
||||
#include "cmds.h"
|
||||
#include "ethernet/ethernet_lwip.h"
|
||||
@ -17,6 +18,8 @@
|
||||
|
||||
#include <cmsis_os2.h>
|
||||
|
||||
#include "user/user.h"
|
||||
|
||||
void init_pll() {
|
||||
RCC_OscInitTypeDef osc;
|
||||
RCC_ClkInitTypeDef clk;
|
||||
@ -39,7 +42,7 @@ void init_pll() {
|
||||
osc.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // Wide-range VCO
|
||||
osc.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // input frequency between 8MHz and 16MHz
|
||||
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.PLLQ = 5; // 550MHz -> 110MHz
|
||||
osc.PLL.PLLR = 5; // 550MHz -> 110MHz
|
||||
@ -59,7 +62,7 @@ void init_pll() {
|
||||
clk.APB3CLKDivider = RCC_APB3_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);
|
||||
}
|
||||
|
||||
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) {
|
||||
// initialize on-board LED(s)
|
||||
init_led();
|
||||
// initialize on-board LEDs and buttons
|
||||
leds_init();
|
||||
btn_init();
|
||||
|
||||
// initialize the CLI
|
||||
cli_init();
|
||||
@ -116,10 +108,6 @@ void task_startup(void *arg) {
|
||||
// print greetings
|
||||
print_welcome_message();
|
||||
|
||||
// #ifdef DEBUG
|
||||
// osDelay(2000);
|
||||
// #endif
|
||||
|
||||
// initialize Ethernet
|
||||
init_ethernet();
|
||||
|
||||
@ -128,6 +116,10 @@ void task_startup(void *arg) {
|
||||
|
||||
// -------------
|
||||
|
||||
user_init();
|
||||
|
||||
// -------------
|
||||
|
||||
for (;;) {
|
||||
osDelay(1000);
|
||||
}
|
||||
@ -144,6 +136,10 @@ void init_randomizer() {
|
||||
srand(LL_RNG_ReadRandData32(RNG));
|
||||
}
|
||||
|
||||
void init_mpu() {
|
||||
HAL_MPU_Disable();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// initialize FPU and several system blocks
|
||||
SystemInit();
|
||||
@ -154,9 +150,12 @@ int main(void) {
|
||||
// initialize oscillator and clocking
|
||||
init_osc_and_clk();
|
||||
|
||||
// make random a bit more undeterministic
|
||||
// make random a bit more less deterministic
|
||||
init_randomizer();
|
||||
|
||||
// initialize MPU
|
||||
init_mpu();
|
||||
|
||||
// initialize standard output
|
||||
serial_io_init();
|
||||
|
||||
@ -179,10 +178,6 @@ int main(void) {
|
||||
}
|
||||
}
|
||||
|
||||
// void SysTick_Handler() {
|
||||
// HAL_IncTick();
|
||||
// }
|
||||
|
||||
// ------------------------
|
||||
|
||||
uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".FreeRTOSHeapSection")));
|
||||
|
||||
4
Src/user/CMakeLists.txt
Normal file
4
Src/user/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
target_sources(${CMAKE_PROJECT_NAME} PUBLIC
|
||||
user.h
|
||||
user.c
|
||||
)
|
||||
397
Src/user/user.c
Normal file
397
Src/user/user.c
Normal 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(ðerType, ((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
6
Src/user/user.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef USER_USER
|
||||
#define USER_USER
|
||||
|
||||
void user_init();
|
||||
|
||||
#endif /* USER_USER */
|
||||
@ -176,12 +176,12 @@ SECTIONS
|
||||
.FreeRTOS_sec (NOLOAD) :
|
||||
{
|
||||
*(.FreeRTOSHeapSection)
|
||||
} >ITCMRAM
|
||||
} >RAM_D1
|
||||
|
||||
.lwIP_sec (NOLOAD) :
|
||||
{
|
||||
*(.lwIPHeapSection)
|
||||
} > DTCMRAM
|
||||
} >RAM_D1
|
||||
|
||||
/* Remove information from the standard libraries */
|
||||
/DISCARD/ :
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user