77
88LOG_MODULE_REGISTER (eth, LOG_LEVEL_INF);
99
10- #define ETH_STATIC_IP " 169.254.0.1"
11- #define ETH_NETMASK " 255.255.0.0"
10+ #define ETH_STATIC_IP " 169.254.0.1"
11+ #define ETH_NETMASK " 255.255.0.0"
12+ #define ETH_THREAD_STACK_SIZE 1024
13+ #define ETH_THREAD_PRIORITY 7
14+ #define ETH_RETRY_DELAY_MS 5000
1215
1316static struct net_if *eth_iface;
1417static struct net_mgmt_event_callback eth_cb;
1518static bool eth_configured;
19+ static bool eth_task_running;
20+
21+ static K_SEM_DEFINE (eth_reconfigure_sem, 0 , 1 );
22+
23+ static void eth_thread_entry (void *p1, void *p2, void *p3);
24+
25+ K_THREAD_STACK_DEFINE (eth_thread_stack, ETH_THREAD_STACK_SIZE);
26+ static struct k_thread eth_thread_data;
1627
1728static void eth_event_handler (struct net_mgmt_event_callback *cb,
1829 uint32_t mgmt_event,
@@ -24,29 +35,25 @@ static void eth_event_handler(struct net_mgmt_event_callback *cb,
2435
2536 if (mgmt_event == NET_EVENT_IF_UP) {
2637 LOG_INF (" Ethernet interface up" );
38+ if (eth_task_running && !eth_configured) {
39+ k_sem_give (ð_reconfigure_sem);
40+ }
2741 } else if (mgmt_event == NET_EVENT_IF_DOWN) {
2842 LOG_WRN (" Ethernet interface down" );
43+ eth_configured = false ;
2944 }
3045}
3146
32- extern " C " auto eth_init () -> int
47+ static auto eth_configure () -> int
3348{
3449 struct in_addr addr;
3550 struct in_addr netmask;
3651 struct net_if_addr *ifaddr;
3752
38- eth_iface = net_if_get_first_by_type (&NET_L2_GET_NAME (ETHERNET));
39- if (eth_iface == nullptr ) {
40- LOG_ERR (" No Ethernet interface found" );
41- return -ENODEV;
53+ if (eth_configured) {
54+ return 0 ;
4255 }
4356
44- LOG_INF (" Ethernet interface found: %s" , net_if_get_device (eth_iface)->name );
45-
46- net_mgmt_init_event_callback (ð_cb, eth_event_handler,
47- NET_EVENT_IF_UP | NET_EVENT_IF_DOWN);
48- net_mgmt_add_event_callback (ð_cb);
49-
5057 if (net_addr_pton (AF_INET, ETH_STATIC_IP, &addr) < 0 ) {
5158 LOG_ERR (" Invalid IP address: %s" , ETH_STATIC_IP);
5259 return -EINVAL;
@@ -71,7 +78,84 @@ extern "C" auto eth_init() -> int
7178 return 0 ;
7279}
7380
81+ extern " C" auto eth_init () -> int
82+ {
83+ eth_iface = net_if_get_first_by_type (&NET_L2_GET_NAME (ETHERNET));
84+ if (eth_iface == nullptr ) {
85+ LOG_ERR (" No Ethernet interface found" );
86+ return -ENODEV;
87+ }
88+
89+ LOG_INF (" Ethernet interface found: %s" , net_if_get_device (eth_iface)->name );
90+
91+ net_mgmt_init_event_callback (ð_cb, eth_event_handler,
92+ NET_EVENT_IF_UP | NET_EVENT_IF_DOWN);
93+ net_mgmt_add_event_callback (ð_cb);
94+
95+ return 0 ;
96+ }
97+
7498extern " C" auto eth_is_configured () -> bool
7599{
76100 return eth_configured;
77101}
102+
103+ static void eth_thread_entry (void *p1, void *p2, void *p3)
104+ {
105+ ARG_UNUSED (p1);
106+ ARG_UNUSED (p2);
107+ ARG_UNUSED (p3);
108+
109+ LOG_INF (" ETH background task started" );
110+
111+ while (eth_task_running) {
112+ if (!eth_configured) {
113+ LOG_INF (" Configuring Ethernet interface..." );
114+ int ret = eth_configure ();
115+ if (ret != 0 ) {
116+ LOG_WRN (" Configuration failed, retry in %d ms" , ETH_RETRY_DELAY_MS);
117+ k_msleep (ETH_RETRY_DELAY_MS);
118+ continue ;
119+ }
120+ }
121+
122+ /* Wait for interface down/up event or timeout */
123+ k_sem_take (ð_reconfigure_sem, K_MSEC (ETH_RETRY_DELAY_MS));
124+ }
125+
126+ LOG_INF (" ETH background task stopped" );
127+ }
128+
129+ extern " C" auto eth_start () -> int
130+ {
131+ if (eth_iface == nullptr ) {
132+ LOG_ERR (" Ethernet not initialized, call eth_init() first" );
133+ return -EINVAL;
134+ }
135+
136+ if (eth_task_running) {
137+ LOG_WRN (" ETH task already running" );
138+ return 0 ;
139+ }
140+
141+ eth_task_running = true ;
142+
143+ k_thread_create (ð_thread_data, eth_thread_stack,
144+ K_THREAD_STACK_SIZEOF (eth_thread_stack),
145+ eth_thread_entry, nullptr , nullptr , nullptr ,
146+ ETH_THREAD_PRIORITY, 0 , K_NO_WAIT);
147+
148+ k_thread_name_set (ð_thread_data, " eth_task" );
149+
150+ return 0 ;
151+ }
152+
153+ extern " C" auto eth_stop () -> void
154+ {
155+ if (!eth_task_running) {
156+ return ;
157+ }
158+
159+ eth_task_running = false ;
160+ k_sem_give (ð_reconfigure_sem);
161+ }
0 commit comments