ThreadX专门为IAR的C库函数做的互斥接口文件,通过宏定义TX_ENABLE_IAR_LIBRARY_SUPPORT可以使能
程序在ThreadX内核代码的6.0.1里面有,对应文件tx_iar.c
http://www.armbbs.cn/forum.php?mod=viewthread&tid=97925
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be*/
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** IAR Multithreaded Library Support */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Define IAR library for tools prior to version 8.*/
#if (__VER__ < 8000000)
/* IAR version 7 and below.*/
/* Include necessary system files.*/
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer =__iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer =TX_NULL;
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#if _MULTI_THREAD
TX_MUTEX __tx_iar_system_lock_mutexes;
UINT __tx_iar_system_lock_next_free_mutex =0;
/* Define error counters, just for debug purposes.*/
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define the TLS access function for the IAR library.*/
void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp)
{
char _DLIB_TLS_MEMORY *p = 0;
/* Is there a current thread?*/
if (_tx_thread_current_ptr)
p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer;
else
p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD");
p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp);
return (void _DLIB_TLS_MEMORY *) p;
}
/* Define mutexes for IAR library.*/
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list.*/
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex.*/
mutex_ptr =&__tx_iar_system_lock_mutexes;
/* Check for wrap-around on the next free mutex.*/
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0.*/
__tx_iar_system_lock_next_free_mutex =0;
}
/* Is this mutex free?*/
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop!*/
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error!No more free mutexes!*/
/* Increment the no mutexes error counter.*/
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL.*/
*m =TX_NULL;
/* Return.*/
return;
}
/* Now create the ThreadX mutex for the IAR library.*/
status =_tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful.*/
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer.*/
*m =(VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter.*/
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error.*/
*m =TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex.*/
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex.*/
status =_tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_system_lock_isr_caller++;
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex.*/
status =_tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_system_lock_isr_caller++;
}
}
#if _DLIB_FILE_DESCRIPTOR
TX_MUTEX __tx_iar_file_lock_mutexes;
UINT __tx_iar_file_lock_next_free_mutex =0;
/* Define error counters, just for debug purposes.*/
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list.*/
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex.*/
mutex_ptr =&__tx_iar_file_lock_mutexes;
/* Check for wrap-around on the next free mutex.*/
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0.*/
__tx_iar_file_lock_next_free_mutex =0;
}
/* Is this mutex free?*/
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop!*/
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error!No more free mutexes!*/
/* Increment the no mutexes error counter.*/
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL.*/
*m =TX_NULL;
/* Return.*/
return;
}
/* Now create the ThreadX mutex for the IAR library.*/
status =_tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful.*/
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer.*/
*m =(VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter.*/
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error.*/
*m =TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex.*/
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex.*/
status =_tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex.*/
status =_tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_file_lock_isr_caller++;
}
}
#endif/* _DLIB_FILE_DESCRIPTOR */
#endif/* _MULTI_THREAD*/
#endif/* TX_ENABLE_IAR_LIBRARY_SUPPORT*/
#else /* IAR version 8 and above.*/
/* Include necessary system files.*/
#include "tx_api.h"
#include "tx_initialize.h"
#include "tx_thread.h"
#include "tx_mutex.h"
/* This implementation requires that the following macros are defined in the
tx_port.h file and <yvals.h> is included with the following code segments:
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
#include <yvals.h>
#endif
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer;
#else
#define TX_THREAD_EXTENSION_2
#endif
#ifdefTX_ENABLE_IAR_LIBRARY_SUPPORT
void *_tx_iar_create_per_thread_tls_area(void);
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
void __iar_Initlocks(void);
#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer =__iar_dlib_perthread_allocate();
#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \
thread_ptr -> tx_thread_iar_tls_pointer =TX_NULL; } while(0);
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0);
#else
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#endif
This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the
application.
Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected.
*/
#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT
#include <DLib_threads.h>
void * __aeabi_read_tp();
void* _tx_iar_create_per_thread_tls_area();
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr);
#pragma section="__iar_tls$DATA"
/* Define the TLS access function for the IAR library.*/
void * __aeabi_read_tp(void)
{
void *p = 0;
TX_THREAD *thread_ptr = _tx_thread_current_ptr;
if (thread_ptr)
{
p = thread_ptr->tx_thread_iar_tls_pointer;
}
else
{
p = __section_begin("__iar_tls$DATA");
}
return p;
}
/* Define the TLS creation and destruction to use malloc/free.*/
void* _tx_iar_create_per_thread_tls_area()
{
UINT tls_size = __iar_tls_size();
/* Get memory for TLS.*/
void *p = malloc(tls_size);
/* Initialize TLS-area and run constructors for objects in TLS */
__iar_tls_init(p);
return p;
}
void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr)
{
/* Destroy objects living in TLS */
__call_thread_dtors();
free(tls_ptr);
}
#ifndef _MAX_LOCK
#define _MAX_LOCK 4
#endif
static TX_MUTEX __tx_iar_system_lock_mutexes;
static UINT __tx_iar_system_lock_next_free_mutex =0;
/* Define error counters, just for debug purposes.*/
UINT __tx_iar_system_lock_no_mutexes;
UINT __tx_iar_system_lock_internal_errors;
UINT __tx_iar_system_lock_isr_caller;
/* Define mutexes for IAR library.*/
void __iar_system_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list.*/
for (i = 0; i < _MAX_LOCK; i++)
{
/* Setup a pointer to the start of the next free mutex.*/
mutex_ptr =&__tx_iar_system_lock_mutexes;
/* Check for wrap-around on the next free mutex.*/
if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0.*/
__tx_iar_system_lock_next_free_mutex =0;
}
/* Is this mutex free?*/
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop!*/
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error!No more free mutexes!*/
/* Increment the no mutexes error counter.*/
__tx_iar_system_lock_no_mutexes++;
/* Set return pointer to NULL.*/
*m =TX_NULL;
/* Return.*/
return;
}
/* Now create the ThreadX mutex for the IAR library.*/
status =_tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful.*/
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer.*/
*m =(VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter.*/
__tx_iar_system_lock_internal_errors++;
/* Return a NULL pointer to indicate an error.*/
*m =TX_NULL;
}
}
void __iar_system_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex.*/
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_system_Mtxlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex.*/
status =_tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_system_lock_isr_caller++;
}
}
}
void __iar_system_Mtxunlock(__iar_Rmtx *m)
{
if (*m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex.*/
status =_tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_system_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_system_lock_isr_caller++;
}
}
}
#if _DLIB_FILE_DESCRIPTOR
#include <stdio.h> /* Added to get access to FOPEN_MAX */
#ifndef _MAX_FLOCK
#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */
#endif
TX_MUTEX __tx_iar_file_lock_mutexes;
UINT __tx_iar_file_lock_next_free_mutex =0;
/* Define error counters, just for debug purposes.*/
UINT __tx_iar_file_lock_no_mutexes;
UINT __tx_iar_file_lock_internal_errors;
UINT __tx_iar_file_lock_isr_caller;
void __iar_file_Mtxinit(__iar_Rmtx *m)
{
UINT i;
UINT status;
TX_MUTEX *mutex_ptr;
/* First, find a free mutex in the list.*/
for (i = 0; i < _MAX_FLOCK; i++)
{
/* Setup a pointer to the start of the next free mutex.*/
mutex_ptr =&__tx_iar_file_lock_mutexes;
/* Check for wrap-around on the next free mutex.*/
if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK)
{
/* Yes, set the free index back to 0.*/
__tx_iar_file_lock_next_free_mutex =0;
}
/* Is this mutex free?*/
if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID)
{
/* Yes, this mutex is free, get out of the loop!*/
break;
}
}
/* Determine if a free mutex was found. */
if (i >= _MAX_LOCK)
{
/* Error!No more free mutexes!*/
/* Increment the no mutexes error counter.*/
__tx_iar_file_lock_no_mutexes++;
/* Set return pointer to NULL.*/
*m =TX_NULL;
/* Return.*/
return;
}
/* Now create the ThreadX mutex for the IAR library.*/
status =_tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT);
/* Determine if the creation was successful.*/
if (status == TX_SUCCESS)
{
/* Yes, successful creation, return mutex pointer.*/
*m =(VOID *) mutex_ptr;
}
else
{
/* Increment the internal error counter.*/
__tx_iar_file_lock_internal_errors++;
/* Return a NULL pointer to indicate an error.*/
*m =TX_NULL;
}
}
void __iar_file_Mtxdst(__iar_Rmtx *m)
{
/* Simply delete the mutex.*/
_tx_mutex_delete((TX_MUTEX *) *m);
}
void __iar_file_Mtxlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex locks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Get the mutex.*/
status =_tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_file_lock_isr_caller++;
}
}
void __iar_file_Mtxunlock(__iar_Rmtx *m)
{
UINT status;
/* Determine the caller's context. Mutex unlocks are only available from initialization and
threads.*/
if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS))
{
/* Release the mutex.*/
status =_tx_mutex_put((TX_MUTEX *) *m);
/* Check the status of the mutex release.*/
if (status)
{
/* Internal error, increment the counter.*/
__tx_iar_file_lock_internal_errors++;
}
}
else
{
/* Increment the ISR caller error.*/
__tx_iar_file_lock_isr_caller++;
}
}
#endif/* _DLIB_FILE_DESCRIPTOR */
#endif/* TX_ENABLE_IAR_LIBRARY_SUPPORT*/
#endif /* IAR version 8 and above.*/
本帖最后由 zhang0352505 于 2024-3-15 10:53 编辑
这个奇怪的支持,需要在编译设置中打开iar的thread support library。
刚开始老是要报错,不明白为什么,报错如下
然后试了一些设置,最后打开如下设置才编译成功
zhang0352505 发表于 2024-3-15 10:51
这个奇怪的支持,需要在编译设置中打开iar的thread support library。
刚开始老是要报错,不明白为什么, ...
谢谢分享,我都没测试过这个。
页:
[1]