diff --git a/CHANGELOG b/CHANGELOG index 6e27a66b..29518303 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -6,6 +6,10 @@ HISTORY ++ New features: + 2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage) + * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static + memory message + ++ Bugfixes: diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 857e7d9b..42561c40 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -117,12 +117,6 @@ tcpip_thread(void *arg) break; #endif /* LWIP_NETIF_API */ - case TCPIP_MSG_CALLBACK: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - #if LWIP_TCPIP_TIMEOUT case TCPIP_MSG_TIMEOUT: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); @@ -136,6 +130,17 @@ tcpip_thread(void *arg) break; #endif /* LWIP_TCPIP_TIMEOUT */ + case TCPIP_MSG_CALLBACK: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + memp_free(MEMP_TCPIP_MSG_API, msg); + break; + + case TCPIP_MSG_CALLBACK_STATIC: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); + msg->msg.cb.function(msg->msg.cb.ctx); + break; + default: LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); LWIP_ASSERT("tcpip_thread: invalid message", 0); @@ -392,6 +397,52 @@ tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) #endif /* !LWIP_TCPIP_CORE_LOCKING */ #endif /* LWIP_NETIF_API */ +/** + * Allocate a structure for a static callback message and initialize it. + * This is intended to be used to send "static" messages from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to function + * @return a struct pointer to pass to tcpip_trycallback(). + */ +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) +{ + struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return NULL; + } + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + return (struct tcpip_callback_msg*)msg; +} + +/** + * Free a callback message allocated by tcpip_callbackmsg_new(). + * + * @param msg the message to free + */ +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) +{ + memp_free(MEMP_TCPIP_MSG_API, msg); +} + +/** + * Try to post a callback-message to the tcpip_thread mbox + * This is intended to be used to send "static" messages from interrupt context. + * + * @param msg pointer to the message to post + * @return sys_mbox_trypost() return code + */ +err_t +tcpip_trycallback(struct tcpip_callback_msg* msg) +{ + if (!sys_mbox_valid(&mbox)) { + return ERR_VAL; + } + return sys_mbox_trypost(&mbox, msg); +} + /** * Initialize this module: * - initialize all sub modules diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index 995ba8ad..637476e1 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -77,6 +77,9 @@ typedef void (*tcpip_init_done_fn)(void *arg); /** Function prototype for functions passed to tcpip_callback() */ typedef void (*tcpip_callback_fn)(void *ctx); +/* Forward declarations */ +struct tcpip_callback_msg; + void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); #if LWIP_NETCONN @@ -98,6 +101,10 @@ err_t tcpip_netifapi_lock(struct netifapi_msg *netifapimsg); err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); #define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) +struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); +void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); +err_t tcpip_trycallback(struct tcpip_callback_msg* msg); + /* free pbufs or heap memory from another context without blocking */ err_t pbuf_free_callback(struct pbuf *p); err_t mem_free_callback(void *m); @@ -119,7 +126,8 @@ enum tcpip_msg_type { TCPIP_MSG_TIMEOUT, TCPIP_MSG_UNTIMEOUT, #endif /* LWIP_TCPIP_TIMEOUT */ - TCPIP_MSG_CALLBACK + TCPIP_MSG_CALLBACK, + TCPIP_MSG_CALLBACK_STATIC }; struct tcpip_msg {