Files
2023-06-10 11:52:00 +08:00

306 lines
6.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 主要实现的内容:内核邮箱、内核互斥量、内核信号量、内核线程创建、内核保护
* 可参照STM32CubeMX生成的sys_arch.c
*
*/
#include <lwip/stats.h>
#include <lwip/debug.h>
#include <string.h>
#include "lwip/def.h"
#include "lwip/sys.h"
#include <lwip/opt.h>
#include <lwip/arch.h>
#include "lwip/tcpip.h"
#include "rtthread.h"
#include "stdint.h"
#include "stdio.h"
/*------------------------IPC邮箱实现-------------------------------------------*/
static uint16_t mbox_count=0; //用于对象容器名称计数
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
{
char s1[16]={0};
sprintf(s1,"lwip_mbox#%d",mbox_count);
mbox_count++;
*mbox = rt_mb_create(s1,(rt_ubase_t)size,RT_IPC_FLAG_PRIO);
if(*mbox == NULL) {
return ERR_MEM;
}
return ERR_OK;
}
void sys_mbox_free(sys_mbox_t *mbox)
{
rt_mb_delete(*mbox);
}
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
rt_base_t ret;
//由于RTThread邮箱大小为4个字节所以这里传递的是指针指向的地址
while(ERR_OK != rt_mb_send_wait(*mbox, (rt_uint32_t)msg, RT_WAITING_FOREVER));
}
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
rt_base_t ret;
//由于RTThread邮箱大小为4个字节所以这里传递的是指针指向的地址
ret = rt_mb_send(*mbox, (rt_uint32_t)msg);
if (ret == RT_EOK) {
return ERR_OK;
} else {
return ERR_MEM;
}
}
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
return sys_mbox_trypost(mbox, msg);
}
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms)
{
rt_base_t ret;
void *msg_dummy;
if (!msg) {
msg = &msg_dummy;
}
if (!timeout_ms) {
/* wait infinite */
ret = rt_mb_recv(*mbox, (rt_ubase_t*)msg, RT_WAITING_FOREVER);
} else {
rt_tick_t timeout_ticks = timeout_ms;
ret = rt_mb_recv(*mbox, (rt_ubase_t*)msg, timeout_ticks);
if (ret != RT_EOK) {
/* timed out */
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
rt_base_t ret;
void *msg_dummy;
if (!msg) {
msg = &msg_dummy;
}
ret = rt_mb_recv(*mbox, (rt_ubase_t*)&(*msg), 0);
if (ret != RT_EOK) {
*msg = NULL;
return SYS_MBOX_EMPTY;
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
int sys_mbox_valid(sys_mbox_t *mbox)
{
if (*mbox == NULL)
return 0;
else
return 1;
}
void sys_mbox_set_invalid(sys_mbox_t *mbox)
{
*mbox = NULL;
}
/*----------------------------IPC信号量实现---------------------------------*/
static uint16_t sem_count=0; //用于对象容器名称计数
err_t sys_sem_new(sys_sem_t *sem, u8_t initial_count)
{
char s1[16]={0};
sprintf(s1,"lwip_sem#%d",mbox_count);
sem_count++;
*sem = rt_sem_create(s1,1,RT_IPC_FLAG_PRIO);
if(*sem == NULL) {
return ERR_MEM;
}
if(initial_count == 0)
{
rt_sem_trytake(*sem);
}
else if(initial_count == 1) {
rt_base_t ret = rt_sem_release(*sem);
}
return ERR_OK;
}
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms)
{
rt_base_t ret;
if(!timeout_ms) {
/* wait infinite */
ret = rt_sem_take(*sem, RT_WAITING_FOREVER);
} else {
rt_tick_t timeout_ticks = timeout_ms;
ret = rt_sem_take(*sem, timeout_ticks);
if (ret != RT_EOK) {
/* timed out */
return SYS_ARCH_TIMEOUT;
}
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
void sys_sem_signal(sys_sem_t *sem)
{
rt_base_t ret;
ret = rt_sem_release(*sem);
}
void sys_sem_free(sys_sem_t *sem)
{
rt_sem_delete(*sem);
}
int sys_sem_valid(sys_sem_t *sem)
{
if (*sem == NULL)
return 0;
else
return 1;
}
void sys_sem_set_invalid(sys_sem_t *sem)
{
*sem = NULL;
}
/*----------------------------IPC互斥量---------------------------------*/
#if LWIP_COMPAT_MUTEX == 0
static uint16_t mutex_count=0; //用于对象容器名称计数
err_t sys_mutex_new(sys_mutex_t *mutex)
{
char s1[16]={0};
sprintf(s1,"lwip_mut#%d",mbox_count);
mutex_count++;
*mutex = rt_mutex_create(s1,RT_IPC_FLAG_PRIO);
if(*mutex == NULL) {
return ERR_MEM;
}
return ERR_OK;
}
void sys_mutex_free(sys_mutex_t *mutex)
{
rt_mutex_delete(*mutex);
}
void sys_mutex_lock(sys_mutex_t *mutex)
{
rt_base_t ret;
ret = rt_mutex_take(*mutex, RT_WAITING_FOREVER);
}
void sys_mutex_unlock(sys_mutex_t *mutex)
{
rt_base_t ret;
ret = rt_mutex_release(*mutex);
}
#endif
/*----------------------------IPC线程---------------------------------*/
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
{
rt_base_t ret;
sys_thread_t lwip_thread;
size_t rtos_stacksize;
rtos_stacksize = (size_t)stacksize;
lwip_thread = rt_thread_create(name,thread,arg,rtos_stacksize,prio,50);
rt_thread_startup(lwip_thread);
return lwip_thread;
}
/*----------------------------保护内存申请等---------------------------------*/
//强烈建议在lwipopts.h将该宏打开
//SYS_LIGHTWEIGHT_PROT宏实现可以用于保护内核申请内存时通过互斥量保护
//可以有效避免由于内存申请出现的错误。
#if SYS_LIGHTWEIGHT_PROT == 1
sys_mutex_t lwip_sys_mutex; //内存保护
void sys_init(void)
{
lwip_sys_mutex = rt_mutex_create("lwip_mut",RT_IPC_FLAG_PRIO);
}
sys_prot_t sys_arch_protect(void)
{
rt_base_t ret;
ret = rt_mutex_take(lwip_sys_mutex, RT_WAITING_FOREVER);
return 1;
}
void sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
rt_base_t ret;
ret = rt_mutex_release(lwip_sys_mutex);
}
//void sys_arch_msleep(u32_t delay_ms)
//{
// rt_thread_delay(delay_ms);
//}
#endif
/*-----------------------------LWIP时间计数-------------------------------------*/
u32_t sys_now(void)
{
return rt_tick_get();
}
u32_t sys_jiffies(void)
{
return rt_tick_get();
}