- 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/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;
}

View File

@ -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,9 +116,7 @@ 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->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;

View File

@ -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)

View File

@ -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 )

View File

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

View File

@ -6,6 +6,8 @@ target_sources(
sysmem.c
system_stm32h7xx.c
board_support.c
board_support.h
cmds.c
cmds.h
)
@ -19,3 +21,5 @@ target_include_directories(
add_subdirectory(standard_output)
add_subdirectory(cliutils)
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);
}
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;

View File

@ -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 */

View File

@ -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
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) :
{
*(.FreeRTOSHeapSection)
} >ITCMRAM
} >RAM_D1
.lwIP_sec (NOLOAD) :
{
*(.lwIPHeapSection)
} > DTCMRAM
} >RAM_D1
/* Remove information from the standard libraries */
/DISCARD/ :