更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
sys_arch.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <arch/sys_arch.h>
33#include <lwip/sys.h>
34#include <lwip/debug.h>
35#include <los_task.h>
36#include <los_sys_pri.h>
37#include <los_tick.h>
38#include <los_queue.h>
39#include <los_sem.h>
40#include <los_mux.h>
41#include <los_spinlock.h>
42/**
43 * @brief
44 * @verbatim
45 移值lwip所需的内核架构层支持.
46 创建线程,互斥锁,信号量,队列的接口实现
47 * @endverbatim
48 */
49
50#ifdef LOSCFG_KERNEL_SMP
51SPIN_LOCK_INIT(arch_protect_spin);
52static u32_t lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
53static int lwprot_count = 0;
54#endif /* LOSCFG_KERNEL_SMP == YES */
55
56#define ROUND_UP_DIV(val, div) (((val) + (div) - 1) / (div))
57
58/**
59 * Thread and System misc
60 */
61//在liteos上实现移值lwip的所需的创建线程接口
62sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio)
63{
64 UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID;
65 UINT32 ret;
66 TSK_INIT_PARAM_S task = {0};
67
68 /* Create host Task */
69 task.pfnTaskEntry = (TSK_ENTRY_FUNC)thread;
70 task.uwStackSize = stackSize;//内核栈大小
71 task.pcName = (char *)name;//任务名称
72 task.usTaskPrio = prio;
73 task.auwArgs[0] = (UINTPTR)arg;
74 task.uwResved = LOS_TASK_STATUS_DETACHED;
75 ret = LOS_TaskCreate(&taskID, &task);
76 if (ret != LOS_OK) {
77 LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: LOS_TaskCreate error %u\n", ret));
78 return -1;
79 }
80
81 return taskID;
82}
83
84void sys_init(void)
85{
86 /* set rand seed to make random sequence diff on every startup */
87 UINT32 seedhsb, seedlsb;
88 LOS_GetCpuCycle(&seedhsb, &seedlsb);
89 srand(seedlsb);
90}
91
92u32_t sys_now(void)
93{
94 /* Lwip docs mentioned like wraparound is not a problem in this funtion */
95 return (u32_t)((LOS_TickCountGet() * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND);
96}
97
98#if (LWIP_CHKSUM_ALGORITHM == 4) /* version #4, asm based */
99#include "in_cksum.h"
100u16_t lwip_standard_chksum(const void *dataptr, int len)
101{
102 return ~(u16_t)(in_cksum(dataptr, len));
103}
104#endif
105
106
107/**
108 * Protector
109 */
110
112{
113#ifdef LOSCFG_KERNEL_SMP
114 /* Note that we are using spinlock instead of mutex for LiteOS-SMP here:
115 * 1. spinlock is more effective for short critical region protection.
116 * 2. this function is called only in task context, not in interrupt handler.
117 * so it's not needed to disable interrupt.
118 */
120 /* We are locking the spinlock where it has not been locked before
121 * or is being locked by another thread */
122 LOS_SpinLock(&arch_protect_spin);
124 lwprot_count = 1;
125 } else {
126 /* It is already locked by THIS thread */
127 lwprot_count++;
128 }
129#else
130 LOS_TaskLock();
131#endif /* LOSCFG_KERNEL_SMP */
132 return 0; /* return value is unused */
133}
134
136{
137 LWIP_UNUSED_ARG(pval);
138#ifdef LOSCFG_KERNEL_SMP
140 lwprot_count--;
141 if (lwprot_count == 0) {
142 lwprot_thread = LOS_ERRNO_TSK_ID_INVALID;
143 LOS_SpinUnlock(&arch_protect_spin);
144 }
145 }
146#else
148#endif /* LOSCFG_KERNEL_SMP */
149}
150
151
152/**
153 * MessageBox
154 */
155//创建消息盒子队列
156err_t sys_mbox_new(sys_mbox_t *mbox, int size)
157{
158 CHAR qName[] = "lwIP";
159 UINT32 ret = LOS_QueueCreate(qName, (UINT16)size, mbox, 0, sizeof(void *));//创建一个队列 "lwip"
160 switch (ret) {
161 case LOS_OK:
162 return ERR_OK;
163 case LOS_ERRNO_QUEUE_CB_UNAVAILABLE:
164 case LOS_ERRNO_QUEUE_CREATE_NO_MEMORY:
165 return ERR_MEM;
166 default:
167 break;
168 }
169 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueCreate error %u\n", __FUNCTION__, ret));
170 return ERR_ARG;
171}
172///发送消息,参数2不能为空,直到发送成功为止
173void sys_mbox_post(sys_mbox_t *mbox, void *msg)
174{
175 /* Caution: the second parameter is NOT &msg */
176 UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), LOS_WAIT_FOREVER);
177 if (ret != LOS_OK) {
178 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
179 }
180}
181///尝试发送消息
182err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
183{
184 /* Caution: the second parameter is NOT &msg */
185 UINT32 ret = LOS_QueueWrite(*mbox, msg, sizeof(char *), 0);
186 switch (ret) {
187 case LOS_OK:
188 return ERR_OK;
189 case LOS_ERRNO_QUEUE_ISFULL:
190 return ERR_MEM;
191 default:
192 break;
193 }
194 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueWrite error %u\n", __FUNCTION__, ret));
195 return ERR_ARG;
196}
197
198err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg);
199//读消息
200u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
201{
202 void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
203 UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
204 UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), tick ? (UINT32)tick : LOS_WAIT_FOREVER);
205 switch (ret) {
206 case LOS_OK:
207 return ERR_OK;
208 case LOS_ERRNO_QUEUE_ISEMPTY:
209 case LOS_ERRNO_QUEUE_TIMEOUT:
210 return SYS_ARCH_TIMEOUT;
211 default:
212 break;
213 }
214 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
215 return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
216}
217///尝试都消息
218u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
219{
220 void *ignore = 0; /* if msg==NULL, the fetched msg should be dropped */
221 UINT32 ret = LOS_QueueRead(*mbox, msg ? msg : &ignore, sizeof(void *), 0);
222 switch (ret) {
223 case LOS_OK:
224 return ERR_OK;
225 case LOS_ERRNO_QUEUE_ISEMPTY:
226 return SYS_MBOX_EMPTY;
227 case LOS_ERRNO_QUEUE_TIMEOUT:
228 return SYS_ARCH_TIMEOUT;
229 default:
230 break;
231 }
232 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_QueueRead error %u\n", __FUNCTION__, ret));
233 return SYS_MBOX_EMPTY; /* Errors should be treated as timeout */
234}
235///删除队列
237{
238 (void)LOS_QueueDelete(*mbox);
239}
240///队列是否有效
242{
243 QUEUE_INFO_S queueInfo;
244 return LOS_OK == LOS_QueueInfoGet(*mbox, &queueInfo);
245}
246
248{
249 *mbox = LOSCFG_BASE_IPC_QUEUE_LIMIT;
250}
251
252
253/**
254 * Semaphore
255 */
256//创建信号量
257err_t sys_sem_new(sys_sem_t *sem, u8_t count)
258{
259 UINT32 ret = LOS_SemCreate(count, sem);
260 if (ret != LOS_OK) {
261 return ERR_ARG;
262 }
263
264 return ERR_OK;
265}
266
268{
269 (void)LOS_SemPost(*sem);
270}
271
272u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs)
273{
274 UINT64 tick = ROUND_UP_DIV((UINT64)timeoutMs * LOSCFG_BASE_CORE_TICK_PER_SECOND, OS_SYS_MS_PER_SECOND);
275 UINT32 ret = LOS_SemPend(*sem, tick ? (UINT32)tick : LOS_WAIT_FOREVER); // timeoutMs 0 means wait forever
276 switch (ret) {
277 case LOS_OK:
278 return ERR_OK;
279 case LOS_ERRNO_SEM_TIMEOUT:
280 return SYS_ARCH_TIMEOUT;
281 default:
282 break;
283 }
284 LWIP_DEBUGF(SYS_DEBUG, ("%s: LOS_SemPend error %u\n", __FUNCTION__, ret));
285 return SYS_ARCH_TIMEOUT; /* Errors should be treated as timeout */
286}
287
289{
290 (void)LOS_SemDelete(*sem);
291}
292
294{
295 return *sem != LOSCFG_BASE_IPC_SEM_LIMIT;
296}
297
299{
300 *sem = LOSCFG_BASE_IPC_SEM_LIMIT;
301}
302
303
304/**
305 * Mutex
306 */
307
309{
310 UINT32 ret = LOS_MuxInit(mutex, NULL);
311 if (ret != LOS_OK) {
312 return ERR_ARG;
313 }
314
315 return ERR_OK;
316}
317
319{
320 (void)LOS_MuxLock(mutex, LOS_WAIT_FOREVER);
321}
322
324{
325 (void)LOS_MuxUnlock(mutex);
326}
327
329{
330 (void)LOS_MuxDestroy(mutex);
331}
332
334{
335 return LOS_MuxIsValid(mutex);
336}
337
339{
340 (void)LOS_MuxDestroy(mutex);
341}
macro EXC_SP_SET stackSize
Definition: asm.h:50
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
初始化互斥锁
Definition: los_mux.c:262
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
释放锁
Definition: los_mux.c:559
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
销毁互斥锁
Definition: los_mux.c:289
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
拿互斥锁,
Definition: los_mux.c:437
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
外部接口, 获取队列信息,用queueInfo 把 LosQueueCB数据接走,QUEUE_INFO_S对内部数据的封装
Definition: los_queue.c:542
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID, UINT32 flags, UINT16 maxMsgSize)
创建一个队列,根据用户传入队列长度和消息节点大小来开辟相应的内存空间以供该队列使用,参数queueID带走队列ID
Definition: los_queue.c:131
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
Delete a queue.
Definition: los_queue.c:486
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
Read a queue.
Definition: los_queue.c:436
LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
Write data into a queue.
Definition: los_queue.c:449
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
对外接口 创建信号量
Definition: los_sem.c:177
LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
对外接口 释放指定的信号量
Definition: los_sem.c:315
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
对外接口 申请指定的信号量,并设置超时时间
Definition: los_sem.c:226
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
对外接口 删除指定的信号量,参数就是 semID
Definition: los_sem.c:187
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
获取自系统启动以来的Tick数
Definition: los_sys.c:82
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
Unlock the task scheduling.
Definition: los_task.c:1148
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
Obtain current running task ID.
Definition: los_task.c:331
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
Lock the task scheduling.
Definition: los_task.c:1139
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *initParam)
创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务
Definition: los_task.c:718
VOID *(* TSK_ENTRY_FUNC)(UINTPTR param1, UINTPTR param2, UINTPTR param3, UINTPTR param4)
Define the type of a task entrance function.
Definition: los_task.h:480
LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt)
获取自系统启动以来的Cycle数
Definition: los_hw_tick.c:54
unsigned short in_cksum(const void *buf, int len)
LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex)
互斥锁是否有效
Definition: los_mux.c:239
VOID LOS_SpinLock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:50
VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:84
unsigned short UINT16
Definition: los_typedef.h:56
long unsigned int UINT64
Definition: los_typedef.h:66
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
void srand(unsigned s)
初始化随机数生成器
Definition: stdlib.c:43
Definition: los_mux.h:73
UINT16 usTaskPrio
Definition: los_task.h:505
UINTPTR auwArgs[4]
Definition: los_task.h:507
UINT32 uwStackSize
Definition: los_task.h:508
CHAR * pcName
Definition: los_task.h:509
TSK_ENTRY_FUNC pfnTaskEntry
Definition: los_task.h:504
UINT32 uwResved
Definition: los_task.h:513
int sys_sem_valid(sys_sem_t *sem)
Definition: sys_arch.c:293
u32_t sys_now(void)
Definition: sys_arch.c:92
void sys_mutex_free(sys_mutex_t *mutex)
Definition: sys_arch.c:328
SPIN_LOCK_INIT(arch_protect_spin)
err_t sys_mutex_new(sys_mutex_t *mutex)
Definition: sys_arch.c:308
void sys_mutex_set_invalid(sys_mutex_t *mutex)
Definition: sys_arch.c:338
void sys_sem_set_invalid(sys_sem_t *sem)
Definition: sys_arch.c:298
u16_t lwip_standard_chksum(const void *dataptr, int len)
Definition: sys_arch.c:100
void sys_mutex_lock(sys_mutex_t *mutex)
Definition: sys_arch.c:318
void sys_mbox_set_invalid(sys_mbox_t *mbox)
Definition: sys_arch.c:247
void sys_mutex_unlock(sys_mutex_t *mutex)
Definition: sys_arch.c:323
sys_prot_t sys_arch_protect(void)
Definition: sys_arch.c:111
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stackSize, int prio)
Definition: sys_arch.c:62
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:288
void sys_arch_unprotect(sys_prot_t pval)
Definition: sys_arch.c:135
int sys_mbox_valid(sys_mbox_t *mbox)
队列是否有效
Definition: sys_arch.c:241
static int lwprot_count
Definition: sys_arch.c:53
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
发送消息,参数2不能为空,直到发送成功为止
Definition: sys_arch.c:173
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
尝试发送消息
Definition: sys_arch.c:182
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:267
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:156
void sys_mbox_free(sys_mbox_t *mbox)
删除队列
Definition: sys_arch.c:236
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeoutMs)
Definition: sys_arch.c:200
static u32_t lwprot_thread
Definition: sys_arch.c:52
int sys_mutex_valid(sys_mutex_t *mutex)
Definition: sys_arch.c:333
void sys_init(void)
Definition: sys_arch.c:84
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeoutMs)
Definition: sys_arch.c:272
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:257
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
尝试都消息
Definition: sys_arch.c:218
uint32_t sys_thread_t
Definition: sys_arch.h:70
void * sys_prot_t
Definition: sys_arch.h:64
uint32_t sys_mbox_t
Definition: sys_arch.h:58
uint32_t sys_sem_t
Definition: sys_arch.h:52
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 void