Skip to content

Commit 0808ead

Browse files
jukkargalak
authored andcommitted
net: 6locan: Convert to use k_fifo instead of k_work
Following commits will remove k_work from net_pkt, so convert 6locan L2 to use k_fifo between application and TX thread, and driver and RX error handler. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 5343aed commit 0808ead

File tree

2 files changed

+101
-21
lines changed

2 files changed

+101
-21
lines changed

include/net/can.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ struct canbus_net_ctx {
131131
struct net_if *iface;
132132
/** The link layer address chosen for this interface */
133133
uint16_t ll_addr;
134+
/** TX queue */
135+
struct k_fifo tx_queue;
136+
/** RX error queue */
137+
struct k_fifo rx_err_queue;
138+
/** Queue handler thread */
139+
struct k_thread queue_handler;
140+
/** Queue handler thread stack */
141+
K_KERNEL_STACK_MEMBER(queue_stack, 512);
134142
};
135143

136144
/**

subsys/net/l2/canbus/6locan.c

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -106,45 +106,55 @@ static void canbus_rx_report_err(struct net_pkt *pkt)
106106
net_pkt_unref(pkt);
107107
}
108108

109-
static void rx_err_work_handler(struct k_work *item)
109+
static void rx_err_work_handler(struct net_pkt *pkt)
110110
{
111-
struct net_pkt *pkt = CONTAINER_OF(item, struct net_pkt, work);
112-
113111
canbus_rx_report_err(pkt);
114112
}
115113

116-
static void canbus_rx_report_err_from_isr(struct net_pkt *pkt)
114+
static void submit_to_queue(struct k_fifo *queue, struct net_pkt *pkt)
117115
{
118-
k_work_init(&pkt->work, rx_err_work_handler);
119-
k_work_submit_to_queue(&net_canbus_workq, &pkt->work);
116+
k_fifo_put(queue, pkt);
117+
}
118+
119+
static void canbus_rx_report_err_from_isr(struct k_fifo *queue,
120+
struct net_pkt *pkt)
121+
{
122+
submit_to_queue(queue, pkt);
120123
}
121124

122125
static void canbus_tx_timeout(struct _timeout *t)
123126
{
124127
struct canbus_isotp_tx_ctx *ctx =
125128
CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);
129+
struct net_if *iface = net_pkt_iface(ctx->pkt);
130+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
126131

127132
NET_ERR("TX Timeout. CTX: %p", ctx);
128133
ctx->state = NET_CAN_TX_STATE_ERR;
129-
k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
134+
135+
submit_to_queue(&net_ctx->tx_queue, ctx->pkt);
130136
}
131137

132138
static void canbus_rx_timeout(struct _timeout *t)
133139
{
134140
struct canbus_isotp_rx_ctx *ctx =
135141
CONTAINER_OF(t, struct canbus_isotp_rx_ctx, timeout);
142+
struct net_if *iface = net_pkt_iface(ctx->pkt);
143+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
136144

137145
NET_ERR("RX Timeout. CTX: %p", ctx);
138146
ctx->state = NET_CAN_RX_STATE_TIMEOUT;
139-
canbus_rx_report_err_from_isr(ctx->pkt);
147+
canbus_rx_report_err_from_isr(&net_ctx->rx_err_queue, ctx->pkt);
140148
}
141149

142150
static void canbus_st_min_timeout(struct _timeout *t)
143151
{
144152
struct canbus_isotp_tx_ctx *ctx =
145153
CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);
154+
struct net_if *iface = net_pkt_iface(ctx->pkt);
155+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
146156

147-
k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
157+
submit_to_queue(&net_ctx->tx_queue, ctx->pkt);
148158
}
149159

150160
static k_timeout_t canbus_stmin_to_ticks(uint8_t stmin)
@@ -682,6 +692,8 @@ static void canbus_tx_frame_isr(uint32_t err_flags, void *arg)
682692
{
683693
struct net_pkt *pkt = (struct net_pkt *)arg;
684694
struct canbus_isotp_tx_ctx *ctx = pkt->canbus_tx_ctx;
695+
struct net_if *iface = net_pkt_iface(pkt);
696+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
685697

686698
ctx->tx_backlog--;
687699

@@ -693,7 +705,7 @@ static void canbus_tx_frame_isr(uint32_t err_flags, void *arg)
693705
ctx->state = NET_CAN_TX_STATE_FIN;
694706
}
695707

696-
k_work_submit_to_queue(&net_canbus_workq, &pkt->work);
708+
submit_to_queue(&net_ctx->tx_queue, pkt);
697709
}
698710

699711
static inline int canbus_send_cf(struct net_pkt *pkt)
@@ -792,13 +804,6 @@ static void canbus_tx_work(struct net_pkt *pkt)
792804
}
793805
}
794806

795-
static void canbus_tx_work_handler(struct k_work *item)
796-
{
797-
struct net_pkt *pkt = CONTAINER_OF(item, struct net_pkt, work);
798-
799-
canbus_tx_work(pkt);
800-
}
801-
802807
static enum net_verdict canbus_process_fc_data(struct canbus_isotp_tx_ctx *ctx,
803808
struct net_pkt *pkt)
804809
{
@@ -855,6 +860,8 @@ static enum net_verdict canbus_process_fc(struct net_pkt *pkt)
855860
struct canbus_isotp_tx_ctx *tx_ctx;
856861
uint16_t src_addr = canbus_get_src_lladdr(pkt);
857862
enum net_verdict ret;
863+
struct net_if *iface = net_pkt_iface(pkt);
864+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
858865

859866
tx_ctx = canbus_get_tx_ctx(NET_CAN_TX_STATE_WAIT_FC, src_addr);
860867
if (!tx_ctx) {
@@ -865,7 +872,7 @@ static enum net_verdict canbus_process_fc(struct net_pkt *pkt)
865872

866873
ret = canbus_process_fc_data(tx_ctx, pkt);
867874
if (ret == NET_OK) {
868-
k_work_submit_to_queue(&net_canbus_workq, &tx_ctx->pkt->work);
875+
submit_to_queue(&net_ctx->tx_queue, tx_ctx->pkt);
869876
}
870877

871878
return ret;
@@ -982,8 +989,10 @@ static void canbus_start_sending_cf(struct _timeout *t)
982989
{
983990
struct canbus_isotp_tx_ctx *ctx =
984991
CONTAINER_OF(t, struct canbus_isotp_tx_ctx, timeout);
992+
struct net_if *iface = net_pkt_iface(ctx->pkt);
993+
struct canbus_net_ctx *net_ctx = net_if_l2_data(iface);
985994

986-
k_work_submit_to_queue(&net_canbus_workq, &ctx->pkt->work);
995+
submit_to_queue(&net_ctx->tx_queue, ctx->pkt);
987996
}
988997

989998
static int canbus_send_multiple_frames(struct net_pkt *pkt, size_t len,
@@ -1008,8 +1017,6 @@ static int canbus_send_multiple_frames(struct net_pkt *pkt, size_t len,
10081017
tx_ctx->rem_len = net_pkt_get_len(pkt);
10091018
tx_ctx->tx_backlog = 0;
10101019

1011-
k_work_init(&pkt->work, canbus_tx_work_handler);
1012-
10131020
ret = canbus_send_ff(pkt, len, mcast, dest_addr);
10141021
if (ret != CAN_TX_OK) {
10151022
NET_ERR("Failed to send FF [%d]", ret);
@@ -1708,10 +1715,51 @@ static inline int canbus_init_ll_addr(struct net_if *iface)
17081715
return ret;
17091716
}
17101717

1718+
static void queue_handler(struct canbus_net_ctx *ctx)
1719+
{
1720+
struct k_poll_event events[] = {
1721+
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
1722+
K_POLL_MODE_NOTIFY_ONLY,
1723+
&ctx->tx_queue),
1724+
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_FIFO_DATA_AVAILABLE,
1725+
K_POLL_MODE_NOTIFY_ONLY,
1726+
&ctx->rx_err_queue),
1727+
};
1728+
1729+
struct net_pkt *pkt;
1730+
int ret;
1731+
1732+
while (1) {
1733+
ret = k_poll(events, ARRAY_SIZE(events), K_FOREVER);
1734+
if (ret) {
1735+
continue;
1736+
}
1737+
1738+
if (events[0].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) {
1739+
pkt = k_fifo_get(&ctx->tx_queue, K_NO_WAIT);
1740+
if (pkt != NULL) {
1741+
canbus_tx_work(pkt);
1742+
}
1743+
1744+
events[0].state = K_POLL_STATE_NOT_READY;
1745+
}
1746+
1747+
if (events[1].state == K_POLL_STATE_FIFO_DATA_AVAILABLE) {
1748+
pkt = k_fifo_get(&ctx->rx_err_queue, K_NO_WAIT);
1749+
if (pkt != NULL) {
1750+
rx_err_work_handler(pkt);
1751+
}
1752+
1753+
events[1].state = K_POLL_STATE_NOT_READY;
1754+
}
1755+
}
1756+
}
1757+
17111758
void net_6locan_init(struct net_if *iface)
17121759
{
17131760
struct canbus_net_ctx *ctx = net_if_l2_data(iface);
17141761
int thread_priority;
1762+
k_tid_t tid;
17151763
int i;
17161764

17171765
NET_DBG("Init CAN net interface");
@@ -1746,6 +1794,30 @@ void net_6locan_init(struct net_if *iface)
17461794
thread_priority, NULL);
17471795
k_thread_name_set(&net_canbus_workq.thread, "isotp_work");
17481796
NET_DBG("Workq started. Thread ID: %p", &net_canbus_workq.thread);
1797+
1798+
k_fifo_init(&ctx->tx_queue);
1799+
k_fifo_init(&ctx->rx_err_queue);
1800+
1801+
tid = k_thread_create(&ctx->queue_handler, ctx->queue_stack,
1802+
K_KERNEL_STACK_SIZEOF(ctx->queue_stack),
1803+
(k_thread_entry_t)queue_handler,
1804+
ctx, NULL, NULL,
1805+
thread_priority, 0, K_FOREVER);
1806+
if (!tid) {
1807+
NET_ERR("Cannot create queue handler thread for %d",
1808+
net_if_get_by_iface(iface));
1809+
} else {
1810+
if (IS_ENABLED(CONFIG_THREAD_NAME)) {
1811+
#define MAX_NAME_LEN sizeof("isotp[01]")
1812+
char name[MAX_NAME_LEN];
1813+
1814+
snprintk(name, sizeof(name), "isotp[%d]",
1815+
net_if_get_by_iface(iface));
1816+
k_thread_name_set(tid, name);
1817+
}
1818+
1819+
k_thread_start(tid);
1820+
}
17491821
}
17501822

17511823
static int canbus_enable(struct net_if *iface, bool state)

0 commit comments

Comments
 (0)