merge
This commit is contained in:
commit
303ef23a48
89
app/main.c
89
app/main.c
@ -11,17 +11,33 @@
|
|||||||
*
|
*
|
||||||
* Date : 2014-6-14
|
* Date : 2014-6-14
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
#include <string.h>
|
||||||
|
#include "nano_shell_server_task.h"
|
||||||
#include "wm_include.h"
|
#include "wm_include.h"
|
||||||
#include "wm_gpio_afsel.h"
|
#include "wm_gpio_afsel.h"
|
||||||
#include "nano_shell.h"
|
#include "nano_shell.h"
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
tls_os_task_t nano_shell_task_handle = NULL;
|
||||||
extern s16 uart0_rx_callback(u16 len, void *user_data);
|
extern s16 uart0_rx_callback(u16 len, void *user_data);
|
||||||
extern s16 uart1_rx_callback(u16 len, void *user_data);
|
extern s16 uart1_rx_callback(u16 len, void *user_data);
|
||||||
extern int shell_printf(const char *format, ...);
|
extern int shell_printf(const char *format, ...);
|
||||||
|
|
||||||
#define NANO_SHELL_TASK_STK_SIZE 1024
|
#define NANO_SHELL_TASK_STK_SIZE 1024
|
||||||
|
#define NANO_SHELL_SERVER_TASK_STK_SIZE 640
|
||||||
#define STATUS_LED WM_IO_PB_18
|
#define STATUS_LED WM_IO_PB_18
|
||||||
|
#define PWM_STATUS_LED WM_IO_PB_25
|
||||||
|
#define FADE_DOWN 1
|
||||||
|
#define FADE_UP -1
|
||||||
|
#define FADE_LOW_THRESHOLD 255
|
||||||
|
#define FADE_HIGH_THRESHOLD 200
|
||||||
|
#define PULSE_FAST 3
|
||||||
|
#define PULSE_SLOW 12
|
||||||
|
|
||||||
|
|
||||||
|
u8 pulse_rate = PULSE_SLOW;
|
||||||
|
|
||||||
void tls_netif_status_event_cb(u8 status)
|
void tls_netif_status_event_cb(u8 status)
|
||||||
{
|
{
|
||||||
@ -36,11 +52,13 @@ void tls_netif_status_event_cb(u8 status)
|
|||||||
break;
|
break;
|
||||||
case NETIF_WIFI_DISCONNECTED:
|
case NETIF_WIFI_DISCONNECTED:
|
||||||
shell_printf("Evt : NETIF_WIFI_DISCONNECTED\n");
|
shell_printf("Evt : NETIF_WIFI_DISCONNECTED\n");
|
||||||
|
pulse_rate = PULSE_SLOW;
|
||||||
break;
|
break;
|
||||||
case NETIF_IP_NET_UP:
|
case NETIF_IP_NET_UP:
|
||||||
shell_printf("Evt : NETIF_IP_NET_UP\nip addr : %v\nnetmask : %v\ngateway : %v\n", netif->ip_addr.addr,
|
shell_printf("Evt : NETIF_IP_NET_UP\nip addr : %v\nnetmask : %v\ngateway : %v\n", netif->ip_addr.addr,
|
||||||
netif->netmask.addr,
|
netif->netmask.addr,
|
||||||
netif->gw.addr);
|
netif->gw.addr);
|
||||||
|
pulse_rate = PULSE_FAST;
|
||||||
break;
|
break;
|
||||||
case NETIF_WIFI_SOFTAP_SUCCESS:
|
case NETIF_WIFI_SOFTAP_SUCCESS:
|
||||||
shell_printf("Evt : NETIF_WIFI_SOFTAP_SUCCESS\n");
|
shell_printf("Evt : NETIF_WIFI_SOFTAP_SUCCESS\n");
|
||||||
@ -65,24 +83,47 @@ void tls_netif_status_event_cb(u8 status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void touchsensor_cb(u32 status)
|
||||||
|
{
|
||||||
|
shell_printf("Touch detected : status(%u)\n", status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tls_gpio_irq_cb(void *arg)
|
||||||
|
{
|
||||||
|
tls_clr_gpio_irq_status(WM_IO_PB_07);
|
||||||
|
}
|
||||||
|
|
||||||
void user_main(void *param)
|
void user_main(void *param)
|
||||||
{
|
{
|
||||||
|
u8 pwm_led_duty_cycle = 255;
|
||||||
|
s8 fading_direction = FADE_UP;
|
||||||
|
|
||||||
//We initialize input/output used by the app
|
//We initialize input/output used by the app
|
||||||
tls_gpio_cfg(STATUS_LED, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_FLOATING);
|
wm_pwm3_config(PWM_STATUS_LED);
|
||||||
|
tls_pwm_init(3, 1000, 0, 0);
|
||||||
wm_uart1_tx_config(WM_IO_PB_06);
|
wm_uart1_tx_config(WM_IO_PB_06);
|
||||||
wm_uart1_rx_config(WM_IO_PB_07);
|
wm_uart1_rx_config(WM_IO_PB_07);
|
||||||
|
tls_gpio_irq_enable(WM_IO_PB_07, WM_GPIO_IRQ_TRIG_DOUBLE_EDGE);
|
||||||
|
tls_gpio_isr_register(WM_IO_PB_07, &(tls_gpio_irq_cb), NULL);
|
||||||
|
//We set a a pin as touch sensor :
|
||||||
|
wm_touch_sensor_config(WM_IO_PA_07);
|
||||||
|
tls_touchsensor_threshold_config(1, 120);
|
||||||
|
tls_touchsensor_init_config(1, 16, 16,1);
|
||||||
|
tls_touchsensor_irq_enable(1);
|
||||||
|
tls_touchsensor_irq_register(&(touchsensor_cb));
|
||||||
|
|
||||||
//We init the uart 1
|
//We init the uart 1
|
||||||
tls_uart_port_init(TLS_UART_1, NULL, 0);
|
tls_uart_port_init(TLS_UART_1, NULL, 0);
|
||||||
|
|
||||||
|
|
||||||
//We create a task for the nano_shell process
|
//We create a task for the nano_shell process
|
||||||
u8 *nano_shell_task_stack = NULL;
|
u8 *nano_shell_task_stack = NULL, *nano_shell_server_task_stack = NULL;
|
||||||
tls_os_task_t nano_shell_task_handle = NULL;
|
|
||||||
|
|
||||||
tls_uart_rx_callback_register(TLS_UART_0, &(uart0_rx_callback), NULL);
|
tls_uart_rx_callback_register(TLS_UART_0, &(uart0_rx_callback), NULL);
|
||||||
tls_uart_rx_callback_register(TLS_UART_1, &(uart1_rx_callback), NULL);
|
tls_uart_rx_callback_register(TLS_UART_1, &(uart1_rx_callback), NULL);
|
||||||
|
|
||||||
|
nano_shell_server_task_stack = tls_mem_alloc(sizeof(u32) * NANO_SHELL_SERVER_TASK_STK_SIZE);
|
||||||
|
|
||||||
nano_shell_task_stack = tls_mem_alloc(sizeof(u32) * NANO_SHELL_TASK_STK_SIZE);
|
nano_shell_task_stack = tls_mem_alloc(sizeof(u32) * NANO_SHELL_TASK_STK_SIZE);
|
||||||
if(nano_shell_task_stack != NULL)
|
if(nano_shell_task_stack != NULL)
|
||||||
{
|
{
|
||||||
@ -101,10 +142,48 @@ void user_main(void *param)
|
|||||||
shell_printf("Registering netif callback.\n");
|
shell_printf("Registering netif callback.\n");
|
||||||
tls_netif_add_status_event(&(tls_netif_status_event_cb));
|
tls_netif_add_status_event(&(tls_netif_status_event_cb));
|
||||||
|
|
||||||
|
//Socket test
|
||||||
|
/*
|
||||||
|
char buffer[100] = "", *found = NULL;
|
||||||
|
struct sockaddr_in server = {
|
||||||
|
.sin_family = AF_INET,
|
||||||
|
.sin_addr.s_addr = INADDR_ANY,
|
||||||
|
.sin_port = htons(80)
|
||||||
|
};
|
||||||
|
struct sockaddr_in client;
|
||||||
|
socklen_t socklent = sizeof(client);
|
||||||
|
int listening_socket = socket(AF_INET, SOCK_STREAM, 0), client_socket;
|
||||||
|
bind(listening_socket, (struct sockaddr *)&server, sizeof(server));
|
||||||
|
listen(listening_socket, 1);*/
|
||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
tls_gpio_write(STATUS_LED, !tls_gpio_read(STATUS_LED));
|
tls_pwm_duty_set(3, pwm_led_duty_cycle);
|
||||||
tls_os_time_delay(500);
|
if(pwm_led_duty_cycle == FADE_LOW_THRESHOLD)
|
||||||
|
{
|
||||||
|
fading_direction = FADE_UP;
|
||||||
|
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate == PULSE_SLOW ? 500 : 100));
|
||||||
|
}
|
||||||
|
else if(pwm_led_duty_cycle == FADE_HIGH_THRESHOLD)
|
||||||
|
{
|
||||||
|
fading_direction = FADE_DOWN;
|
||||||
|
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate == PULSE_SLOW ? 500 : 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
pwm_led_duty_cycle+=fading_direction;
|
||||||
|
|
||||||
|
tls_os_time_delay(pdMS_TO_TICKS(pulse_rate));
|
||||||
|
/*client_socket = accept(listening_socket, (struct sockaddr *)&client, &socklent);
|
||||||
|
shell_printf("Client got accepted\n");
|
||||||
|
while(recv(client_socket, buffer, 99, 0) > 0)
|
||||||
|
{
|
||||||
|
if((found = strchr(buffer, '\r')) != NULL)
|
||||||
|
*found = '\0';
|
||||||
|
if(buffer[0])
|
||||||
|
shell_printf("Recv data : #%s#\n", buffer);
|
||||||
|
memset(buffer, 0, sizeof buffer);
|
||||||
|
}
|
||||||
|
close(client_socket);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,20 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
#include "command/command.h"
|
#include "command/command.h"
|
||||||
#include "wm_include.h"
|
#include "wm_include.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
extern int shell_printf(const char *format, ...);
|
extern int shell_printf(const char *format, ...);
|
||||||
extern int wm_printf(const char *fmt,...);
|
extern int wm_printf(const char *fmt,...);
|
||||||
|
extern u32 tls_mem_get_avail_heapsize(void);
|
||||||
|
|
||||||
|
extern int demo_bt_enable();
|
||||||
|
extern int demo_bt_destroy();
|
||||||
|
extern int demo_ble_server_on();
|
||||||
|
extern int demo_ble_server_off();
|
||||||
|
|
||||||
void tls_wifi_client_event_cb(u8 *mac, enum tls_wifi_client_event_type event)
|
void tls_wifi_client_event_cb(u8 *mac, enum tls_wifi_client_event_type event)
|
||||||
{
|
{
|
||||||
@ -57,24 +65,59 @@ void tls_wifi_data_ext_recv_cb(u8* data, u32 data_len, struct tls_wifi_ext_t *ex
|
|||||||
for(u32 i = 0; i < data_len; i++)
|
for(u32 i = 0; i < data_len; i++)
|
||||||
{
|
{
|
||||||
shell_printf("%02X", data[i]);
|
shell_printf("%02X", data[i]);
|
||||||
if(i % 20 == 0)
|
if(i % 30 == 0)
|
||||||
shell_printf("\n");
|
shell_printf("\n");
|
||||||
}
|
}
|
||||||
|
shell_printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int _task_list(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
void tls_rtc_irq_cb(void *arg)
|
||||||
{
|
{
|
||||||
char *buf = NULL;
|
struct tm rtc_time;
|
||||||
|
tls_get_rtc(&rtc_time);
|
||||||
|
|
||||||
buf = tls_mem_alloc(1024);
|
shell_printf("rtc isr called\ntime is :\n%d:%d:%d %d/%d/%d\n",
|
||||||
if(NULL == buf)
|
rtc_time.tm_hour,
|
||||||
return 0;
|
rtc_time.tm_min,
|
||||||
|
rtc_time.tm_sec,
|
||||||
|
rtc_time.tm_mday,
|
||||||
|
rtc_time.tm_mon,
|
||||||
|
rtc_time.tm_year);
|
||||||
|
|
||||||
|
tls_rtc_timer_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
int _system(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
if(strcmp(argv[1], "list_task") == 0)
|
||||||
|
{
|
||||||
|
char *buf = NULL;
|
||||||
|
|
||||||
|
buf = tls_mem_alloc(1024);
|
||||||
|
if(NULL == buf)
|
||||||
|
return 0;
|
||||||
#if configUSE_TRACE_FACILITY
|
#if configUSE_TRACE_FACILITY
|
||||||
vTaskList((signed char *)buf);
|
vTaskList(buf);
|
||||||
#endif
|
#endif
|
||||||
shell_printf("\n%s\nbuf_len : %d\n", buf, strlen(buf));
|
shell_printf("\n%s\nbuf_len : %d\n", buf, strlen(buf));
|
||||||
tls_mem_free(buf);
|
tls_mem_free(buf);
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "ram_usage") == 0)
|
||||||
|
{
|
||||||
|
shell_printf("Free OS heap : %u/%u byte(s)\ntls heap size : %u\n", xPortGetFreeHeapSize(), configTOTAL_HEAP_SIZE, tls_mem_get_avail_heapsize());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("List of system actions :\nlist_task\nram_usage\n");
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +140,8 @@ int _soft_ap(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
struct tls_softap_info_t ap_info;
|
struct tls_softap_info_t ap_info;
|
||||||
struct tls_ip_info_t ip_info;
|
struct tls_ip_info_t ip_info;
|
||||||
|
|
||||||
tls_wifi_disconnect();
|
tls_wifi_set_oneshot_flag(0);
|
||||||
|
tls_wifi_softap_destroy();
|
||||||
|
|
||||||
shell_printf("Registering client event callback\n");
|
shell_printf("Registering client event callback\n");
|
||||||
tls_wifi_softap_client_event_register(&(tls_wifi_client_event_cb));
|
tls_wifi_softap_client_event_register(&(tls_wifi_client_event_cb));
|
||||||
@ -127,14 +171,14 @@ int _soft_ap(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
else if(strcmp(argv[1], "destroy") == 0)
|
else if(strcmp(argv[1], "destroy") == 0)
|
||||||
{
|
{
|
||||||
//tls_wifi_softap_destroy();
|
|
||||||
tls_wifi_softap_client_event_register(NULL);
|
tls_wifi_softap_client_event_register(NULL);
|
||||||
tls_wifi_disconnect();
|
tls_wifi_set_oneshot_flag(0);
|
||||||
|
tls_wifi_softap_destroy();
|
||||||
shell_printf("Stopping SOFT AP\n");
|
shell_printf("Stopping SOFT AP\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shell_printf("Unknown soft_ap action\n");
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -180,11 +224,12 @@ int _station(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
else if(strcmp(argv[1], "disconnect") == 0)
|
else if(strcmp(argv[1], "disconnect") == 0)
|
||||||
{
|
{
|
||||||
shell_printf("Disconnecting from current station\n");
|
shell_printf("Disconnecting from current station\n");
|
||||||
|
tls_wifi_set_oneshot_flag(0);
|
||||||
tls_wifi_disconnect();
|
tls_wifi_disconnect();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shell_printf("Unknown station action\n");
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -227,14 +272,40 @@ int _wifi(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
shell_printf("WiFi promiscuous off\n");
|
shell_printf("WiFi promiscuous off\n");
|
||||||
tls_wifi_data_ext_recv_cb_register(NULL);
|
tls_wifi_data_ext_recv_cb_register(NULL);
|
||||||
}
|
}
|
||||||
|
else if(strcmp(argv[1], "mode") == 0)
|
||||||
|
{
|
||||||
|
shell_printf("Mode is : %d\n", tls_wifi_get_oneshot_flag());
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "get_ip") == 0)
|
||||||
|
{
|
||||||
|
struct netif *netif = tls_get_netif();
|
||||||
|
|
||||||
|
if(netif)
|
||||||
|
{
|
||||||
|
shell_printf("netif 1\nip addr : %v\nnetmask : %v\ngateway : %v\n", netif->ip_addr.addr,
|
||||||
|
netif->netmask.addr,
|
||||||
|
netif->gw.addr);
|
||||||
|
|
||||||
|
if(netif->next)
|
||||||
|
{
|
||||||
|
shell_printf("netif 2\nip addr : %v\nnetmask : %v\ngateway : %v\n", netif->next->ip_addr.addr,
|
||||||
|
netif->next->netmask.addr,
|
||||||
|
netif->next->gw.addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("No netif yet, connect to sta or create soft_ap !\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shell_printf("Unknown wifi action\n");
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shell_printf("List of wifi actions :\noff\nerror\npromiscuous_on\npromiscuous_off\n");
|
shell_printf("List of wifi actions :\noff\nerror\npromiscuous_on\npromiscuous_off\nmode\nget_ip\n");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -255,7 +326,7 @@ int _wifi_sleep(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shell_printf("Unknown wifi_sleep action\n");
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -266,11 +337,150 @@ int _wifi_sleep(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _pmu(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
if(strcmp(argv[1], "sleep") == 0)
|
||||||
|
{
|
||||||
|
u32 duration = strtoul(argv[2], NULL, 10);
|
||||||
|
shell_printf("Going to sleep mode for %u s\n", duration);
|
||||||
|
tls_pmu_timer0_start(duration);
|
||||||
|
tls_pmu_sleep_start();
|
||||||
|
shell_printf("Waking up out of sleep mode\n");
|
||||||
|
tls_pmu_timer0_stop();
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "standby") == 0)
|
||||||
|
{
|
||||||
|
u32 duration = strtoul(argv[2], NULL, 10);
|
||||||
|
shell_printf("Going to standby mode for %u s\n", duration);
|
||||||
|
tls_pmu_timer0_start(duration);
|
||||||
|
tls_pmu_standby_start();
|
||||||
|
shell_printf("Waking up out of standby mode\n");
|
||||||
|
tls_pmu_timer0_stop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("List of pmu actions :\nsleep <duration(s)>\nstandby <duration(s)>\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
NANO_SHELL_ADD_CMD(task_list,
|
int _rtc(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||||
_task_list,
|
{
|
||||||
"List all tasks",
|
if(argc > 1)
|
||||||
" Use this command to list all defined tasks\r\n");
|
{
|
||||||
|
if(strcmp(argv[1], "get") == 0)
|
||||||
|
{
|
||||||
|
struct tm rtc_time;
|
||||||
|
tls_get_rtc(&rtc_time);
|
||||||
|
|
||||||
|
shell_printf("rtc time is :\n%d:%d:%d %d/%d/%d\n",
|
||||||
|
rtc_time.tm_hour,
|
||||||
|
rtc_time.tm_min,
|
||||||
|
rtc_time.tm_sec,
|
||||||
|
rtc_time.tm_mday,
|
||||||
|
rtc_time.tm_mon,
|
||||||
|
rtc_time.tm_year);
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "set") == 0)
|
||||||
|
{
|
||||||
|
struct tm rtc_time;
|
||||||
|
|
||||||
|
rtc_time.tm_hour = strtoul(argv[2], NULL, 10);
|
||||||
|
rtc_time.tm_min = strtoul(argv[3], NULL, 10);
|
||||||
|
rtc_time.tm_sec = strtoul(argv[4], NULL, 10);
|
||||||
|
rtc_time.tm_mday = strtoul(argv[5], NULL, 10);
|
||||||
|
rtc_time.tm_mon = strtoul(argv[6], NULL, 10);
|
||||||
|
rtc_time.tm_year = strtoul(argv[7], NULL, 10);
|
||||||
|
|
||||||
|
shell_printf("Setting rtc to :\n%d:%d:%d %d/%d/%d\nisr callback registered !\n",
|
||||||
|
rtc_time.tm_hour,
|
||||||
|
rtc_time.tm_min,
|
||||||
|
rtc_time.tm_sec,
|
||||||
|
rtc_time.tm_mday,
|
||||||
|
rtc_time.tm_mon,
|
||||||
|
rtc_time.tm_year);
|
||||||
|
|
||||||
|
tls_set_rtc(&rtc_time);
|
||||||
|
tls_rtc_isr_register(&(tls_rtc_irq_cb), NULL);
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "alarm") == 0)
|
||||||
|
{
|
||||||
|
struct tm rtc_time;
|
||||||
|
|
||||||
|
rtc_time.tm_hour = strtoul(argv[2], NULL, 10);
|
||||||
|
rtc_time.tm_min = strtoul(argv[3], NULL, 10);
|
||||||
|
rtc_time.tm_sec = strtoul(argv[4], NULL, 10);
|
||||||
|
rtc_time.tm_mday = strtoul(argv[5], NULL, 10);
|
||||||
|
rtc_time.tm_mon = strtoul(argv[6], NULL, 10);
|
||||||
|
rtc_time.tm_year = strtoul(argv[7], NULL, 10);
|
||||||
|
|
||||||
|
shell_printf("Setting rtc alarm to :\n%d:%d:%d %d/%d/%d\n",
|
||||||
|
rtc_time.tm_hour,
|
||||||
|
rtc_time.tm_min,
|
||||||
|
rtc_time.tm_sec,
|
||||||
|
rtc_time.tm_mday,
|
||||||
|
rtc_time.tm_mon,
|
||||||
|
rtc_time.tm_year);
|
||||||
|
|
||||||
|
tls_rtc_timer_start(&(rtc_time));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("List of rtc actions :\nget\nset <h> <m> <s> <d> <m> <y>\nalarm <h> <m> <s> <d> <m> <y>\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _bluetooth(const shell_cmd_t *pcmd, int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
if(strcmp(argv[1], "enable") == 0)
|
||||||
|
{
|
||||||
|
//shell_printf("Enabling bluetooth : %d\n", demo_bt_enable());
|
||||||
|
shell_printf("Enabling bluetooth test\n");
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "disable") == 0)
|
||||||
|
{
|
||||||
|
//shell_printf("Disabling bluetooth : %d\n", demo_bt_destroy());
|
||||||
|
shell_printf("Disabling bluetooth test\n");
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "start_demo") == 0)
|
||||||
|
{
|
||||||
|
shell_printf("Starting demo : %d\nUse a BLE app to find the device\n", demo_ble_server_on());
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "stop_demo") == 0)
|
||||||
|
{
|
||||||
|
shell_printf("Stopping demo : %d\n", demo_ble_server_off());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("Unknown %s action\n", argv[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shell_printf("List of bluetooth actions :\nenable\ndisable\nstart_demo\nstop_demo\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NANO_SHELL_ADD_CMD(system,
|
||||||
|
_system,
|
||||||
|
"Query system information",
|
||||||
|
" Use this command to get system information\r\n");
|
||||||
NANO_SHELL_ADD_CMD(reset,
|
NANO_SHELL_ADD_CMD(reset,
|
||||||
_reset,
|
_reset,
|
||||||
"Reset the system",
|
"Reset the system",
|
||||||
@ -295,3 +505,15 @@ NANO_SHELL_ADD_CMD(wifi_sleep,
|
|||||||
_wifi_sleep,
|
_wifi_sleep,
|
||||||
"Command to control WiFi sleep",
|
"Command to control WiFi sleep",
|
||||||
" Use this command to control WiFi sleep feature\r\n");
|
" Use this command to control WiFi sleep feature\r\n");
|
||||||
|
NANO_SHELL_ADD_CMD(pmu,
|
||||||
|
_pmu,
|
||||||
|
"Command to control the power management unit",
|
||||||
|
" Use this command to control power management unit feature\r\n");
|
||||||
|
NANO_SHELL_ADD_CMD(rtc,
|
||||||
|
_rtc,
|
||||||
|
"Command to query and set up the rtc",
|
||||||
|
" Use this command to interact with the rtc module\n");
|
||||||
|
NANO_SHELL_ADD_CMD(bluetooth,
|
||||||
|
_bluetooth,
|
||||||
|
"Command to control bluetooth functionality",
|
||||||
|
" Use this command to interact use bluetooth\n");
|
||||||
|
|||||||
@ -3,39 +3,70 @@
|
|||||||
|
|
||||||
static_fifo_declare(uart_char_fifo, 256, unsigned char, char);
|
static_fifo_declare(uart_char_fifo, 256, unsigned char, char);
|
||||||
extern int sendchar(int ch);
|
extern int sendchar(int ch);
|
||||||
|
extern void network_write(char c);
|
||||||
|
extern tls_os_task_t nano_shell_task_handle;
|
||||||
|
|
||||||
s16 uart0_rx_callback(u16 len, void *user_data)
|
s16 uart0_rx_callback(u16 len, void *user_data)
|
||||||
{
|
{
|
||||||
|
(void)len;
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
u8 buff[256] = "";
|
u8 buff[256] = "";
|
||||||
int data_len = tls_uart_read(TLS_UART_0, (u8 *) buff, 256);
|
int data_len = tls_uart_read(TLS_UART_0, (u8 *) buff, 256);
|
||||||
for(int i = 0; i < data_len; i++)
|
for(int i = 0; i < data_len; i++)
|
||||||
|
{
|
||||||
fifo_push(uart_char_fifo, buff[i]);
|
fifo_push(uart_char_fifo, buff[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)tls_os_task_resume_from_isr(nano_shell_task_handle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s16 uart1_rx_callback(u16 len, void *user_data)
|
s16 uart1_rx_callback(u16 len, void *user_data)
|
||||||
{
|
{
|
||||||
|
(void)len;
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
u8 buff[256] = "";
|
u8 buff[256] = "";
|
||||||
int data_len = tls_uart_read(TLS_UART_1, (u8 *) buff, 256);
|
int data_len = tls_uart_read(TLS_UART_1, (u8 *) buff, 256);
|
||||||
for(int i = 0; i < data_len; i++)
|
for(int i = 0; i < data_len; i++)
|
||||||
|
{
|
||||||
fifo_push(uart_char_fifo, buff[i]);
|
fifo_push(uart_char_fifo, buff[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)tls_os_task_resume_from_isr(nano_shell_task_handle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void network_rx_callback(u16 len, char *data)
|
||||||
|
{
|
||||||
|
if(!len)return;
|
||||||
|
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
fifo_push(uart_char_fifo, data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)tls_os_task_resume(nano_shell_task_handle);
|
||||||
|
}
|
||||||
|
|
||||||
int shell_getc(char *ch)
|
int shell_getc(char *ch)
|
||||||
{
|
{
|
||||||
//Do not forget to sleep a bit to let the idle task run ...
|
|
||||||
tls_os_time_delay(5);
|
|
||||||
if(is_fifo_empty(uart_char_fifo))
|
if(is_fifo_empty(uart_char_fifo))
|
||||||
return 0;
|
{
|
||||||
|
//If the fifo is empty then we can suspend the task since
|
||||||
|
//it is only waiting for inputs to be processed
|
||||||
|
tls_os_task_suspend(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
*ch = fifo_pop_unsafe(uart_char_fifo);
|
*ch = fifo_pop_unsafe(uart_char_fifo);
|
||||||
return 1;
|
return 1;
|
||||||
//return tls_uart_read(TLS_UART_0, (u8 *) ch, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void low_level_write_char(char ch)
|
void low_level_write_char(char ch)
|
||||||
{
|
{
|
||||||
(void)sendchar((int)ch);
|
(void)sendchar((int)ch);
|
||||||
(void)tls_uart_write(TLS_UART_1, &ch, 1);
|
(void)tls_uart_write(TLS_UART_1, &ch, 1);
|
||||||
|
network_write(ch);
|
||||||
}
|
}
|
||||||
|
|||||||
6
app/nano_shell_server_task.c
Normal file
6
app/nano_shell_server_task.c
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "nano_shell_server_task.h"
|
||||||
|
|
||||||
|
void network_write(char c)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
0
app/nano_shell_server_task.h
Normal file
0
app/nano_shell_server_task.h
Normal file
@ -214,7 +214,10 @@ tls_os_status_t tls_os_task_create(tls_os_task_t *task,
|
|||||||
*
|
*
|
||||||
* @note Generally, you do not need to call this function in your application.
|
* @note Generally, you do not need to call this function in your application.
|
||||||
*/
|
*/
|
||||||
|
// This API call is not available in freertos 8.0.0
|
||||||
|
#if 0
|
||||||
tls_os_status_t tls_os_task_del(u8 prio, void (*freefun)(void));
|
tls_os_status_t tls_os_task_del(u8 prio, void (*freefun)(void));
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function allows you to delete a task. The calling
|
* @brief This function allows you to delete a task. The calling
|
||||||
@ -232,6 +235,12 @@ tls_os_status_t tls_os_task_del(u8 prio, void (*freefun)(void));
|
|||||||
*/
|
*/
|
||||||
tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void));
|
tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void));
|
||||||
|
|
||||||
|
tls_os_status_t tls_os_task_suspend(tls_os_task_t task);
|
||||||
|
|
||||||
|
tls_os_status_t tls_os_task_resume(tls_os_task_t task);
|
||||||
|
|
||||||
|
tls_os_status_t tls_os_task_resume_from_isr(tls_os_task_t task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function creates a mutual exclusion semaphore
|
* @brief This function creates a mutual exclusion semaphore
|
||||||
*
|
*
|
||||||
@ -707,6 +716,8 @@ tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer);
|
|||||||
*/
|
*/
|
||||||
void tls_os_time_delay(u32 ticks);
|
void tls_os_time_delay(u32 ticks);
|
||||||
|
|
||||||
|
void tls_os_time_delay_until(u32 *previous_ticks , u32 ticks);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is used to display all the tasks' detail status.
|
* @brief This function is used to display all the tasks' detail status.
|
||||||
|
|||||||
@ -83,6 +83,11 @@
|
|||||||
#include "wm_regs.h"
|
#include "wm_regs.h"
|
||||||
#include "wm_watchdog.h"
|
#include "wm_watchdog.h"
|
||||||
#include "wm_adc.h"
|
#include "wm_adc.h"
|
||||||
|
#include "wm_pmu.h"
|
||||||
|
#include "wm_touchsensor.h"
|
||||||
|
#include "wm_irq.h"
|
||||||
|
#include "wm_rtc.h"
|
||||||
|
#include "wm_ble.h"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -453,7 +453,7 @@ void task_start (void *data)
|
|||||||
if (tststarthdl)
|
if (tststarthdl)
|
||||||
{
|
{
|
||||||
tls_os_task_del_by_task_handle(tststarthdl,task_start_free);
|
tls_os_task_del_by_task_handle(tststarthdl,task_start_free);
|
||||||
}
|
}
|
||||||
tls_os_time_delay(0x10000000);
|
tls_os_time_delay(0x10000000);
|
||||||
#else
|
#else
|
||||||
#if 1
|
#if 1
|
||||||
|
|||||||
@ -473,7 +473,7 @@ int tls_at_bt_cleanup_host()
|
|||||||
int demo_bt_enable()
|
int demo_bt_enable()
|
||||||
{
|
{
|
||||||
tls_bt_status_t status;
|
tls_bt_status_t status;
|
||||||
uint8_t uart_no = 1; //default we use uart 1 for testing;
|
uint8_t uart_no = 2; //default we use uart 1 for testing;
|
||||||
tls_appl_trace_level = TLS_BT_LOG_VERBOSE;
|
tls_appl_trace_level = TLS_BT_LOG_VERBOSE;
|
||||||
tls_bt_hci_if_t hci_if;
|
tls_bt_hci_if_t hci_if;
|
||||||
|
|
||||||
|
|||||||
@ -1,142 +1,194 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#define INC_FREERTOS_H
|
#define INC_FREERTOS_H
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Include the generic headers required for the FreeRTOS port being used.
|
* Include the generic headers required for the FreeRTOS port being used.
|
||||||
*/
|
*/
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If stdint.h cannot be located then:
|
||||||
|
* + If using GCC ensure the -nostdint options is *not* being used.
|
||||||
|
* + Ensure the project's include path includes the directory in which your
|
||||||
|
* compiler stores stdint.h.
|
||||||
|
* + Set any compiler options necessary for it to support C99, as technically
|
||||||
|
* stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any
|
||||||
|
* other way).
|
||||||
|
* + The FreeRTOS download includes a simple stdint.h definition that can be
|
||||||
|
* used in cases where none is provided by the compiler. The files only
|
||||||
|
* contains the typedefs required to build FreeRTOS. Read the instructions
|
||||||
|
* in FreeRTOS/source/stdint.readme for more information.
|
||||||
|
*/
|
||||||
|
#include <stdint.h> /* READ COMMENT ABOVE. */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Basic FreeRTOS definitions. */
|
/* Basic FreeRTOS definitions. */
|
||||||
#include "projdefs.h"
|
#include "projdefs.h"
|
||||||
|
|
||||||
/* Application specific configuration options. */
|
/* Application specific configuration options. */
|
||||||
#include "FreeRTOSConfig.h"
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* configUSE_PORT_OPTIMISED_TASK_SELECTION must be defined before portable.h
|
||||||
|
is included as it is used by the port layer. */
|
||||||
|
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Definitions specific to the port being used. */
|
/* Definitions specific to the port being used. */
|
||||||
#include "portable.h"
|
#include "portable.h"
|
||||||
|
|
||||||
|
|
||||||
/* Defines the prototype to which the application task hook function must
|
|
||||||
conform. */
|
|
||||||
typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
|
||||||
|
|
||||||
|
|
||||||
extern int ulSetInterruptMaskFromISR( void );
|
|
||||||
extern void vClearInterruptMaskFromISR( int ulMask );
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check all the required application specific macros have been defined.
|
* Check all the required application specific macros have been defined.
|
||||||
* These macros are application specific and (as downloaded) are defined
|
* These macros are application specific and (as downloaded) are defined
|
||||||
* within FreeRTOSConfig.h.
|
* within FreeRTOSConfig.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef configMINIMAL_STACK_SIZE
|
||||||
|
#error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMAX_PRIORITIES
|
||||||
|
#error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_PREEMPTION
|
#ifndef configUSE_PREEMPTION
|
||||||
#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_IDLE_HOOK
|
#ifndef configUSE_IDLE_HOOK
|
||||||
#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_TICK_HOOK
|
#ifndef configUSE_TICK_HOOK
|
||||||
#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_CO_ROUTINES
|
#ifndef configUSE_CO_ROUTINES
|
||||||
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: configUSE_CO_ROUTINES must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_vTaskPrioritySet
|
#ifndef INCLUDE_vTaskPrioritySet
|
||||||
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_vTaskPrioritySet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_uxTaskPriorityGet
|
#ifndef INCLUDE_uxTaskPriorityGet
|
||||||
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_uxTaskPriorityGet must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_vTaskDelete
|
#ifndef INCLUDE_vTaskDelete
|
||||||
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_vTaskDelete must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_vTaskSuspend
|
#ifndef INCLUDE_vTaskSuspend
|
||||||
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_vTaskSuspend must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_vTaskDelayUntil
|
#ifndef INCLUDE_vTaskDelayUntil
|
||||||
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_vTaskDelayUntil must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_vTaskDelay
|
#ifndef INCLUDE_vTaskDelay
|
||||||
#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: INCLUDE_vTaskDelay must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_16_BIT_TICKS
|
#ifndef configUSE_16_BIT_TICKS
|
||||||
#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
#error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configUSE_CO_ROUTINES != 0
|
||||||
|
#ifndef configMAX_CO_ROUTINE_PRIORITIES
|
||||||
|
#error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1.
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMAX_PRIORITIES
|
||||||
|
#error configMAX_PRIORITIES must be defined to be greater than or equal to 1.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
||||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
||||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xQueueGetMutexHolder
|
||||||
|
#define INCLUDE_xQueueGetMutexHolder 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xSemaphoreGetMutexHolder
|
||||||
|
#define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_pcTaskGetTaskName
|
#ifndef INCLUDE_pcTaskGetTaskName
|
||||||
#define INCLUDE_pcTaskGetTaskName 0
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
#endif
|
#endif
|
||||||
@ -146,7 +198,11 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
|
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
|
||||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_eTaskGetState
|
||||||
|
#define INCLUDE_eTaskGetState 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_RECURSIVE_MUTEXES
|
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||||
@ -158,15 +214,11 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_TIMERS
|
#ifndef configUSE_TIMERS
|
||||||
#define configUSE_TIMERS 1
|
#define configUSE_TIMERS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_COUNTING_SEMAPHORES
|
#ifndef configUSE_COUNTING_SEMAPHORES
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 0
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef configUSE_MAILBOX
|
|
||||||
#define configUSE_MAILBOX 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configUSE_ALTERNATIVE_API
|
#ifndef configUSE_ALTERNATIVE_API
|
||||||
@ -193,26 +245,34 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#define INCLUDE_xTaskResumeFromISR 1
|
#define INCLUDE_xTaskResumeFromISR 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xEventGroupSetBitFromISR
|
||||||
|
#define INCLUDE_xEventGroupSetBitFromISR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTimerPendFunctionCall
|
||||||
|
#define INCLUDE_xTimerPendFunctionCall 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef configASSERT
|
#ifndef configASSERT
|
||||||
#define configASSERT( x )
|
#define configASSERT( x )
|
||||||
|
#define configASSERT_DEFINED 0
|
||||||
|
#else
|
||||||
|
#define configASSERT_DEFINED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The timers module relies on xTaskGetSchedulerState(). */
|
/* The timers module relies on xTaskGetSchedulerState(). */
|
||||||
#if configUSE_TIMERS == 1
|
#if configUSE_TIMERS == 1
|
||||||
|
|
||||||
#ifndef configTIMER_TASK_PRIORITY
|
#ifndef configTIMER_TASK_PRIORITY
|
||||||
#define configTIMER_TASK_PRIORITY 1
|
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
|
||||||
// #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
|
|
||||||
#endif /* configTIMER_TASK_PRIORITY */
|
#endif /* configTIMER_TASK_PRIORITY */
|
||||||
|
|
||||||
#ifndef configTIMER_QUEUE_LENGTH
|
#ifndef configTIMER_QUEUE_LENGTH
|
||||||
//#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
|
#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
|
||||||
#define configTIMER_QUEUE_LENGTH 128
|
|
||||||
#endif /* configTIMER_QUEUE_LENGTH */
|
#endif /* configTIMER_QUEUE_LENGTH */
|
||||||
|
|
||||||
#ifndef configTIMER_TASK_STACK_DEPTH
|
#ifndef configTIMER_TASK_STACK_DEPTH
|
||||||
#define configTIMER_TASK_STACK_DEPTH 200
|
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
|
||||||
//#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
|
|
||||||
#endif /* configTIMER_TASK_STACK_DEPTH */
|
#endif /* configTIMER_TASK_STACK_DEPTH */
|
||||||
|
|
||||||
#endif /* configUSE_TIMERS */
|
#endif /* configUSE_TIMERS */
|
||||||
@ -227,13 +287,24 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
|
|
||||||
|
|
||||||
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
||||||
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
|
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
|
||||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vClearInterruptMaskFromISR( uxSavedStatusValue )
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCLEAN_UP_TCB
|
||||||
|
#define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portPRE_TASK_DELETE_HOOK
|
||||||
|
#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portSETUP_TCB
|
||||||
|
#define portSETUP_TCB( pxTCB ) ( void ) pxTCB
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef configQUEUE_REGISTRY_SIZE
|
#ifndef configQUEUE_REGISTRY_SIZE
|
||||||
#define configQUEUE_REGISTRY_SIZE 0U
|
#define configQUEUE_REGISTRY_SIZE 0U
|
||||||
@ -245,7 +316,7 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portPOINTER_SIZE_TYPE
|
#ifndef portPOINTER_SIZE_TYPE
|
||||||
#define portPOINTER_SIZE_TYPE unsigned long
|
#define portPOINTER_SIZE_TYPE uint32_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove any unused trace macros. */
|
/* Remove any unused trace macros. */
|
||||||
@ -267,12 +338,45 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#define traceTASK_SWITCHED_IN()
|
#define traceTASK_SWITCHED_IN()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceINCREASE_TICK_COUNT
|
||||||
|
/* Called before stepping the tick count after waking from tickless idle
|
||||||
|
sleep. */
|
||||||
|
#define traceINCREASE_TICK_COUNT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceLOW_POWER_IDLE_BEGIN
|
||||||
|
/* Called immediately before entering tickless idle. */
|
||||||
|
#define traceLOW_POWER_IDLE_BEGIN()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceLOW_POWER_IDLE_END
|
||||||
|
/* Called when returning to the Idle task after a tickless idle. */
|
||||||
|
#define traceLOW_POWER_IDLE_END()
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef traceTASK_SWITCHED_OUT
|
#ifndef traceTASK_SWITCHED_OUT
|
||||||
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
|
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
|
||||||
to the task control block of the task being switched out. */
|
to the task control block of the task being switched out. */
|
||||||
#define traceTASK_SWITCHED_OUT()
|
#define traceTASK_SWITCHED_OUT()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_INHERIT
|
||||||
|
/* Called when a task attempts to take a mutex that is already held by a
|
||||||
|
lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task
|
||||||
|
that holds the mutex. uxInheritedPriority is the priority the mutex holder
|
||||||
|
will inherit (the priority of the task that is attempting to obtain the
|
||||||
|
muted. */
|
||||||
|
#define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_DISINHERIT
|
||||||
|
/* Called when a task releases a mutex, the holding of which had resulted in
|
||||||
|
the task inheriting the priority of a higher priority task.
|
||||||
|
pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the
|
||||||
|
mutex. uxOriginalPriority is the task's configured (base) priority. */
|
||||||
|
#define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
|
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
|
||||||
/* Task is about to block because it cannot read from a
|
/* Task is about to block because it cannot read from a
|
||||||
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||||
@ -290,17 +394,21 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef configCHECK_FOR_STACK_OVERFLOW
|
#ifndef configCHECK_FOR_STACK_OVERFLOW
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The following event macros are embedded in the kernel API calls. */
|
/* The following event macros are embedded in the kernel API calls. */
|
||||||
|
|
||||||
#ifndef traceQUEUE_CREATE
|
#ifndef traceMOVED_TASK_TO_READY_STATE
|
||||||
|
#define traceMOVED_TASK_TO_READY_STATE( pxTCB )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_CREATE
|
||||||
#define traceQUEUE_CREATE( pxNewQueue )
|
#define traceQUEUE_CREATE( pxNewQueue )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef traceQUEUE_CREATE_FAILED
|
#ifndef traceQUEUE_CREATE_FAILED
|
||||||
#define traceQUEUE_CREATE_FAILED()
|
#define traceQUEUE_CREATE_FAILED( ucQueueType )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef traceCREATE_MUTEX
|
#ifndef traceCREATE_MUTEX
|
||||||
@ -351,6 +459,10 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#define traceQUEUE_PEEK( pxQueue )
|
#define traceQUEUE_PEEK( pxQueue )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_PEEK_FROM_ISR
|
||||||
|
#define traceQUEUE_PEEK_FROM_ISR( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef traceQUEUE_RECEIVE_FAILED
|
#ifndef traceQUEUE_RECEIVE_FAILED
|
||||||
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
|
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
|
||||||
#endif
|
#endif
|
||||||
@ -371,6 +483,10 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
|
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED
|
||||||
|
#define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef traceQUEUE_DELETE
|
#ifndef traceQUEUE_DELETE
|
||||||
#define traceQUEUE_DELETE( pxQueue )
|
#define traceQUEUE_DELETE( pxQueue )
|
||||||
#endif
|
#endif
|
||||||
@ -435,6 +551,70 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
|
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceMALLOC
|
||||||
|
#define traceMALLOC( pvAddress, uiSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceFREE
|
||||||
|
#define traceFREE( pvAddress, uiSize )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_CREATE
|
||||||
|
#define traceEVENT_GROUP_CREATE( xEventGroup )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_CREATE_FAILED
|
||||||
|
#define traceEVENT_GROUP_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_SYNC_BLOCK
|
||||||
|
#define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_SYNC_END
|
||||||
|
#define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK
|
||||||
|
#define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_WAIT_BITS_END
|
||||||
|
#define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_CLEAR_BITS
|
||||||
|
#define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR
|
||||||
|
#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_SET_BITS
|
||||||
|
#define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR
|
||||||
|
#define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEVENT_GROUP_DELETE
|
||||||
|
#define traceEVENT_GROUP_DELETE( xEventGroup )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef tracePEND_FUNC_CALL
|
||||||
|
#define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef tracePEND_FUNC_CALL_FROM_ISR
|
||||||
|
#define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_REGISTRY_ADD
|
||||||
|
#define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef configGENERATE_RUN_TIME_STATS
|
#ifndef configGENERATE_RUN_TIME_STATS
|
||||||
#define configGENERATE_RUN_TIME_STATS 0
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
#endif
|
#endif
|
||||||
@ -462,7 +642,7 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portPRIVILEGE_BIT
|
#ifndef portPRIVILEGE_BIT
|
||||||
#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
|
#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef portYIELD_WITHIN_API
|
#ifndef portYIELD_WITHIN_API
|
||||||
@ -474,7 +654,102 @@ extern void vClearInterruptMaskFromISR( int ulMask );
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef vPortFreeAligned
|
#ifndef vPortFreeAligned
|
||||||
#define vPortFreeAligned( pvBlockToFree ) if (xPortMemIsKernel(pvBlockToFree)) vPortFree( pvBlockToFree )
|
#define vPortFreeAligned( pvBlockToFree ) vPortFree( pvBlockToFree )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||||
|
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP
|
||||||
|
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2
|
||||||
|
#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TICKLESS_IDLE
|
||||||
|
#define configUSE_TICKLESS_IDLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configPRE_SLEEP_PROCESSING
|
||||||
|
#define configPRE_SLEEP_PROCESSING( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configPOST_SLEEP_PROCESSING
|
||||||
|
#define configPOST_SLEEP_PROCESSING( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_QUEUE_SETS
|
||||||
|
#define configUSE_QUEUE_SETS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portTASK_USES_FLOATING_POINT
|
||||||
|
#define portTASK_USES_FLOATING_POINT()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TIME_SLICING
|
||||||
|
#define configUSE_TIME_SLICING 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS
|
||||||
|
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_NEWLIB_REENTRANT
|
||||||
|
#define configUSE_NEWLIB_REENTRANT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_STATS_FORMATTING_FUNCTIONS
|
||||||
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID
|
||||||
|
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TRACE_FACILITY
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef mtCOVERAGE_TEST_MARKER
|
||||||
|
#define mtCOVERAGE_TEST_MARKER()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Definitions to allow backward compatibility with FreeRTOS versions prior to
|
||||||
|
V8 if desired. */
|
||||||
|
#ifndef configENABLE_BACKWARD_COMPATIBILITY
|
||||||
|
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configENABLE_BACKWARD_COMPATIBILITY == 1
|
||||||
|
#define eTaskStateGet eTaskGetState
|
||||||
|
#define portTickType TickType_t
|
||||||
|
#define xTaskHandle TaskHandle_t
|
||||||
|
#define xQueueHandle QueueHandle_t
|
||||||
|
#define xSemaphoreHandle SemaphoreHandle_t
|
||||||
|
#define xQueueSetHandle QueueSetHandle_t
|
||||||
|
#define xQueueSetMemberHandle QueueSetMemberHandle_t
|
||||||
|
#define xTimeOutType TimeOut_t
|
||||||
|
#define xMemoryRegion MemoryRegion_t
|
||||||
|
#define xTaskParameters TaskParameters_t
|
||||||
|
#define xTaskStatusType TaskStatus_t
|
||||||
|
#define xTimerHandle TimerHandle_t
|
||||||
|
#define xCoRoutineHandle CoRoutineHandle_t
|
||||||
|
#define pdTASK_HOOK_CODE TaskHookFunction_t
|
||||||
|
#define portTICK_RATE_MS portTICK_PERIOD_MS
|
||||||
|
|
||||||
|
/* Backward compatibility within the scheduler code only - these definitions
|
||||||
|
are not really required but are included for completeness. */
|
||||||
|
#define tmrTIMER_CALLBACK TimerCallbackFunction_t
|
||||||
|
#define pdTASK_CODE TaskFunction_t
|
||||||
|
#define xListItem ListItem_t
|
||||||
|
#define xList List_t
|
||||||
|
#endif /* configENABLE_BACKWARD_COMPATIBILITY */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* INC_FREERTOS_H */
|
#endif /* INC_FREERTOS_H */
|
||||||
|
|||||||
481
src/os/rtos/include/FreeRTOS.h.old
Normal file
481
src/os/rtos/include/FreeRTOS.h.old
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#define INC_FREERTOS_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Include the generic headers required for the FreeRTOS port being used.
|
||||||
|
*/
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/* Basic FreeRTOS definitions. */
|
||||||
|
#include "projdefs.h"
|
||||||
|
|
||||||
|
/* Application specific configuration options. */
|
||||||
|
#include "FreeRTOSConfig.h"
|
||||||
|
|
||||||
|
/* Definitions specific to the port being used. */
|
||||||
|
#include "portable.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines the prototype to which the application task hook function must
|
||||||
|
conform. */
|
||||||
|
typedef portBASE_TYPE (*pdTASK_HOOK_CODE)( void * );
|
||||||
|
|
||||||
|
|
||||||
|
extern int ulSetInterruptMaskFromISR( void );
|
||||||
|
extern void vClearInterruptMaskFromISR( int ulMask );
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check all the required application specific macros have been defined.
|
||||||
|
* These macros are application specific and (as downloaded) are defined
|
||||||
|
* within FreeRTOSConfig.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef configUSE_PREEMPTION
|
||||||
|
#error Missing definition: configUSE_PREEMPTION should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_IDLE_HOOK
|
||||||
|
#error Missing definition: configUSE_IDLE_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TICK_HOOK
|
||||||
|
#error Missing definition: configUSE_TICK_HOOK should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_CO_ROUTINES
|
||||||
|
#error Missing definition: configUSE_CO_ROUTINES should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskPrioritySet
|
||||||
|
#error Missing definition: INCLUDE_vTaskPrioritySet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_uxTaskPriorityGet
|
||||||
|
#error Missing definition: INCLUDE_uxTaskPriorityGet should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelete
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelete should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskSuspend
|
||||||
|
#error Missing definition: INCLUDE_vTaskSuspend should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelayUntil
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelayUntil should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_vTaskDelay
|
||||||
|
#error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_16_BIT_TICKS
|
||||||
|
#error Missing definition: configUSE_16_BIT_TICKS should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetIdleTaskHandle
|
||||||
|
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTimerGetTimerDaemonTaskHandle
|
||||||
|
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_pcTaskGetTaskName
|
||||||
|
#define INCLUDE_pcTaskGetTaskName 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_APPLICATION_TASK_TAG
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_uxTaskGetStackHighWaterMark
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_RECURSIVE_MUTEXES
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_MUTEXES
|
||||||
|
#define configUSE_MUTEXES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_TIMERS
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_COUNTING_SEMAPHORES
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_MAILBOX
|
||||||
|
#define configUSE_MAILBOX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_ALTERNATIVE_API
|
||||||
|
#define configUSE_ALTERNATIVE_API 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCRITICAL_NESTING_IN_TCB
|
||||||
|
#define portCRITICAL_NESTING_IN_TCB 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMAX_TASK_NAME_LEN
|
||||||
|
#define configMAX_TASK_NAME_LEN 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configIDLE_SHOULD_YIELD
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if configMAX_TASK_NAME_LEN < 1
|
||||||
|
#error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskResumeFromISR
|
||||||
|
#define INCLUDE_xTaskResumeFromISR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configASSERT
|
||||||
|
#define configASSERT( x )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The timers module relies on xTaskGetSchedulerState(). */
|
||||||
|
#if configUSE_TIMERS == 1
|
||||||
|
|
||||||
|
#ifndef configTIMER_TASK_PRIORITY
|
||||||
|
#define configTIMER_TASK_PRIORITY 1
|
||||||
|
// #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined.
|
||||||
|
#endif /* configTIMER_TASK_PRIORITY */
|
||||||
|
|
||||||
|
#ifndef configTIMER_QUEUE_LENGTH
|
||||||
|
//#error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined.
|
||||||
|
#define configTIMER_QUEUE_LENGTH 128
|
||||||
|
#endif /* configTIMER_QUEUE_LENGTH */
|
||||||
|
|
||||||
|
#ifndef configTIMER_TASK_STACK_DEPTH
|
||||||
|
#define configTIMER_TASK_STACK_DEPTH 200
|
||||||
|
//#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
|
||||||
|
#endif /* configTIMER_TASK_STACK_DEPTH */
|
||||||
|
|
||||||
|
#endif /* configUSE_TIMERS */
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetSchedulerState
|
||||||
|
#define INCLUDE_xTaskGetSchedulerState 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INCLUDE_xTaskGetCurrentTaskHandle
|
||||||
|
#define INCLUDE_xTaskGetCurrentTaskHandle 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
|
||||||
|
#define portSET_INTERRUPT_MASK_FROM_ISR() ulSetInterruptMaskFromISR()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
|
||||||
|
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vClearInterruptMaskFromISR( uxSavedStatusValue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef configQUEUE_REGISTRY_SIZE
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 0U
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configQUEUE_REGISTRY_SIZE < 1 )
|
||||||
|
#define vQueueAddToRegistry( xQueue, pcName )
|
||||||
|
#define vQueueUnregisterQueue( xQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portPOINTER_SIZE_TYPE
|
||||||
|
#define portPOINTER_SIZE_TYPE unsigned long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove any unused trace macros. */
|
||||||
|
#ifndef traceSTART
|
||||||
|
/* Used to perform any necessary initialisation - for example, open a file
|
||||||
|
into which trace is to be written. */
|
||||||
|
#define traceSTART()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceEND
|
||||||
|
/* Use to close a trace, for example close a file into which trace has been
|
||||||
|
written. */
|
||||||
|
#define traceEND()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SWITCHED_IN
|
||||||
|
/* Called after a task has been selected to run. pxCurrentTCB holds a pointer
|
||||||
|
to the task control block of the selected task. */
|
||||||
|
#define traceTASK_SWITCHED_IN()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SWITCHED_OUT
|
||||||
|
/* Called before a task has been selected to run. pxCurrentTCB holds a pointer
|
||||||
|
to the task control block of the task being switched out. */
|
||||||
|
#define traceTASK_SWITCHED_OUT()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceBLOCKING_ON_QUEUE_RECEIVE
|
||||||
|
/* Task is about to block because it cannot read from a
|
||||||
|
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||||
|
upon which the read was attempted. pxCurrentTCB points to the TCB of the
|
||||||
|
task that attempted the read. */
|
||||||
|
#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceBLOCKING_ON_QUEUE_SEND
|
||||||
|
/* Task is about to block because it cannot write to a
|
||||||
|
queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore
|
||||||
|
upon which the write was attempted. pxCurrentTCB points to the TCB of the
|
||||||
|
task that attempted the write. */
|
||||||
|
#define traceBLOCKING_ON_QUEUE_SEND( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configCHECK_FOR_STACK_OVERFLOW
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following event macros are embedded in the kernel API calls. */
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_CREATE
|
||||||
|
#define traceQUEUE_CREATE( pxNewQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_CREATE_FAILED
|
||||||
|
#define traceQUEUE_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_MUTEX
|
||||||
|
#define traceCREATE_MUTEX( pxNewQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_MUTEX_FAILED
|
||||||
|
#define traceCREATE_MUTEX_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceGIVE_MUTEX_RECURSIVE
|
||||||
|
#define traceGIVE_MUTEX_RECURSIVE( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED
|
||||||
|
#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTAKE_MUTEX_RECURSIVE
|
||||||
|
#define traceTAKE_MUTEX_RECURSIVE( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED
|
||||||
|
#define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_COUNTING_SEMAPHORE
|
||||||
|
#define traceCREATE_COUNTING_SEMAPHORE()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED
|
||||||
|
#define traceCREATE_COUNTING_SEMAPHORE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND
|
||||||
|
#define traceQUEUE_SEND( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FAILED
|
||||||
|
#define traceQUEUE_SEND_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE
|
||||||
|
#define traceQUEUE_RECEIVE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_PEEK
|
||||||
|
#define traceQUEUE_PEEK( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FAILED
|
||||||
|
#define traceQUEUE_RECEIVE_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FROM_ISR
|
||||||
|
#define traceQUEUE_SEND_FROM_ISR( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_SEND_FROM_ISR_FAILED
|
||||||
|
#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FROM_ISR
|
||||||
|
#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED
|
||||||
|
#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceQUEUE_DELETE
|
||||||
|
#define traceQUEUE_DELETE( pxQueue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_CREATE
|
||||||
|
#define traceTASK_CREATE( pxNewTCB )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_CREATE_FAILED
|
||||||
|
#define traceTASK_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELETE
|
||||||
|
#define traceTASK_DELETE( pxTaskToDelete )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELAY_UNTIL
|
||||||
|
#define traceTASK_DELAY_UNTIL()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_DELAY
|
||||||
|
#define traceTASK_DELAY()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_PRIORITY_SET
|
||||||
|
#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_SUSPEND
|
||||||
|
#define traceTASK_SUSPEND( pxTaskToSuspend )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_RESUME
|
||||||
|
#define traceTASK_RESUME( pxTaskToResume )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_RESUME_FROM_ISR
|
||||||
|
#define traceTASK_RESUME_FROM_ISR( pxTaskToResume )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTASK_INCREMENT_TICK
|
||||||
|
#define traceTASK_INCREMENT_TICK( xTickCount )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_CREATE
|
||||||
|
#define traceTIMER_CREATE( pxNewTimer )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_CREATE_FAILED
|
||||||
|
#define traceTIMER_CREATE_FAILED()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_COMMAND_SEND
|
||||||
|
#define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_EXPIRED
|
||||||
|
#define traceTIMER_EXPIRED( pxTimer )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef traceTIMER_COMMAND_RECEIVED
|
||||||
|
#define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configGENERATE_RUN_TIME_STATS
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
|
||||||
|
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
|
||||||
|
#error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base.
|
||||||
|
#endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */
|
||||||
|
|
||||||
|
#ifndef portGET_RUN_TIME_COUNTER_VALUE
|
||||||
|
#ifndef portALT_GET_RUN_TIME_COUNTER_VALUE
|
||||||
|
#error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information.
|
||||||
|
#endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */
|
||||||
|
#endif /* portGET_RUN_TIME_COUNTER_VALUE */
|
||||||
|
|
||||||
|
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||||
|
|
||||||
|
#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS
|
||||||
|
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef configUSE_MALLOC_FAILED_HOOK
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portPRIVILEGE_BIT
|
||||||
|
#define portPRIVILEGE_BIT ( ( unsigned portBASE_TYPE ) 0x00 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portYIELD_WITHIN_API
|
||||||
|
#define portYIELD_WITHIN_API portYIELD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef pvPortMallocAligned
|
||||||
|
#define pvPortMallocAligned( x, puxStackBuffer ) ( ( ( puxStackBuffer ) == NULL ) ? ( pvPortMalloc( ( x ) ) ) : ( puxStackBuffer ) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef vPortFreeAligned
|
||||||
|
#define vPortFreeAligned( pvBlockToFree ) if (xPortMemIsKernel(pvBlockToFree)) vPortFree( pvBlockToFree )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* INC_FREERTOS_H */
|
||||||
|
|
||||||
@ -68,29 +68,34 @@
|
|||||||
* See http://www.freertos.org/a00110.html.
|
* See http://www.freertos.org/a00110.html.
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1 //使用抢先式内核
|
#define configUSE_PREEMPTION 1 //ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ں<EFBFBD>
|
||||||
#define configUSE_IDLE_HOOK 1 //使用空闲钩子
|
#define configUSE_IDLE_HOOK 1 //ʹ<EFBFBD>ÿ<EFBFBD><EFBFBD>й<EFBFBD><EFBFBD><EFBFBD>
|
||||||
#define configUSE_TICK_HOOK 0 //不使用时间片钩子
|
#define configUSE_TICK_HOOK 0 //<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
#define configCPU_CLOCK_HZ ( ( unsigned long ) 40000000 ) /* =12.0MHz xtal multiplied by 5 using the PLL. *///内部处理器执行频率
|
#define configCPU_CLOCK_HZ ( ( unsigned long ) 40000000 ) /* =12.0MHz xtal multiplied by 5 using the PLL. *///<EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>
|
||||||
|
|
||||||
#define configTICK_RATE_HZ ( ( portTickType ) 500u ) //时间片中断的频率
|
#define configTICK_RATE_HZ ( ( portTickType ) 500u ) //ʱ<><CAB1>Ƭ<EFBFBD>жϵ<D0B6>Ƶ<EFBFBD><C6B5>
|
||||||
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 63) //应用程序中可用优先级的数目
|
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 63) //Ӧ<>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>п<EFBFBD><D0BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||||
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 90 ) //空闲任务使用的堆栈大小
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 90 ) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õĶ<C3B5>ջ<EFBFBD><D5BB>С
|
||||||
#define configTOTAL_HEAP_SIZE ( ( size_t ) 12 * 1024 ) //内核中可用的RAM数量,heap2使用
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) 20 * 1024 ) //<2F>ں<EFBFBD><DABA>п<EFBFBD><D0BF>õ<EFBFBD>RAM<41><4D><EFBFBD><EFBFBD>,heap2ʹ<32><CAB9>
|
||||||
#define configMAX_TASK_NAME_LEN ( 8 ) //创建任务名称最大允许长度
|
#define configMAX_TASK_NAME_LEN ( 8 ) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
#define configUSE_TRACE_FACILITY 1 //是否使用可视化追踪
|
#define configUSE_TRACE_FACILITY 1 //<2F>Ƿ<EFBFBD>ʹ<EFBFBD>ÿ<EFBFBD><C3BF>ӻ<EFBFBD><EFBFBD><D7B7>
|
||||||
#define configUSE_16_BIT_TICKS 0 //定义portTickType
|
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||||
#define configIDLE_SHOULD_YIELD 1 //讲阻止空闲任务让出时间直到他的时间片用完
|
#define configUSE_16_BIT_TICKS 0 //<2F><><EFBFBD><EFBFBD>portTickType
|
||||||
|
#define configIDLE_SHOULD_YIELD 1 //<2F><><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD>ʱ<EFBFBD><CAB1>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>
|
||||||
#define configUSE_HEAP3 0
|
#define configUSE_HEAP3 0
|
||||||
|
|
||||||
#define configQUEUE_REGISTRY_SIZE 0
|
#define configQUEUE_REGISTRY_SIZE 0
|
||||||
#define configSEMAPHORE_INIT_VALUE 5 //创建信号量的最大计数值
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configSEMAPHORE_INIT_VALUE 5 //<2F><><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0 //不使用合作轮转式程序
|
#define configUSE_CO_ROUTINES 0 //<EFBFBD><EFBFBD>ʹ<EFBFBD>ú<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>תʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) //合作式应用程序中可用的优先级数目
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽӦ<EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD><EFBFBD>п<EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><EFBFBD><EFBFBD>Ŀ
|
||||||
|
|
||||||
|
#define configUSE_TIMERS 1
|
||||||
|
#define configTIMER_TASK_PRIORITY 1
|
||||||
|
#define configTIMER_QUEUE_LENGTH 128
|
||||||
#define configTIMER_TASK_STACK_DEPTH 400
|
#define configTIMER_TASK_STACK_DEPTH 400
|
||||||
|
|
||||||
|
|
||||||
@ -104,11 +109,12 @@ to exclude the API function. */
|
|||||||
#define INCLUDE_vTaskSuspend 1
|
#define INCLUDE_vTaskSuspend 1
|
||||||
#define INCLUDE_vTaskDelayUntil 1
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
#define INCLUDE_vTaskDelay 1
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
|
||||||
#define configUSE_MUTEXES 1
|
#define configUSE_MUTEXES 1
|
||||||
#define configUSE_RECURSIVE_MUTEXES 1
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
|
||||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1 //可以获取当前任务
|
#define INCLUDE_xTaskGetCurrentTaskHandle 1 //<EFBFBD><EFBFBD><EFBFBD>Ի<EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef STACK_MACROS_H
|
#ifndef STACK_MACROS_H
|
||||||
@ -96,7 +108,7 @@
|
|||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName, pxCurrentTCB->uxPriority); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +124,7 @@
|
|||||||
/* Is the currently saved stack pointer within the stack limit? */ \
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,20 +133,20 @@
|
|||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
/* Has the extremity of the task stack ever been written over? */ \
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
@ -142,23 +154,23 @@
|
|||||||
|
|
||||||
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
{ \
|
{ \
|
||||||
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
|
int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||||
\
|
\
|
||||||
/* Has the extremity of the task stack ever been written over? */ \
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
{ \
|
{ \
|
||||||
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
|||||||
168
src/os/rtos/include/StackMacros.h.old
Normal file
168
src/os/rtos/include/StackMacros.h.old
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STACK_MACROS_H
|
||||||
|
#define STACK_MACROS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call the stack overflow hook function if the stack of the task being swapped
|
||||||
|
* out is currently overflowed, or looks like it might have overflowed in the
|
||||||
|
* past.
|
||||||
|
*
|
||||||
|
* Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
|
||||||
|
* the current stack state only - comparing the current top of stack value to
|
||||||
|
* the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
|
||||||
|
* will also cause the last few stack bytes to be checked to ensure the value
|
||||||
|
* to which the bytes were set when the task was created have not been
|
||||||
|
* overwritten. Note this second test does not guarantee that an overflowed
|
||||||
|
* stack will always be recognised.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configCHECK_FOR_STACK_OVERFLOW == 0 )
|
||||||
|
|
||||||
|
/* FreeRTOSConfig.h is not set to check for stack overflows. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 0 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( configCHECK_FOR_STACK_OVERFLOW == 1 )
|
||||||
|
|
||||||
|
/* FreeRTOSConfig.h is only set to use the first method of
|
||||||
|
overflow checking. */
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW()
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName, pxCurrentTCB->uxPriority); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW > 0 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 0 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
/* Only the current stack state is to be checked. */
|
||||||
|
#define taskFIRST_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
\
|
||||||
|
/* Is the currently saved stack pointer within the stack limit? */ \
|
||||||
|
if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
|
||||||
|
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
|
if( memcmp( ( void * ) pxCurrentTCB->pxStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
|
||||||
|
|
||||||
|
#define taskSECOND_CHECK_FOR_STACK_OVERFLOW() \
|
||||||
|
{ \
|
||||||
|
char *pcEndOfStack = ( char * ) pxCurrentTCB->pxEndOfStack; \
|
||||||
|
static const unsigned char ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \
|
||||||
|
tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
pcEndOfStack -= sizeof( ucExpectedStackBytes ); \
|
||||||
|
\
|
||||||
|
/* Has the extremity of the task stack ever been written over? */ \
|
||||||
|
if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \
|
||||||
|
{ \
|
||||||
|
vApplicationStackOverflowHook( ( xTaskHandle ) pxCurrentTCB, pxCurrentTCB->pcTaskName,pxCurrentTCB->uxPriority ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* STACK_MACROS_H */
|
||||||
|
|
||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CO_ROUTINE_H
|
#ifndef CO_ROUTINE_H
|
||||||
@ -58,7 +70,7 @@
|
|||||||
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "rtoslist.h"
|
#include "list.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -67,28 +79,28 @@ extern "C" {
|
|||||||
/* Used to hide the implementation of the co-routine control block. The
|
/* Used to hide the implementation of the co-routine control block. The
|
||||||
control block structure however has to be included in the header due to
|
control block structure however has to be included in the header due to
|
||||||
the macro implementation of the co-routine functionality. */
|
the macro implementation of the co-routine functionality. */
|
||||||
typedef void * xCoRoutineHandle;
|
typedef void * CoRoutineHandle_t;
|
||||||
|
|
||||||
/* Defines the prototype to which co-routine functions must conform. */
|
/* Defines the prototype to which co-routine functions must conform. */
|
||||||
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
|
typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t );
|
||||||
|
|
||||||
typedef struct corCoRoutineControlBlock
|
typedef struct corCoRoutineControlBlock
|
||||||
{
|
{
|
||||||
crCOROUTINE_CODE pxCoRoutineFunction;
|
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||||
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||||
xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
|
ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||||
unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||||
unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||||
unsigned short uxState; /*< Used internally by the co-routine implementation. */
|
uint16_t uxState; /*< Used internally by the co-routine implementation. */
|
||||||
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
|
} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
portBASE_TYPE xCoRoutineCreate(
|
BaseType_t xCoRoutineCreate(
|
||||||
crCOROUTINE_CODE pxCoRoutineCode,
|
crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
unsigned portBASE_TYPE uxPriority,
|
UBaseType_t uxPriority,
|
||||||
unsigned portBASE_TYPE uxIndex
|
UBaseType_t uxIndex
|
||||||
);</pre>
|
);</pre>
|
||||||
*
|
*
|
||||||
* Create a new co-routine and add it to the list of co-routines that are
|
* Create a new co-routine and add it to the list of co-routines that are
|
||||||
@ -111,12 +123,12 @@ typedef struct corCoRoutineControlBlock
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
// This may not be necessary for const variables.
|
// This may not be necessary for const variables.
|
||||||
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||||
static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
|
static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -126,7 +138,7 @@ typedef struct corCoRoutineControlBlock
|
|||||||
// This co-routine just delays for a fixed period, then toggles
|
// This co-routine just delays for a fixed period, then toggles
|
||||||
// an LED. Two co-routines are created using this function, so
|
// an LED. Two co-routines are created using this function, so
|
||||||
// the uxIndex parameter is used to tell the co-routine which
|
// the uxIndex parameter is used to tell the co-routine which
|
||||||
// LED to flash and how long to delay. This assumes xQueue has
|
// LED to flash and how int32_t to delay. This assumes xQueue has
|
||||||
// already been created.
|
// already been created.
|
||||||
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||||
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||||
@ -139,9 +151,9 @@ typedef struct corCoRoutineControlBlock
|
|||||||
// Function that creates two co-routines.
|
// Function that creates two co-routines.
|
||||||
void vOtherFunction( void )
|
void vOtherFunction( void )
|
||||||
{
|
{
|
||||||
unsigned char ucParameterToPass;
|
uint8_t ucParameterToPass;
|
||||||
xTaskHandle xHandle;
|
TaskHandle_t xHandle;
|
||||||
|
|
||||||
// Create two co-routines at priority 0. The first is given index 0
|
// Create two co-routines at priority 0. The first is given index 0
|
||||||
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||||
// is given index 1 so toggles LED 6 every 400 ticks.
|
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||||
@ -154,7 +166,7 @@ typedef struct corCoRoutineControlBlock
|
|||||||
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,17 +213,17 @@ void vCoRoutineSchedule( void );
|
|||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crSTART( xCoRoutineHandle xHandle );</pre>
|
crSTART( CoRoutineHandle_t xHandle );</pre>
|
||||||
*
|
*
|
||||||
* This macro MUST always be called at the start of a co-routine function.
|
* This macro MUST always be called at the start of a co-routine function.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static long ulAVariable;
|
static int32_t ulAVariable;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -227,7 +239,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* \defgroup crSTART crSTART
|
* \defgroup crSTART crSTART
|
||||||
* \ingroup Tasks
|
* \ingroup Tasks
|
||||||
*/
|
*/
|
||||||
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:
|
#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
@ -239,10 +251,10 @@ void vCoRoutineSchedule( void );
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static long ulAVariable;
|
static int32_t ulAVariable;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -264,13 +276,13 @@ void vCoRoutineSchedule( void );
|
|||||||
* These macros are intended for internal use by the co-routine implementation
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
* only. The macros should not be used directly by application writers.
|
* only. The macros should not be used directly by application writers.
|
||||||
*/
|
*/
|
||||||
#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||||
#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* croutine. h
|
* croutine. h
|
||||||
*<pre>
|
*<pre>
|
||||||
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
|
crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );</pre>
|
||||||
*
|
*
|
||||||
* Delay a co-routine for a fixed period of time.
|
* Delay a co-routine for a fixed period of time.
|
||||||
*
|
*
|
||||||
@ -283,18 +295,18 @@ void vCoRoutineSchedule( void );
|
|||||||
*
|
*
|
||||||
* @param xTickToDelay The number of ticks that the co-routine should delay
|
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||||
* for. The actual amount of time this equates to is defined by
|
* for. The actual amount of time this equates to is defined by
|
||||||
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
|
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS
|
||||||
* can be used to convert ticks to milliseconds.
|
* can be used to convert ticks to milliseconds.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// Co-routine to be created.
|
// Co-routine to be created.
|
||||||
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
// This may not be necessary for const variables.
|
// This may not be necessary for const variables.
|
||||||
// We are to delay for 200ms.
|
// We are to delay for 200ms.
|
||||||
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
|
static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
// Must start every co-routine with a call to crSTART();
|
// Must start every co-routine with a call to crSTART();
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -323,11 +335,11 @@ void vCoRoutineSchedule( void );
|
|||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND(
|
crQUEUE_SEND(
|
||||||
xCoRoutineHandle xHandle,
|
CoRoutineHandle_t xHandle,
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
void *pvItemToQueue,
|
||||||
portTickType xTicksToWait,
|
TickType_t xTicksToWait,
|
||||||
portBASE_TYPE *pxResult
|
BaseType_t *pxResult
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
@ -360,7 +372,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* to wait for space to become available on the queue, should space not be
|
* to wait for space to become available on the queue, should space not be
|
||||||
* available immediately. The actual amount of time this equates to is defined
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
|
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
|
||||||
* below).
|
* below).
|
||||||
*
|
*
|
||||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
@ -371,11 +383,11 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// Co-routine function that blocks for a fixed period then posts a number onto
|
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||||
// a queue.
|
// a queue.
|
||||||
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static portBASE_TYPE xNumberToPost = 0;
|
static BaseType_t xNumberToPost = 0;
|
||||||
static portBASE_TYPE xResult;
|
static BaseType_t xResult;
|
||||||
|
|
||||||
// Co-routines must begin with a call to crSTART().
|
// Co-routines must begin with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -422,11 +434,11 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_RECEIVE(
|
crQUEUE_RECEIVE(
|
||||||
xCoRoutineHandle xHandle,
|
CoRoutineHandle_t xHandle,
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
void *pvBuffer,
|
||||||
portTickType xTicksToWait,
|
TickType_t xTicksToWait,
|
||||||
portBASE_TYPE *pxResult
|
BaseType_t *pxResult
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
@ -458,7 +470,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* to wait for data to become available from the queue, should data not be
|
* to wait for data to become available from the queue, should data not be
|
||||||
* available immediately. The actual amount of time this equates to is defined
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
|
* portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
|
||||||
* crQUEUE_SEND example).
|
* crQUEUE_SEND example).
|
||||||
*
|
*
|
||||||
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
@ -469,11 +481,11 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// A co-routine receives the number of an LED to flash from a queue. It
|
// A co-routine receives the number of an LED to flash from a queue. It
|
||||||
// blocks on the queue until the number is received.
|
// blocks on the queue until the number is received.
|
||||||
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
static portBASE_TYPE xResult;
|
static BaseType_t xResult;
|
||||||
static unsigned portBASE_TYPE uxLEDToFlash;
|
static UBaseType_t uxLEDToFlash;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -514,9 +526,9 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
crQUEUE_SEND_FROM_ISR(
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvItemToQueue,
|
void *pvItemToQueue,
|
||||||
portBASE_TYPE xCoRoutinePreviouslyWoken
|
BaseType_t xCoRoutinePreviouslyWoken
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
@ -554,10 +566,10 @@ void vCoRoutineSchedule( void );
|
|||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
// A co-routine that blocks on a queue waiting for characters to be received.
|
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||||
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
char cRxedChar;
|
char cRxedChar;
|
||||||
portBASE_TYPE xResult;
|
BaseType_t xResult;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -584,7 +596,7 @@ void vCoRoutineSchedule( void );
|
|||||||
void vUART_ISR( void )
|
void vUART_ISR( void )
|
||||||
{
|
{
|
||||||
char cRxedChar;
|
char cRxedChar;
|
||||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
// We loop around reading characters until there are none left in the UART.
|
// We loop around reading characters until there are none left in the UART.
|
||||||
while( UART_RX_REG_NOT_EMPTY() )
|
while( UART_RX_REG_NOT_EMPTY() )
|
||||||
@ -611,9 +623,9 @@ void vCoRoutineSchedule( void );
|
|||||||
* croutine. h
|
* croutine. h
|
||||||
* <pre>
|
* <pre>
|
||||||
crQUEUE_SEND_FROM_ISR(
|
crQUEUE_SEND_FROM_ISR(
|
||||||
xQueueHandle pxQueue,
|
QueueHandle_t pxQueue,
|
||||||
void *pvBuffer,
|
void *pvBuffer,
|
||||||
portBASE_TYPE * pxCoRoutineWoken
|
BaseType_t * pxCoRoutineWoken
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
@ -652,12 +664,12 @@ void vCoRoutineSchedule( void );
|
|||||||
<pre>
|
<pre>
|
||||||
// A co-routine that posts a character to a queue then blocks for a fixed
|
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||||
// period. The character is incremented each time.
|
// period. The character is incremented each time.
|
||||||
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
// cChar holds its value while this co-routine is blocked and must therefore
|
// cChar holds its value while this co-routine is blocked and must therefore
|
||||||
// be declared static.
|
// be declared static.
|
||||||
static char cCharToTx = 'a';
|
static char cCharToTx = 'a';
|
||||||
portBASE_TYPE xResult;
|
BaseType_t xResult;
|
||||||
|
|
||||||
// All co-routines must start with a call to crSTART().
|
// All co-routines must start with a call to crSTART().
|
||||||
crSTART( xHandle );
|
crSTART( xHandle );
|
||||||
@ -700,7 +712,7 @@ void vCoRoutineSchedule( void );
|
|||||||
void vUART_ISR( void )
|
void vUART_ISR( void )
|
||||||
{
|
{
|
||||||
char cCharToTx;
|
char cCharToTx;
|
||||||
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
BaseType_t xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
while( UART_TX_REG_EMPTY() )
|
while( UART_TX_REG_EMPTY() )
|
||||||
{
|
{
|
||||||
@ -728,7 +740,7 @@ void vCoRoutineSchedule( void );
|
|||||||
* Removes the current co-routine from its ready list and places it in the
|
* Removes the current co-routine from its ready list and places it in the
|
||||||
* appropriate delayed list.
|
* appropriate delayed list.
|
||||||
*/
|
*/
|
||||||
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is intended for internal use by the queue implementation only.
|
* This function is intended for internal use by the queue implementation only.
|
||||||
@ -737,7 +749,7 @@ void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList
|
|||||||
* Removes the highest priority co-routine from the event list and places it in
|
* Removes the highest priority co-routine from the event list and places it in
|
||||||
* the pending ready list.
|
* the pending ready list.
|
||||||
*/
|
*/
|
||||||
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
746
src/os/rtos/include/croutine.h.old
Normal file
746
src/os/rtos/include/croutine.h.old
Normal file
@ -0,0 +1,746 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CO_ROUTINE_H
|
||||||
|
#define CO_ROUTINE_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include croutine.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rtoslist.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Used to hide the implementation of the co-routine control block. The
|
||||||
|
control block structure however has to be included in the header due to
|
||||||
|
the macro implementation of the co-routine functionality. */
|
||||||
|
typedef void * xCoRoutineHandle;
|
||||||
|
|
||||||
|
/* Defines the prototype to which co-routine functions must conform. */
|
||||||
|
typedef void (*crCOROUTINE_CODE)( xCoRoutineHandle, unsigned portBASE_TYPE );
|
||||||
|
|
||||||
|
typedef struct corCoRoutineControlBlock
|
||||||
|
{
|
||||||
|
crCOROUTINE_CODE pxCoRoutineFunction;
|
||||||
|
xListItem xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */
|
||||||
|
xListItem xEventListItem; /*< List item used to place the CRCB in event lists. */
|
||||||
|
unsigned portBASE_TYPE uxPriority; /*< The priority of the co-routine in relation to other co-routines. */
|
||||||
|
unsigned portBASE_TYPE uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
|
||||||
|
unsigned short uxState; /*< Used internally by the co-routine implementation. */
|
||||||
|
} corCRCB; /* Co-routine control block. Note must be identical in size down to uxPriority with tskTCB. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
portBASE_TYPE xCoRoutineCreate(
|
||||||
|
crCOROUTINE_CODE pxCoRoutineCode,
|
||||||
|
unsigned portBASE_TYPE uxPriority,
|
||||||
|
unsigned portBASE_TYPE uxIndex
|
||||||
|
);</pre>
|
||||||
|
*
|
||||||
|
* Create a new co-routine and add it to the list of co-routines that are
|
||||||
|
* ready to run.
|
||||||
|
*
|
||||||
|
* @param pxCoRoutineCode Pointer to the co-routine function. Co-routine
|
||||||
|
* functions require special syntax - see the co-routine section of the WEB
|
||||||
|
* documentation for more information.
|
||||||
|
*
|
||||||
|
* @param uxPriority The priority with respect to other co-routines at which
|
||||||
|
* the co-routine will run.
|
||||||
|
*
|
||||||
|
* @param uxIndex Used to distinguish between different co-routines that
|
||||||
|
* execute the same function. See the example below and the co-routine section
|
||||||
|
* of the WEB documentation for further information.
|
||||||
|
*
|
||||||
|
* @return pdPASS if the co-routine was successfully created and added to a ready
|
||||||
|
* list, otherwise an error code defined with ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vFlashCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
// This may not be necessary for const variables.
|
||||||
|
static const char cLedToFlash[ 2 ] = { 5, 6 };
|
||||||
|
static const portTickType uxFlashRates[ 2 ] = { 200, 400 };
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// This co-routine just delays for a fixed period, then toggles
|
||||||
|
// an LED. Two co-routines are created using this function, so
|
||||||
|
// the uxIndex parameter is used to tell the co-routine which
|
||||||
|
// LED to flash and how long to delay. This assumes xQueue has
|
||||||
|
// already been created.
|
||||||
|
vParTestToggleLED( cLedToFlash[ uxIndex ] );
|
||||||
|
crDELAY( xHandle, uxFlashRates[ uxIndex ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function that creates two co-routines.
|
||||||
|
void vOtherFunction( void )
|
||||||
|
{
|
||||||
|
unsigned char ucParameterToPass;
|
||||||
|
xTaskHandle xHandle;
|
||||||
|
|
||||||
|
// Create two co-routines at priority 0. The first is given index 0
|
||||||
|
// so (from the code above) toggles LED 5 every 200 ticks. The second
|
||||||
|
// is given index 1 so toggles LED 6 every 400 ticks.
|
||||||
|
for( uxIndex = 0; uxIndex < 2; uxIndex++ )
|
||||||
|
{
|
||||||
|
xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xCoRoutineCreate xCoRoutineCreate
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
void vCoRoutineSchedule( void );</pre>
|
||||||
|
*
|
||||||
|
* Run a co-routine.
|
||||||
|
*
|
||||||
|
* vCoRoutineSchedule() executes the highest priority co-routine that is able
|
||||||
|
* to run. The co-routine will execute until it either blocks, yields or is
|
||||||
|
* preempted by a task. Co-routines execute cooperatively so one
|
||||||
|
* co-routine cannot be preempted by another, but can be preempted by a task.
|
||||||
|
*
|
||||||
|
* If an application comprises of both tasks and co-routines then
|
||||||
|
* vCoRoutineSchedule should be called from the idle task (in an idle task
|
||||||
|
* hook).
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// This idle task hook will schedule a co-routine each time it is called.
|
||||||
|
// The rest of the idle task will execute between co-routine calls.
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
vCoRoutineSchedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternatively, if you do not require any other part of the idle task to
|
||||||
|
// execute, the idle task hook can call vCoRoutineScheduler() within an
|
||||||
|
// infinite loop.
|
||||||
|
void vApplicationIdleHook( void )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
vCoRoutineSchedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vCoRoutineSchedule vCoRoutineSchedule
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
void vCoRoutineSchedule( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crSTART( xCoRoutineHandle xHandle );</pre>
|
||||||
|
*
|
||||||
|
* This macro MUST always be called at the start of a co-routine function.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static long ulAVariable;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Co-routine functionality goes here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crSTART crSTART
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crSTART( pxCRCB ) switch( ( ( corCRCB * )( pxCRCB ) )->uxState ) { case 0:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crEND();</pre>
|
||||||
|
*
|
||||||
|
* This macro MUST always be called at the end of a co-routine function.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static long ulAVariable;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Co-routine functionality goes here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crSTART crSTART
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crEND() }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These macros are intended for internal use by the co-routine implementation
|
||||||
|
* only. The macros should not be used directly by application writers.
|
||||||
|
*/
|
||||||
|
#define crSET_STATE0( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2):
|
||||||
|
#define crSET_STATE1( xHandle ) ( ( corCRCB * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1):
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
*<pre>
|
||||||
|
crDELAY( xCoRoutineHandle xHandle, portTickType xTicksToDelay );</pre>
|
||||||
|
*
|
||||||
|
* Delay a co-routine for a fixed period of time.
|
||||||
|
*
|
||||||
|
* crDELAY can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the co-routine to delay. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should delay
|
||||||
|
* for. The actual amount of time this equates to is defined by
|
||||||
|
* configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_RATE_MS
|
||||||
|
* can be used to convert ticks to milliseconds.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine to be created.
|
||||||
|
void vACoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
// This may not be necessary for const variables.
|
||||||
|
// We are to delay for 200ms.
|
||||||
|
static const xTickType xDelayTime = 200 / portTICK_RATE_MS;
|
||||||
|
|
||||||
|
// Must start every co-routine with a call to crSTART();
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Delay for 200ms.
|
||||||
|
crDELAY( xHandle, xDelayTime );
|
||||||
|
|
||||||
|
// Do something here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must end every co-routine with a call to crEND();
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crDELAY crDELAY
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crDELAY( xHandle, xTicksToDelay ) \
|
||||||
|
if( ( xTicksToDelay ) > 0 ) \
|
||||||
|
{ \
|
||||||
|
vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
|
||||||
|
} \
|
||||||
|
crSET_STATE0( ( xHandle ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND(
|
||||||
|
xCoRoutineHandle xHandle,
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvItemToQueue,
|
||||||
|
portTickType xTicksToWait,
|
||||||
|
portBASE_TYPE *pxResult
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||||
|
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param pxQueue The handle of the queue on which the data will be posted.
|
||||||
|
* The handle is obtained as the return value when the queue is created using
|
||||||
|
* the xQueueCreate() API function.
|
||||||
|
*
|
||||||
|
* @param pvItemToQueue A pointer to the data being posted onto the queue.
|
||||||
|
* The number of bytes of each queued item is specified when the queue is
|
||||||
|
* created. This number of bytes is copied from pvItemToQueue into the queue
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||||
|
* to wait for space to become available on the queue, should space not be
|
||||||
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
|
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see example
|
||||||
|
* below).
|
||||||
|
*
|
||||||
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
|
* data was successfully posted onto the queue, otherwise it will be set to an
|
||||||
|
* error defined within ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Co-routine function that blocks for a fixed period then posts a number onto
|
||||||
|
// a queue.
|
||||||
|
static void prvCoRoutineFlashTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static portBASE_TYPE xNumberToPost = 0;
|
||||||
|
static portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// Co-routines must begin with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// This assumes the queue has already been created.
|
||||||
|
crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult != pdPASS )
|
||||||
|
{
|
||||||
|
// The message was not posted!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the number to be posted onto the queue.
|
||||||
|
xNumberToPost++;
|
||||||
|
|
||||||
|
// Delay for 100 ticks.
|
||||||
|
crDELAY( xHandle, 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_SEND crQUEUE_SEND
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \
|
||||||
|
{ \
|
||||||
|
*( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \
|
||||||
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
|
*pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \
|
||||||
|
} \
|
||||||
|
if( *pxResult == errQUEUE_YIELD ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
|
*pxResult = pdPASS; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_RECEIVE(
|
||||||
|
xCoRoutineHandle xHandle,
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvBuffer,
|
||||||
|
portTickType xTicksToWait,
|
||||||
|
portBASE_TYPE *pxResult
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
|
||||||
|
* equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
|
||||||
|
* xQueueSend() and xQueueReceive() can only be used from tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_RECEIVE can only be called from the co-routine function itself - not
|
||||||
|
* from within a function called by the co-routine function. This is because
|
||||||
|
* co-routines do not maintain their own stack.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xHandle The handle of the calling co-routine. This is the xHandle
|
||||||
|
* parameter of the co-routine function.
|
||||||
|
*
|
||||||
|
* @param pxQueue The handle of the queue from which the data will be received.
|
||||||
|
* The handle is obtained as the return value when the queue is created using
|
||||||
|
* the xQueueCreate() API function.
|
||||||
|
*
|
||||||
|
* @param pvBuffer The buffer into which the received item is to be copied.
|
||||||
|
* The number of bytes of each queued item is specified when the queue is
|
||||||
|
* created. This number of bytes is copied into pvBuffer.
|
||||||
|
*
|
||||||
|
* @param xTickToDelay The number of ticks that the co-routine should block
|
||||||
|
* to wait for data to become available from the queue, should data not be
|
||||||
|
* available immediately. The actual amount of time this equates to is defined
|
||||||
|
* by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant
|
||||||
|
* portTICK_RATE_MS can be used to convert ticks to milliseconds (see the
|
||||||
|
* crQUEUE_SEND example).
|
||||||
|
*
|
||||||
|
* @param pxResult The variable pointed to by pxResult will be set to pdPASS if
|
||||||
|
* data was successfully retrieved from the queue, otherwise it will be set to
|
||||||
|
* an error code as defined within ProjDefs.h.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine receives the number of an LED to flash from a queue. It
|
||||||
|
// blocks on the queue until the number is received.
|
||||||
|
static void prvCoRoutineFlashWorkTask( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// Variables in co-routines must be declared static if they must maintain value across a blocking call.
|
||||||
|
static portBASE_TYPE xResult;
|
||||||
|
static unsigned portBASE_TYPE uxLEDToFlash;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Wait for data to become available on the queue.
|
||||||
|
crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// We received the LED to flash - flash it!
|
||||||
|
vParTestToggleLED( uxLEDToFlash );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crEND();
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \
|
||||||
|
{ \
|
||||||
|
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \
|
||||||
|
if( *( pxResult ) == errQUEUE_BLOCKED ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE0( ( xHandle ) ); \
|
||||||
|
*( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \
|
||||||
|
} \
|
||||||
|
if( *( pxResult ) == errQUEUE_YIELD ) \
|
||||||
|
{ \
|
||||||
|
crSET_STATE1( ( xHandle ) ); \
|
||||||
|
*( pxResult ) = pdPASS; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND_FROM_ISR(
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvItemToQueue,
|
||||||
|
portBASE_TYPE xCoRoutinePreviouslyWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
* functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||||
|
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||||
|
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||||
|
* ISR.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
|
||||||
|
* that is being used from within a co-routine.
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||||
|
*
|
||||||
|
* @param pvItemToQueue A pointer to the item that is to be placed on the
|
||||||
|
* queue. The size of the items the queue will hold was defined when the
|
||||||
|
* queue was created, so this many bytes will be copied from pvItemToQueue
|
||||||
|
* into the queue storage area.
|
||||||
|
*
|
||||||
|
* @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
|
||||||
|
* the same queue multiple times from a single interrupt. The first call
|
||||||
|
* should always pass in pdFALSE. Subsequent calls should pass in
|
||||||
|
* the value returned from the previous call.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if a co-routine was woken by posting onto the queue. This is
|
||||||
|
* used by the ISR to determine if a context switch may be required following
|
||||||
|
* the ISR.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine that blocks on a queue waiting for characters to be received.
|
||||||
|
static void vReceivingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
char cRxedChar;
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Wait for data to become available on the queue. This assumes the
|
||||||
|
// queue xCommsRxQueue has already been created!
|
||||||
|
crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
|
||||||
|
|
||||||
|
// Was a character received?
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// Process the character here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ISR that uses a queue to send characters received on a serial port to
|
||||||
|
// a co-routine.
|
||||||
|
void vUART_ISR( void )
|
||||||
|
{
|
||||||
|
char cRxedChar;
|
||||||
|
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
|
// We loop around reading characters until there are none left in the UART.
|
||||||
|
while( UART_RX_REG_NOT_EMPTY() )
|
||||||
|
{
|
||||||
|
// Obtain the character from the UART.
|
||||||
|
cRxedChar = UART_RX_REG;
|
||||||
|
|
||||||
|
// Post the character onto a queue. xCRWokenByPost will be pdFALSE
|
||||||
|
// the first time around the loop. If the post causes a co-routine
|
||||||
|
// to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
|
||||||
|
// In this manner we can ensure that if more than one co-routine is
|
||||||
|
// blocked on the queue only one is woken by this ISR no matter how
|
||||||
|
// many characters are posted to the queue.
|
||||||
|
xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
|
||||||
|
}
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* croutine. h
|
||||||
|
* <pre>
|
||||||
|
crQUEUE_SEND_FROM_ISR(
|
||||||
|
xQueueHandle pxQueue,
|
||||||
|
void *pvBuffer,
|
||||||
|
portBASE_TYPE * pxCoRoutineWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
|
||||||
|
* co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
|
||||||
|
* functions used by tasks.
|
||||||
|
*
|
||||||
|
* crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
|
||||||
|
* pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
|
||||||
|
* xQueueReceiveFromISR() can only be used to pass data between a task and and
|
||||||
|
* ISR.
|
||||||
|
*
|
||||||
|
* crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
|
||||||
|
* from a queue that is being used from within a co-routine (a co-routine
|
||||||
|
* posted to the queue).
|
||||||
|
*
|
||||||
|
* See the co-routine section of the WEB documentation for information on
|
||||||
|
* passing data between tasks and co-routines and between ISR's and
|
||||||
|
* co-routines.
|
||||||
|
*
|
||||||
|
* @param xQueue The handle to the queue on which the item is to be posted.
|
||||||
|
*
|
||||||
|
* @param pvBuffer A pointer to a buffer into which the received item will be
|
||||||
|
* placed. The size of the items the queue will hold was defined when the
|
||||||
|
* queue was created, so this many bytes will be copied from the queue into
|
||||||
|
* pvBuffer.
|
||||||
|
*
|
||||||
|
* @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
|
||||||
|
* available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a
|
||||||
|
* co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
|
||||||
|
* *pxCoRoutineWoken will remain unchanged.
|
||||||
|
*
|
||||||
|
* @return pdTRUE an item was successfully received from the queue, otherwise
|
||||||
|
* pdFALSE.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// A co-routine that posts a character to a queue then blocks for a fixed
|
||||||
|
// period. The character is incremented each time.
|
||||||
|
static void vSendingCoRoutine( xCoRoutineHandle xHandle, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
// cChar holds its value while this co-routine is blocked and must therefore
|
||||||
|
// be declared static.
|
||||||
|
static char cCharToTx = 'a';
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
// All co-routines must start with a call to crSTART().
|
||||||
|
crSTART( xHandle );
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Send the next character to the queue.
|
||||||
|
crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
|
||||||
|
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// The character was successfully posted to the queue.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Could not post the character to the queue.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the UART Tx interrupt to cause an interrupt in this
|
||||||
|
// hypothetical UART. The interrupt will obtain the character
|
||||||
|
// from the queue and send it.
|
||||||
|
ENABLE_RX_INTERRUPT();
|
||||||
|
|
||||||
|
// Increment to the next character then block for a fixed period.
|
||||||
|
// cCharToTx will maintain its value across the delay as it is
|
||||||
|
// declared static.
|
||||||
|
cCharToTx++;
|
||||||
|
if( cCharToTx > 'x' )
|
||||||
|
{
|
||||||
|
cCharToTx = 'a';
|
||||||
|
}
|
||||||
|
crDELAY( 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// All co-routines must end with a call to crEND().
|
||||||
|
crEND();
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ISR that uses a queue to receive characters to send on a UART.
|
||||||
|
void vUART_ISR( void )
|
||||||
|
{
|
||||||
|
char cCharToTx;
|
||||||
|
portBASE_TYPE xCRWokenByPost = pdFALSE;
|
||||||
|
|
||||||
|
while( UART_TX_REG_EMPTY() )
|
||||||
|
{
|
||||||
|
// Are there any characters in the queue waiting to be sent?
|
||||||
|
// xCRWokenByPost will automatically be set to pdTRUE if a co-routine
|
||||||
|
// is woken by the post - ensuring that only a single co-routine is
|
||||||
|
// woken no matter how many times we go around this loop.
|
||||||
|
if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
|
||||||
|
{
|
||||||
|
SEND_CHARACTER( cCharToTx );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}</pre>
|
||||||
|
* \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
|
||||||
|
* \ingroup Tasks
|
||||||
|
*/
|
||||||
|
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended for internal use by the co-routine macros only.
|
||||||
|
* The macro nature of the co-routine implementation requires that the
|
||||||
|
* prototype appears here. The function should not be used by application
|
||||||
|
* writers.
|
||||||
|
*
|
||||||
|
* Removes the current co-routine from its ready list and places it in the
|
||||||
|
* appropriate delayed list.
|
||||||
|
*/
|
||||||
|
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is intended for internal use by the queue implementation only.
|
||||||
|
* The function should not be used by application writers.
|
||||||
|
*
|
||||||
|
* Removes the highest priority co-routine from the event list and places it in
|
||||||
|
* the pending ready list.
|
||||||
|
*/
|
||||||
|
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CO_ROUTINE_H */
|
||||||
680
src/os/rtos/include/event_groups.h
Normal file
680
src/os/rtos/include/event_groups.h
Normal file
@ -0,0 +1,680 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
|
>>! kernel.
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EVENT_GROUPS_H
|
||||||
|
#define EVENT_GROUPS_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rtostimers.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event group is a collection of bits to which an application can assign a
|
||||||
|
* meaning. For example, an application may create an event group to convey
|
||||||
|
* the status of various CAN bus related events in which bit 0 might mean "A CAN
|
||||||
|
* message has been received and is ready for processing", bit 1 might mean "The
|
||||||
|
* application has queued a message that is ready for sending onto the CAN
|
||||||
|
* network", and bit 2 might mean "It is time to send a SYNC message onto the
|
||||||
|
* CAN network" etc. A task can then test the bit values to see which events
|
||||||
|
* are active, and optionally enter the Blocked state to wait for a specified
|
||||||
|
* bit or a group of specified bits to be active. To continue the CAN bus
|
||||||
|
* example, a CAN controlling task can enter the Blocked state (and therefore
|
||||||
|
* not consume any processing time) until either bit 0, bit 1 or bit 2 are
|
||||||
|
* active, at which time the bit that was actually active would inform the task
|
||||||
|
* which action it had to take (process a received message, send a message, or
|
||||||
|
* send a SYNC).
|
||||||
|
*
|
||||||
|
* The event groups implementation contains intelligence to avoid race
|
||||||
|
* conditions that would otherwise occur were an application to use a simple
|
||||||
|
* variable for the same purpose. This is particularly important with respect
|
||||||
|
* to when a bit within an event group is to be cleared, and when bits have to
|
||||||
|
* be set and then tested atomically - as is the case where event groups are
|
||||||
|
* used to create a synchronisation point between multiple tasks (a
|
||||||
|
* 'rendezvous').
|
||||||
|
*
|
||||||
|
* \defgroup EventGroup
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*
|
||||||
|
* Type by which event groups are referenced. For example, a call to
|
||||||
|
* xEventGroupCreate() returns an EventGroupHandle_t variable that can then
|
||||||
|
* be used as a parameter to other event group functions.
|
||||||
|
*
|
||||||
|
* \defgroup EventGroupHandle_t EventGroupHandle_t
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
typedef void * EventGroupHandle_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The type that holds event bits always matches TickType_t - therefore the
|
||||||
|
* number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1,
|
||||||
|
* 32 bits if set to 0.
|
||||||
|
*
|
||||||
|
* \defgroup EventBits_t EventBits_t
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
typedef TickType_t EventBits_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Create a new event group. This function cannot be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Although event groups are not related to ticks, for internal implementation
|
||||||
|
* reasons the number of bits available for use in an event group is dependent
|
||||||
|
* on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If
|
||||||
|
* configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit
|
||||||
|
* 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has
|
||||||
|
* 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store
|
||||||
|
* event bits within an event group.
|
||||||
|
*
|
||||||
|
* @return If the event group was created then a handle to the event group is
|
||||||
|
* returned. If there was insufficient FreeRTOS heap available to create the
|
||||||
|
* event group then NULL is returned. See http://www.freertos.org/a00111.html
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Declare a variable to hold the created event group.
|
||||||
|
EventGroupHandle_t xCreatedEventGroup;
|
||||||
|
|
||||||
|
// Attempt to create the event group.
|
||||||
|
xCreatedEventGroup = xEventGroupCreate();
|
||||||
|
|
||||||
|
// Was the event group created successfully?
|
||||||
|
if( xCreatedEventGroup == NULL )
|
||||||
|
{
|
||||||
|
// The event group was not created because there was insufficient
|
||||||
|
// FreeRTOS heap available.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The event group was created.
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupCreate xEventGroupCreate
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
const BaseType_t xClearOnExit,
|
||||||
|
const BaseType_t xWaitForAllBits,
|
||||||
|
const TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* [Potentially] block to wait for one or more bits to be set within a
|
||||||
|
* previously created event group.
|
||||||
|
*
|
||||||
|
* This function cannot be called from an interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are being tested. The
|
||||||
|
* event group must have previously been created using a call to
|
||||||
|
* xEventGroupCreate().
|
||||||
|
*
|
||||||
|
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group. For example, to wait for bit 0 and/or bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x07. Etc.
|
||||||
|
*
|
||||||
|
* @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
|
||||||
|
* uxBitsToWaitFor that are set within the event group will be cleared before
|
||||||
|
* xEventGroupWaitBits() returns if the wait condition was met (if the function
|
||||||
|
* returns for a reason other than a timeout). If xClearOnExit is set to
|
||||||
|
* pdFALSE then the bits set in the event group are not altered when the call to
|
||||||
|
* xEventGroupWaitBits() returns.
|
||||||
|
*
|
||||||
|
* @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
|
||||||
|
* xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
|
||||||
|
* are set or the specified block time expires. If xWaitForAllBits is set to
|
||||||
|
* pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
|
||||||
|
* in uxBitsToWaitFor is set or the specified block time expires. The block
|
||||||
|
* time is specified by the xTicksToWait parameter.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||||
|
* for one/all (depending on the xWaitForAllBits value) of the bits specified by
|
||||||
|
* uxBitsToWaitFor to become set.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time either the bits being waited
|
||||||
|
* for became set, or the block time expired. Test the return value to know
|
||||||
|
* which bits were set. If xEventGroupWaitBits() returned because its timeout
|
||||||
|
* expired then not all the bits being waited for will be set. If
|
||||||
|
* xEventGroupWaitBits() returned because the bits it was waiting for were set
|
||||||
|
* then the returned value is the event group value before any bits were
|
||||||
|
* automatically cleared in the case that xClearOnExit parameter was set to
|
||||||
|
* pdTRUE.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
|
||||||
|
// the event group. Clear the bits before exiting.
|
||||||
|
uxBits = xEventGroupWaitBits(
|
||||||
|
xEventGroup, // The event group being tested.
|
||||||
|
BIT_0 | BIT_4, // The bits within the event group to wait for.
|
||||||
|
pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
|
||||||
|
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||||
|
xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because both bits were set.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because just BIT_0 was set.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because just BIT_4 was set.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// xEventGroupWaitBits() returned because xTicksToWait ticks passed
|
||||||
|
// without either BIT_0 or BIT_4 becoming set.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupWaitBits xEventGroupWaitBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Clear bits within an event group. This function cannot be called from an
|
||||||
|
* interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be cleared.
|
||||||
|
*
|
||||||
|
* @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
|
||||||
|
* in the event group. For example, to clear bit 3 only, set uxBitsToClear to
|
||||||
|
* 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
|
||||||
|
*
|
||||||
|
* @return The value of the event group before the specified bits were cleared.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
|
||||||
|
// Clear bit 0 and bit 4 in xEventGroup.
|
||||||
|
uxBits = xEventGroupClearBits(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 );// The bits being cleared.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
|
||||||
|
// called. Both will now be clear (not set).
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 0 was set before xEventGroupClearBits() was called. It will
|
||||||
|
// now be clear.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 4 was set before xEventGroupClearBits() was called. It will
|
||||||
|
// now be clear.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Neither bit 0 nor bit 4 were set in the first place.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupClearBits xEventGroupClearBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupClearBits() that can be called from an interrupt
|
||||||
|
* service routine. See the xEventGroupClearBits() documentation.
|
||||||
|
*
|
||||||
|
* \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Set bits within an event group.
|
||||||
|
* This function cannot be called from an interrupt. xEventGroupSetBitsFromISR()
|
||||||
|
* is a version that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group will automatically unblock tasks that are
|
||||||
|
* blocked waiting for the bits.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||||
|
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||||
|
* and bit 0 set uxBitsToSet to 0x09.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time the call to
|
||||||
|
* xEventGroupSetBits() returns. There are two reasons why the returned value
|
||||||
|
* might have the bits specified by the uxBitsToSet parameter cleared. First,
|
||||||
|
* if setting a bit results in a task that was waiting for the bit leaving the
|
||||||
|
* blocked state then it is possible the bit will be cleared automatically
|
||||||
|
* (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any
|
||||||
|
* unblocked (or otherwise Ready state) task that has a priority above that of
|
||||||
|
* the task that called xEventGroupSetBits() will execute and may change the
|
||||||
|
* event group value before the call to xEventGroupSetBits() returns.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
void aFunction( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventBits_t uxBits;
|
||||||
|
|
||||||
|
// Set bit 0 and bit 4 in xEventGroup.
|
||||||
|
uxBits = xEventGroupSetBits(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 );// The bits being set.
|
||||||
|
|
||||||
|
if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
|
||||||
|
{
|
||||||
|
// Both bit 0 and bit 4 remained set when the function returned.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_0 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 0 remained set when the function returned, but bit 4 was
|
||||||
|
// cleared. It might be that bit 4 was cleared automatically as a
|
||||||
|
// task that was waiting for bit 4 was removed from the Blocked
|
||||||
|
// state.
|
||||||
|
}
|
||||||
|
else if( ( uxBits & BIT_4 ) != 0 )
|
||||||
|
{
|
||||||
|
// Bit 4 remained set when the function returned, but bit 0 was
|
||||||
|
// cleared. It might be that bit 0 was cleared automatically as a
|
||||||
|
// task that was waiting for bit 0 was removed from the Blocked
|
||||||
|
// state.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Neither bit 0 nor bit 4 remained set. It might be that a task
|
||||||
|
// was waiting for both of the bits to be set, and the bits were
|
||||||
|
// cleared as the task left the Blocked state.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSetBits xEventGroupSetBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupSetBits() that can be called from an interrupt.
|
||||||
|
*
|
||||||
|
* Setting bits in an event group is not a deterministic operation because there
|
||||||
|
* are an unknown number of tasks that may be waiting for the bit or bits being
|
||||||
|
* set. FreeRTOS does not allow nondeterministic operations to be performed in
|
||||||
|
* interrupts or from critical sections. Therefore xEventGroupSetBitFromISR()
|
||||||
|
* sends a message to the timer task to have the set operation performed in the
|
||||||
|
* context of the timer task - where a scheduler lock is used in place of a
|
||||||
|
* critical section.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are to be set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
|
||||||
|
* For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3
|
||||||
|
* and bit 0 set uxBitsToSet to 0x09.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||||
|
* will result in a message being sent to the timer daemon task. If the
|
||||||
|
* priority of the timer daemon task is higher than the priority of the
|
||||||
|
* currently running task (the task the interrupt interrupted) then
|
||||||
|
* *pxHigherPriorityTaskWoken will be set to pdTRUE by
|
||||||
|
* xEventGroupSetBitsFromISR(), indicating that a context switch should be
|
||||||
|
* requested before the interrupt exits. For that reason
|
||||||
|
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||||
|
* example code below.
|
||||||
|
*
|
||||||
|
* @return If the request to execute the function was posted successfully then
|
||||||
|
* pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned
|
||||||
|
* if the timer service queue was full.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
#define BIT_0 ( 1 << 0 )
|
||||||
|
#define BIT_4 ( 1 << 4 )
|
||||||
|
|
||||||
|
// An event group which it is assumed has already been created by a call to
|
||||||
|
// xEventGroupCreate().
|
||||||
|
EventGroupHandle_t xEventGroup;
|
||||||
|
|
||||||
|
void anInterruptHandler( void )
|
||||||
|
{
|
||||||
|
BaseType_t xHigherPriorityTaskWoken, xResult;
|
||||||
|
|
||||||
|
// xHigherPriorityTaskWoken must be initialised to pdFALSE.
|
||||||
|
xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
|
||||||
|
// Set bit 0 and bit 4 in xEventGroup.
|
||||||
|
xResult = xEventGroupSetBitsFromISR(
|
||||||
|
xEventGroup, // The event group being updated.
|
||||||
|
BIT_0 | BIT_4 // The bits being set.
|
||||||
|
&xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
// Was the message posted successfully?
|
||||||
|
if( xResult == pdPASS )
|
||||||
|
{
|
||||||
|
// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
// switch should be requested. The macro used is port specific and
|
||||||
|
// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
|
||||||
|
// refer to the documentation page for the port being used.
|
||||||
|
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
#else
|
||||||
|
#define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
||||||
|
const EventBits_t uxBitsToSet,
|
||||||
|
const EventBits_t uxBitsToWaitFor,
|
||||||
|
TickType_t xTicksToWait );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Atomically set bits within an event group, then wait for a combination of
|
||||||
|
* bits to be set within the same event group. This functionality is typically
|
||||||
|
* used to synchronise multiple tasks, where each task has to wait for the other
|
||||||
|
* tasks to reach a synchronisation point before proceeding.
|
||||||
|
*
|
||||||
|
* This function cannot be used from an interrupt.
|
||||||
|
*
|
||||||
|
* The function will return before its block time expires if the bits specified
|
||||||
|
* by the uxBitsToWait parameter are set, or become set within that time. In
|
||||||
|
* this case all the bits specified by uxBitsToWait will be automatically
|
||||||
|
* cleared before the function returns.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group in which the bits are being tested. The
|
||||||
|
* event group must have previously been created using a call to
|
||||||
|
* xEventGroupCreate().
|
||||||
|
*
|
||||||
|
* @param uxBitsToSet The bits to set in the event group before determining
|
||||||
|
* if, and possibly waiting for, all the bits specified by the uxBitsToWait
|
||||||
|
* parameter are set.
|
||||||
|
*
|
||||||
|
* @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
|
||||||
|
* inside the event group. For example, to wait for bit 0 and bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set
|
||||||
|
* uxBitsToWaitFor to 0x07. Etc.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
|
||||||
|
* for all of the bits specified by uxBitsToWaitFor to become set.
|
||||||
|
*
|
||||||
|
* @return The value of the event group at the time either the bits being waited
|
||||||
|
* for became set, or the block time expired. Test the return value to know
|
||||||
|
* which bits were set. If xEventGroupSync() returned because its timeout
|
||||||
|
* expired then not all the bits being waited for will be set. If
|
||||||
|
* xEventGroupSync() returned because all the bits it was waiting for were
|
||||||
|
* set then the returned value is the event group value before any bits were
|
||||||
|
* automatically cleared.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
// Bits used by the three tasks.
|
||||||
|
#define TASK_0_BIT ( 1 << 0 )
|
||||||
|
#define TASK_1_BIT ( 1 << 1 )
|
||||||
|
#define TASK_2_BIT ( 1 << 2 )
|
||||||
|
|
||||||
|
#define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
|
||||||
|
|
||||||
|
// Use an event group to synchronise three tasks. It is assumed this event
|
||||||
|
// group has already been created elsewhere.
|
||||||
|
EventGroupHandle_t xEventBits;
|
||||||
|
|
||||||
|
void vTask0( void *pvParameters )
|
||||||
|
{
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 0 in the event flag to note this task has reached the
|
||||||
|
// sync point. The other two tasks will set the other two bits defined
|
||||||
|
// by ALL_SYNC_BITS. All three tasks have reached the synchronisation
|
||||||
|
// point when all the ALL_SYNC_BITS are set. Wait a maximum of 100ms
|
||||||
|
// for this to happen.
|
||||||
|
uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
|
||||||
|
|
||||||
|
if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
|
||||||
|
{
|
||||||
|
// All three tasks reached the synchronisation point before the call
|
||||||
|
// to xEventGroupSync() timed out.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTask1( void *pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 1 in the event flag to note this task has reached the
|
||||||
|
// synchronisation point. The other two tasks will set the other two
|
||||||
|
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
|
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
|
// indefinitely for this to happen.
|
||||||
|
xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
|
||||||
|
// xEventGroupSync() was called with an indefinite block time, so
|
||||||
|
// this task will only reach here if the syncrhonisation was made by all
|
||||||
|
// three tasks, so there is no need to test the return value.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vTask2( void *pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// Perform task functionality here.
|
||||||
|
|
||||||
|
// Set bit 2 in the event flag to note this task has reached the
|
||||||
|
// synchronisation point. The other two tasks will set the other two
|
||||||
|
// bits defined by ALL_SYNC_BITS. All three tasks have reached the
|
||||||
|
// synchronisation point when all the ALL_SYNC_BITS are set. Wait
|
||||||
|
// indefinitely for this to happen.
|
||||||
|
xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
|
||||||
|
|
||||||
|
// xEventGroupSync() was called with an indefinite block time, so
|
||||||
|
// this task will only reach here if the syncrhonisation was made by all
|
||||||
|
// three tasks, so there is no need to test the return value.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
* \defgroup xEventGroupSync xEventGroupSync
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Returns the current value of the bits in an event group. This function
|
||||||
|
* cannot be used from an interrupt.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being queried.
|
||||||
|
*
|
||||||
|
* @return The event group bits at the time xEventGroupGetBits() was called.
|
||||||
|
*
|
||||||
|
* \defgroup xEventGroupGetBits xEventGroupGetBits
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* A version of xEventGroupGetBits() that can be called from an ISR.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being queried.
|
||||||
|
*
|
||||||
|
* @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
|
||||||
|
*
|
||||||
|
* \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
|
||||||
|
* \ingroup EventGroup
|
||||||
|
*/
|
||||||
|
#define xEventGroupGetBitsFromISR( xEventGroup ) xEventGroupClearBitsFromISR( xEventGroup, 0 )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* event_groups.h
|
||||||
|
*<pre>
|
||||||
|
void xEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||||
|
</pre>
|
||||||
|
*
|
||||||
|
* Delete an event group that was previously created by a call to
|
||||||
|
* xEventGroupCreate(). Tasks that are blocked on the event group will be
|
||||||
|
* unblocked and obtain 0 as the event group's value.
|
||||||
|
*
|
||||||
|
* @param xEventGroup The event group being deleted.
|
||||||
|
*/
|
||||||
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup );
|
||||||
|
|
||||||
|
/* For internal use only. */
|
||||||
|
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet );
|
||||||
|
|
||||||
|
#if (configUSE_TRACE_FACILITY == 1)
|
||||||
|
UBaseType_t uxEventGroupGetNumber( void* xEventGroup );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EVENT_GROUPS_H */
|
||||||
|
|
||||||
|
|
||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MPU_WRAPPERS_H
|
#ifndef MPU_WRAPPERS_H
|
||||||
@ -70,8 +82,8 @@ only for ports that are using the MPU. */
|
|||||||
#define vTaskDelay MPU_vTaskDelay
|
#define vTaskDelay MPU_vTaskDelay
|
||||||
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||||
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||||
|
#define eTaskGetState MPU_eTaskGetState
|
||||||
#define vTaskSuspend MPU_vTaskSuspend
|
#define vTaskSuspend MPU_vTaskSuspend
|
||||||
#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended
|
|
||||||
#define vTaskResume MPU_vTaskResume
|
#define vTaskResume MPU_vTaskResume
|
||||||
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||||
#define xTaskResumeAll MPU_xTaskResumeAll
|
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||||
@ -79,16 +91,16 @@ only for ports that are using the MPU. */
|
|||||||
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||||
#define vTaskList MPU_vTaskList
|
#define vTaskList MPU_vTaskList
|
||||||
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||||
#define vTaskStartTrace MPU_vTaskStartTrace
|
|
||||||
#define ulTaskEndTrace MPU_ulTaskEndTrace
|
|
||||||
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||||
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||||
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||||
|
#define uxTaskGetSystemState MPU_uxTaskGetSystemState
|
||||||
|
|
||||||
#define xQueueCreate MPU_xQueueCreate
|
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||||
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||||
@ -99,6 +111,12 @@ only for ports that are using the MPU. */
|
|||||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
#define vQueueDelete MPU_vQueueDelete
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||||
|
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||||
|
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||||
|
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||||
|
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||||
|
#define xQueuePeekFromISR MPU_xQueuePeekFromISR
|
||||||
|
|
||||||
#define pvPortMalloc MPU_pvPortMalloc
|
#define pvPortMalloc MPU_pvPortMalloc
|
||||||
#define vPortFree MPU_vPortFree
|
#define vPortFree MPU_vPortFree
|
||||||
@ -118,7 +136,6 @@ only for ports that are using the MPU. */
|
|||||||
/* Ensure API functions go in the privileged execution section. */
|
/* Ensure API functions go in the privileged execution section. */
|
||||||
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||||
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||||
//#define PRIVILEGED_DATA
|
|
||||||
|
|
||||||
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
|||||||
135
src/os/rtos/include/mpu_wrappers.h.old
Normal file
135
src/os/rtos/include/mpu_wrappers.h.old
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPU_WRAPPERS_H
|
||||||
|
#define MPU_WRAPPERS_H
|
||||||
|
|
||||||
|
/* This file redefines API functions to be called through a wrapper macro, but
|
||||||
|
only for ports that are using the MPU. */
|
||||||
|
#ifdef portUSING_MPU_WRAPPERS
|
||||||
|
|
||||||
|
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
|
||||||
|
included from queue.c or task.c to prevent it from having an effect within
|
||||||
|
those files. */
|
||||||
|
#ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#define xTaskGenericCreate MPU_xTaskGenericCreate
|
||||||
|
#define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions
|
||||||
|
#define vTaskDelete MPU_vTaskDelete
|
||||||
|
#define vTaskDelayUntil MPU_vTaskDelayUntil
|
||||||
|
#define vTaskDelay MPU_vTaskDelay
|
||||||
|
#define uxTaskPriorityGet MPU_uxTaskPriorityGet
|
||||||
|
#define vTaskPrioritySet MPU_vTaskPrioritySet
|
||||||
|
#define vTaskSuspend MPU_vTaskSuspend
|
||||||
|
#define xTaskIsTaskSuspended MPU_xTaskIsTaskSuspended
|
||||||
|
#define vTaskResume MPU_vTaskResume
|
||||||
|
#define vTaskSuspendAll MPU_vTaskSuspendAll
|
||||||
|
#define xTaskResumeAll MPU_xTaskResumeAll
|
||||||
|
#define xTaskGetTickCount MPU_xTaskGetTickCount
|
||||||
|
#define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks
|
||||||
|
#define vTaskList MPU_vTaskList
|
||||||
|
#define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats
|
||||||
|
#define vTaskStartTrace MPU_vTaskStartTrace
|
||||||
|
#define ulTaskEndTrace MPU_ulTaskEndTrace
|
||||||
|
#define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag
|
||||||
|
#define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag
|
||||||
|
#define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook
|
||||||
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
|
||||||
|
#define xQueueCreate MPU_xQueueCreate
|
||||||
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
|
#define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive
|
||||||
|
#define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive
|
||||||
|
#define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore
|
||||||
|
#define xQueueGenericSend MPU_xQueueGenericSend
|
||||||
|
#define xQueueAltGenericSend MPU_xQueueAltGenericSend
|
||||||
|
#define xQueueAltGenericReceive MPU_xQueueAltGenericReceive
|
||||||
|
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||||
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
|
||||||
|
#define pvPortMalloc MPU_pvPortMalloc
|
||||||
|
#define vPortFree MPU_vPortFree
|
||||||
|
#define xPortGetFreeHeapSize MPU_xPortGetFreeHeapSize
|
||||||
|
#define vPortInitialiseBlocks MPU_vPortInitialiseBlocks
|
||||||
|
|
||||||
|
#if configQUEUE_REGISTRY_SIZE > 0
|
||||||
|
#define vQueueAddToRegistry MPU_vQueueAddToRegistry
|
||||||
|
#define vQueueUnregisterQueue MPU_vQueueUnregisterQueue
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Remove the privileged function macro. */
|
||||||
|
#define PRIVILEGED_FUNCTION
|
||||||
|
|
||||||
|
#else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
/* Ensure API functions go in the privileged execution section. */
|
||||||
|
#define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions")))
|
||||||
|
#define PRIVILEGED_DATA __attribute__((section("privileged_data")))
|
||||||
|
//#define PRIVILEGED_DATA
|
||||||
|
|
||||||
|
#endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
|
||||||
|
|
||||||
|
#else /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
#define PRIVILEGED_FUNCTION
|
||||||
|
#define PRIVILEGED_DATA
|
||||||
|
#define portUSING_MPU_WRAPPERS 0
|
||||||
|
|
||||||
|
#endif /* portUSING_MPU_WRAPPERS */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MPU_WRAPPERS_H */
|
||||||
|
|
||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
@ -58,8 +70,10 @@
|
|||||||
#ifndef PORTABLE_H
|
#ifndef PORTABLE_H
|
||||||
#define PORTABLE_H
|
#define PORTABLE_H
|
||||||
|
|
||||||
/* Include the macro file relevant to the port being used. */
|
/* Include the macro file relevant to the port being used.
|
||||||
|
NOTE: The following definitions are *DEPRECATED* as it is preferred to instead
|
||||||
|
just add the path to the correct portmacro.h header file to the compiler's
|
||||||
|
include path. */
|
||||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
typedef void ( __interrupt __far *pxISR )();
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
@ -79,19 +93,19 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MPLAB_PIC24_PORT
|
#ifdef MPLAB_PIC24_PORT
|
||||||
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MPLAB_DSPIC_PORT
|
#ifdef MPLAB_DSPIC_PORT
|
||||||
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
#include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MPLAB_PIC18F_PORT
|
#ifdef MPLAB_PIC18F_PORT
|
||||||
#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
|
#include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MPLAB_PIC32MX_PORT
|
#ifdef MPLAB_PIC32MX_PORT
|
||||||
#include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
|
#include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _FEDPICC
|
#ifdef _FEDPICC
|
||||||
@ -115,9 +129,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IAR_MSP430
|
#ifdef IAR_MSP430
|
||||||
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GCC_MSP430
|
#ifdef GCC_MSP430
|
||||||
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
@ -153,7 +167,7 @@
|
|||||||
#ifdef STR75X_IAR
|
#ifdef STR75X_IAR
|
||||||
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STR75X_GCC
|
#ifdef STR75X_GCC
|
||||||
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
@ -161,7 +175,7 @@
|
|||||||
#ifdef STR91X_IAR
|
#ifdef STR91X_IAR
|
||||||
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef GCC_H8S
|
#ifdef GCC_H8S
|
||||||
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
@ -189,10 +203,10 @@
|
|||||||
#ifdef IAR_ARMCM3_LM
|
#ifdef IAR_ARMCM3_LM
|
||||||
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HCS12_CODE_WARRIOR
|
#ifdef HCS12_CODE_WARRIOR
|
||||||
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MICROBLAZE_GCC
|
#ifdef MICROBLAZE_GCC
|
||||||
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||||
@ -292,11 +306,11 @@
|
|||||||
#ifdef __IAR_78K0R_Kx3__
|
#ifdef __IAR_78K0R_Kx3__
|
||||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __IAR_78K0R_Kx3L__
|
#ifdef __IAR_78K0R_Kx3L__
|
||||||
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
||||||
have the path as part of the project options, rather than as relative from
|
have the path as part of the project options, rather than as relative from
|
||||||
the project location. If portENTER_CRITICAL() has not been defined then
|
the project location. If portENTER_CRITICAL() has not been defined then
|
||||||
@ -304,9 +318,9 @@ portmacro.h has not yet been included - as every portmacro.h provides a
|
|||||||
portENTER_CRITICAL() definition. Check the demo application for your demo
|
portENTER_CRITICAL() definition. Check the demo application for your demo
|
||||||
to find the path to the correct portmacro.h file. */
|
to find the path to the correct portmacro.h file. */
|
||||||
#ifndef portENTER_CRITICAL
|
#ifndef portENTER_CRITICAL
|
||||||
#include "portmacro.h"
|
#include "portmacro.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if portBYTE_ALIGNMENT == 8
|
#if portBYTE_ALIGNMENT == 8
|
||||||
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
#endif
|
#endif
|
||||||
@ -344,9 +358,9 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
#else
|
#else
|
||||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
|
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -356,13 +370,13 @@ void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
|||||||
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
int xPortMemIsKernel(void *mem) PRIVILEGED_FUNCTION;
|
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup the hardware ready for the scheduler to take control. This generally
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||||
@ -378,9 +392,9 @@ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
|||||||
* Fills the xMPUSettings structure with the memory region information
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
* contained in xRegions.
|
* contained in xRegions.
|
||||||
*/
|
*/
|
||||||
#if( portUSING_MPU_WRAPPERS == 1 )
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
struct xMEMORY_REGION;
|
struct xMEMORY_REGION;
|
||||||
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint16_t usStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
391
src/os/rtos/include/portable.h.old
Normal file
391
src/os/rtos/include/portable.h.old
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Portable layer API. Each function must be defined for each port.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PORTABLE_H
|
||||||
|
#define PORTABLE_H
|
||||||
|
|
||||||
|
/* Include the macro file relevant to the port being used. */
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
|
||||||
|
#include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MEGA_AVR
|
||||||
|
#include "../portable/GCC/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MEGA_AVR
|
||||||
|
#include "../portable/IAR/ATMega323/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC24_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_DSPIC_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC24_dsPIC\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC18F_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC18F\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MPLAB_PIC32MX_PORT
|
||||||
|
#include "..\..\Source\portable\MPLAB\PIC32MX\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _FEDPICC
|
||||||
|
#include "libFreeRTOS/Include/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDCC_CYGNAL
|
||||||
|
#include "../../Source/portable/SDCC/Cygnal/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARM7_ECLIPSE
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_LPC23xx
|
||||||
|
#include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_MSP430
|
||||||
|
#include "..\..\Source\portable\IAR\MSP430\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MSP430
|
||||||
|
#include "../../Source/portable/GCC/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ROWLEY_MSP430
|
||||||
|
#include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ARM7_LPC21xx_KEIL_RVDS
|
||||||
|
#include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_GCC
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM7_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SAM9XE_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LPC2000_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR71X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR71x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR75X_GCC
|
||||||
|
#include "..\..\Source\portable\GCC\STR75x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef STR91X_IAR
|
||||||
|
#include "..\..\Source\portable\IAR\STR91x\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_H8S
|
||||||
|
#include "../../Source/portable/GCC/H8S2329/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_AT91FR40008
|
||||||
|
#include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RVDS_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3_LM3S102
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_ARMCM3
|
||||||
|
#include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARM_CM3
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IAR_ARMCM3_LM
|
||||||
|
#include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HCS12_CODE_WARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MICROBLAZE_GCC
|
||||||
|
#include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TERN_EE
|
||||||
|
#include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_HCS12
|
||||||
|
#include "../../Source/portable/GCC/HCS12/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_MCF5235
|
||||||
|
#include "../../Source/portable/GCC/MCF5235/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_GCC
|
||||||
|
#include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef COLDFIRE_V2_CODEWARRIOR
|
||||||
|
#include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC405
|
||||||
|
#include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GCC_PPC440
|
||||||
|
#include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _16FX_SOFTUNE
|
||||||
|
#include "..\..\Source\portable\Softune\MB96340\portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_INDUSTRIAL_PC_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BCC_FLASH_LITE_186_PORT
|
||||||
|
/* A short file name has to be used in place of the normal
|
||||||
|
FreeRTOSConfig.h when using the Borland compiler. */
|
||||||
|
#include "frconfig.h"
|
||||||
|
#include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
|
||||||
|
typedef void ( __interrupt __far *pxISR )();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#ifdef __AVR32_AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ICCAVR32__
|
||||||
|
#ifdef __CORE__
|
||||||
|
#if __CORE__ == __AVR32A__
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __91467D
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __96340
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Fx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx3_L__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Jx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_V850ES_Hx2__
|
||||||
|
#include "../../Source/portable/IAR/V850ES/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __IAR_78K0R_Kx3L__
|
||||||
|
#include "../../Source/portable/IAR/78K0R/portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Catch all to ensure portmacro.h is included in the build. Newer demos
|
||||||
|
have the path as part of the project options, rather than as relative from
|
||||||
|
the project location. If portENTER_CRITICAL() has not been defined then
|
||||||
|
portmacro.h has not yet been included - as every portmacro.h provides a
|
||||||
|
portENTER_CRITICAL() definition. Check the demo application for your demo
|
||||||
|
to find the path to the correct portmacro.h file. */
|
||||||
|
#ifndef portENTER_CRITICAL
|
||||||
|
#include "portmacro.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 8
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0007 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 4
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0003 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 2
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0001 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if portBYTE_ALIGNMENT == 1
|
||||||
|
#define portBYTE_ALIGNMENT_MASK ( 0x0000 )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portBYTE_ALIGNMENT_MASK
|
||||||
|
#error "Invalid portBYTE_ALIGNMENT definition"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef portNUM_CONFIGURABLE_REGIONS
|
||||||
|
#define portNUM_CONFIGURABLE_REGIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "mpu_wrappers.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the stack of a new task so it is ready to be placed under the
|
||||||
|
* scheduler control. The registers have to be placed on the stack in
|
||||||
|
* the order that the port expects to find them.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged ) PRIVILEGED_FUNCTION;
|
||||||
|
#else
|
||||||
|
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map to the memory management routines required for the port.
|
||||||
|
*/
|
||||||
|
void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
|
||||||
|
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
|
||||||
|
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
|
||||||
|
int xPortMemIsKernel(void *mem) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup the hardware ready for the scheduler to take control. This generally
|
||||||
|
* sets up a tick interrupt and sets timers for the correct tick frequency.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
|
||||||
|
* the hardware is left in its original condition after the scheduler stops
|
||||||
|
* executing.
|
||||||
|
*/
|
||||||
|
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The structures and methods of manipulating the MPU are contained within the
|
||||||
|
* port layer.
|
||||||
|
*
|
||||||
|
* Fills the xMPUSettings structure with the memory region information
|
||||||
|
* contained in xRegions.
|
||||||
|
*/
|
||||||
|
#if( portUSING_MPU_WRAPPERS == 1 )
|
||||||
|
struct xMEMORY_REGION;
|
||||||
|
void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth ) PRIVILEGED_FUNCTION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PORTABLE_H */
|
||||||
|
|
||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PROJDEFS_H
|
#ifndef PROJDEFS_H
|
||||||
@ -60,20 +72,19 @@
|
|||||||
*/
|
*/
|
||||||
typedef void (*TaskFunction_t)( void * );
|
typedef void (*TaskFunction_t)( void * );
|
||||||
|
|
||||||
/* Defines the prototype to which task functions must conform. */
|
/* Converts a time in milliseconds to a time in ticks. */
|
||||||
typedef void (*pdTASK_CODE)( void * );
|
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
|
||||||
|
|
||||||
#define pdTRUE ( 1 )
|
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||||
#define pdFALSE ( 0 )
|
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||||
|
|
||||||
#define pdPASS ( 1 )
|
#define pdPASS ( pdTRUE )
|
||||||
#define pdFAIL ( 0 )
|
#define pdFAIL ( pdFALSE )
|
||||||
#define errQUEUE_EMPTY ( 0 )
|
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
|
||||||
#define errQUEUE_FULL ( 0 )
|
#define errQUEUE_FULL ( ( BaseType_t ) 0 )
|
||||||
|
|
||||||
/* Error definitions. */
|
/* Error definitions. */
|
||||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||||
#define errNO_TASK_TO_RUN ( -2 )
|
|
||||||
#define errQUEUE_BLOCKED ( -4 )
|
#define errQUEUE_BLOCKED ( -4 )
|
||||||
#define errQUEUE_YIELD ( -5 )
|
#define errQUEUE_YIELD ( -5 )
|
||||||
|
|
||||||
|
|||||||
83
src/os/rtos/include/projdefs.h.old
Normal file
83
src/os/rtos/include/projdefs.h.old
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PROJDEFS_H
|
||||||
|
#define PROJDEFS_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the prototype to which task functions must conform. Defined in this
|
||||||
|
* file to ensure the type is known before portable.h is included.
|
||||||
|
*/
|
||||||
|
typedef void (*TaskFunction_t)( void * );
|
||||||
|
|
||||||
|
/* Defines the prototype to which task functions must conform. */
|
||||||
|
typedef void (*pdTASK_CODE)( void * );
|
||||||
|
|
||||||
|
#define pdTRUE ( 1 )
|
||||||
|
#define pdFALSE ( 0 )
|
||||||
|
|
||||||
|
#define pdPASS ( 1 )
|
||||||
|
#define pdFAIL ( 0 )
|
||||||
|
#define errQUEUE_EMPTY ( 0 )
|
||||||
|
#define errQUEUE_FULL ( 0 )
|
||||||
|
|
||||||
|
/* Error definitions. */
|
||||||
|
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 )
|
||||||
|
#define errNO_TASK_TO_RUN ( -2 )
|
||||||
|
#define errQUEUE_BLOCKED ( -4 )
|
||||||
|
#define errQUEUE_YIELD ( -5 )
|
||||||
|
|
||||||
|
#endif /* PROJDEFS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -56,7 +68,7 @@
|
|||||||
* heavily for the schedulers needs, it is also available for use by
|
* heavily for the schedulers needs, it is also available for use by
|
||||||
* application code.
|
* application code.
|
||||||
*
|
*
|
||||||
* xLists can only store pointers to xListItems. Each xListItem contains a
|
* list_ts can only store pointers to list_item_ts. Each ListItem_t contains a
|
||||||
* numeric value (xItemValue). Most of the time the lists are sorted in
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
* descending item value order.
|
* descending item value order.
|
||||||
*
|
*
|
||||||
@ -83,6 +95,38 @@
|
|||||||
#ifndef RTOS_LIST_H
|
#ifndef RTOS_LIST_H
|
||||||
#define RTOS_LIST_H
|
#define RTOS_LIST_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The list structure members are modified from within interrupts, and therefore
|
||||||
|
* by rights should be declared volatile. However, they are only modified in a
|
||||||
|
* functionally atomic way (within critical sections of with the scheduler
|
||||||
|
* suspended) and are either passed by reference into a function or indexed via
|
||||||
|
* a volatile variable. Therefore, in all use cases tested so far, the volatile
|
||||||
|
* qualifier can be omitted in order to provide a moderate performance
|
||||||
|
* improvement without adversely affecting functional behaviour. The assembly
|
||||||
|
* instructions generated by the IAR, ARM and GCC compilers when the respective
|
||||||
|
* compiler's options were set for maximum optimisation has been inspected and
|
||||||
|
* deemed to be as intended. That said, as compiler technology advances, and
|
||||||
|
* especially if aggressive cross module optimisation is used (a use case that
|
||||||
|
* has not been exercised to any great extend) then it is feasible that the
|
||||||
|
* volatile qualifier will be needed for correct optimisation. It is expected
|
||||||
|
* that a compiler removing essential code because, without the volatile
|
||||||
|
* qualifier on the list structure members and with aggressive cross module
|
||||||
|
* optimisation, the compiler deemed the code unnecessary will result in
|
||||||
|
* complete and obvious failure of the scheduler. If this is ever experienced
|
||||||
|
* then the volatile qualifier can be inserted in the relevant places within the
|
||||||
|
* list structures by simply defining configLIST_VOLATILE to volatile in
|
||||||
|
* FreeRTOSConfig.h (as per the example at the bottom of this comment block).
|
||||||
|
* If configLIST_VOLATILE is not defined then the preprocessor directives below
|
||||||
|
* will simply #define configLIST_VOLATILE away completely.
|
||||||
|
*
|
||||||
|
* To use volatile list structure members then add the following line to
|
||||||
|
* FreeRTOSConfig.h (without the quotes):
|
||||||
|
* "#define configLIST_VOLATILE volatile"
|
||||||
|
*/
|
||||||
|
#ifndef configLIST_VOLATILE
|
||||||
|
#define configLIST_VOLATILE
|
||||||
|
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -91,31 +135,31 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
struct xLIST_ITEM
|
struct xLIST_ITEM
|
||||||
{
|
{
|
||||||
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */
|
||||||
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */
|
||||||
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
};
|
};
|
||||||
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
struct xMINI_LIST_ITEM
|
struct xMINI_LIST_ITEM
|
||||||
{
|
{
|
||||||
portTickType xItemValue;
|
configLIST_VOLATILE TickType_t xItemValue;
|
||||||
volatile struct xLIST_ITEM *pxNext;
|
struct xLIST_ITEM * configLIST_VOLATILE pxNext;
|
||||||
volatile struct xLIST_ITEM *pxPrevious;
|
struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
|
||||||
};
|
};
|
||||||
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
typedef struct xMINI_LIST_ITEM MiniListItem_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the type of queue used by the scheduler.
|
* Definition of the type of queue used by the scheduler.
|
||||||
*/
|
*/
|
||||||
typedef struct xLIST
|
typedef struct xLIST
|
||||||
{
|
{
|
||||||
volatile unsigned portBASE_TYPE uxNumberOfItems;
|
configLIST_VOLATILE UBaseType_t uxNumberOfItems;
|
||||||
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
|
||||||
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
} xList;
|
} List_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the owner of a list item. The owner of a list item
|
* Access macro to set the owner of a list item. The owner of a list item
|
||||||
@ -124,7 +168,16 @@ typedef struct xLIST
|
|||||||
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) ( pxOwner )
|
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to get the owner of a list item. The owner of a list item
|
||||||
|
* is the object (usually a TCB) that contains the list item.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to set the value of the list item. In most cases the value is
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
@ -133,26 +186,50 @@ typedef struct xLIST
|
|||||||
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )
|
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro the retrieve the value of the list item. The value can
|
* Access macro to retrieve the value of the list item. The value can
|
||||||
* represent anything - for example a the priority of a task, or the time at
|
* represent anything - for example the priority of a task, or the time at
|
||||||
* which a task should be unblocked.
|
* which a task should be unblocked.
|
||||||
*
|
*
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro the retrieve the value of the list item at the head of a given
|
* Access macro to retrieve the value of the list item at the head of a given
|
||||||
* list.
|
* list.
|
||||||
*
|
*
|
||||||
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )
|
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item at the head of the list.
|
||||||
|
*
|
||||||
|
* \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item at the head of the list.
|
||||||
|
*
|
||||||
|
* \page listGET_NEXT listGET_NEXT
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list item that marks the end of the list
|
||||||
|
*
|
||||||
|
* \page listGET_END_MARKER listGET_END_MARKER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to determine if a list contains any items. The macro will
|
* Access macro to determine if a list contains any items. The macro will
|
||||||
@ -161,19 +238,19 @@ typedef struct xLIST
|
|||||||
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
|
#define listLIST_IS_EMPTY( pxList ) ( ( BaseType_t ) ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access macro to return the number of items in the list.
|
* Access macro to return the number of items in the list.
|
||||||
*/
|
*/
|
||||||
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access function to obtain the owner of the next entry in a list.
|
* Access function to obtain the owner of the next entry in a list.
|
||||||
*
|
*
|
||||||
* The list member pxIndex is used to walk through a list. Calling
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||||
* and returns that entries pxOwner parameter. Using multiple calls to this
|
* and returns that entry's pxOwner parameter. Using multiple calls to this
|
||||||
* function it is therefore possible to move through every item contained in
|
* function it is therefore possible to move through every item contained in
|
||||||
* a list.
|
* a list.
|
||||||
*
|
*
|
||||||
@ -182,22 +259,23 @@ typedef struct xLIST
|
|||||||
* The pxOwner parameter effectively creates a two way link between the list
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
* item and its owner.
|
* item and its owner.
|
||||||
*
|
*
|
||||||
|
* @param pxTCB pxTCB is set to the address of the owner of the next list item.
|
||||||
* @param pxList The list from which the next item owner is to be returned.
|
* @param pxList The list from which the next item owner is to be returned.
|
||||||
*
|
*
|
||||||
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
{ \
|
{ \
|
||||||
xList * const pxConstList = ( pxList ); \
|
List_t * const pxConstList = ( pxList ); \
|
||||||
/* Increment the index to the next item and return the item, ensuring */ \
|
/* Increment the index to the next item and return the item, ensuring */ \
|
||||||
/* we don't return the marker used at the end of the list. */ \
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
|
if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
|
||||||
{ \
|
{ \
|
||||||
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
} \
|
} \
|
||||||
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -226,10 +304,24 @@ xList * const pxConstList = ( pxList ); \
|
|||||||
*
|
*
|
||||||
* @param pxList The list we want to know if the list item is within.
|
* @param pxList The list we want to know if the list item is within.
|
||||||
* @param pxListItem The list item we want to know if is in the list.
|
* @param pxListItem The list item we want to know if is in the list.
|
||||||
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
|
* @return pdTRUE if the list item is in the list, otherwise pdFALSE.
|
||||||
* pointer against
|
|
||||||
*/
|
*/
|
||||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( BaseType_t ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the list a list item is contained within (referenced from).
|
||||||
|
*
|
||||||
|
* @param pxListItem The list item being queried.
|
||||||
|
* @return A pointer to the List_t object that references the pxListItem
|
||||||
|
*/
|
||||||
|
#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pvContainer )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This provides a crude means of knowing if a list has been initialised, as
|
||||||
|
* pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
|
||||||
|
* function.
|
||||||
|
*/
|
||||||
|
#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list is used! This initialises all the members
|
* Must be called before a list is used! This initialises all the members
|
||||||
@ -241,7 +333,7 @@ xList * const pxConstList = ( pxList ); \
|
|||||||
* \page vListInitialise vListInitialise
|
* \page vListInitialise vListInitialise
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialise( xList *pxList );
|
void vListInitialise( List_t * const pxList );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Must be called before a list item is used. This sets the list container to
|
* Must be called before a list item is used. This sets the list container to
|
||||||
@ -252,7 +344,7 @@ void vListInitialise( xList *pxList );
|
|||||||
* \page vListInitialiseItem vListInitialiseItem
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInitialiseItem( xListItem *pxItem );
|
void vListInitialiseItem( ListItem_t * const pxItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted into the list in
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
@ -260,12 +352,12 @@ void vListInitialiseItem( xListItem *pxItem );
|
|||||||
*
|
*
|
||||||
* @param pxList The list into which the item is to be inserted.
|
* @param pxList The list into which the item is to be inserted.
|
||||||
*
|
*
|
||||||
* @param pxNewListItem The item to that is to be placed in the list.
|
* @param pxNewListItem The item that is to be placed in the list.
|
||||||
*
|
*
|
||||||
* \page vListInsert vListInsert
|
* \page vListInsert vListInsert
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert a list item into a list. The item will be inserted in a position
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
@ -286,19 +378,22 @@ void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
|||||||
* \page vListInsertEnd vListInsertEnd
|
* \page vListInsertEnd vListInsertEnd
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove an item from a list. The list item has a pointer to the list that
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
* it is in, so only the list item need be passed into the function.
|
* it is in, so only the list item need be passed into the function.
|
||||||
*
|
*
|
||||||
* @param vListRemove The item to be removed. The item will remove itself from
|
* @param uxListRemove The item to be removed. The item will remove itself from
|
||||||
* the list pointed to by it's pxContainer parameter.
|
* the list pointed to by it's pxContainer parameter.
|
||||||
*
|
*
|
||||||
* \page vListRemove vListRemove
|
* @return The number of items that remain in the list after the list item has
|
||||||
|
* been removed.
|
||||||
|
*
|
||||||
|
* \page uxListRemove uxListRemove
|
||||||
* \ingroup LinkedList
|
* \ingroup LinkedList
|
||||||
*/
|
*/
|
||||||
void vListRemove( xListItem *pxItemToRemove );
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
308
src/os/rtos/include/rtoslist.h.old
Normal file
308
src/os/rtos/include/rtoslist.h.old
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is the list implementation used by the scheduler. While it is tailored
|
||||||
|
* heavily for the schedulers needs, it is also available for use by
|
||||||
|
* application code.
|
||||||
|
*
|
||||||
|
* xLists can only store pointers to xListItems. Each xListItem contains a
|
||||||
|
* numeric value (xItemValue). Most of the time the lists are sorted in
|
||||||
|
* descending item value order.
|
||||||
|
*
|
||||||
|
* Lists are created already containing one list item. The value of this
|
||||||
|
* item is the maximum possible that can be stored, it is therefore always at
|
||||||
|
* the end of the list and acts as a marker. The list member pxHead always
|
||||||
|
* points to this marker - even though it is at the tail of the list. This
|
||||||
|
* is because the tail contains a wrap back pointer to the true head of
|
||||||
|
* the list.
|
||||||
|
*
|
||||||
|
* In addition to it's value, each list item contains a pointer to the next
|
||||||
|
* item in the list (pxNext), a pointer to the list it is in (pxContainer)
|
||||||
|
* and a pointer to back to the object that contains it. These later two
|
||||||
|
* pointers are included for efficiency of list manipulation. There is
|
||||||
|
* effectively a two way link between the object containing the list item and
|
||||||
|
* the list item itself.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* \page ListIntroduction List Implementation
|
||||||
|
* \ingroup FreeRTOSIntro
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RTOS_LIST_H
|
||||||
|
#define RTOS_LIST_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Definition of the only type of object that a list can contain.
|
||||||
|
*/
|
||||||
|
struct xLIST_ITEM
|
||||||
|
{
|
||||||
|
portTickType xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */
|
||||||
|
volatile struct xLIST_ITEM * pxNext; /*< Pointer to the next xListItem in the list. */
|
||||||
|
volatile struct xLIST_ITEM * pxPrevious;/*< Pointer to the previous xListItem in the list. */
|
||||||
|
void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */
|
||||||
|
void * pvContainer; /*< Pointer to the list in which this list item is placed (if any). */
|
||||||
|
};
|
||||||
|
typedef struct xLIST_ITEM xListItem; /* For some reason lint wants this as two separate definitions. */
|
||||||
|
|
||||||
|
struct xMINI_LIST_ITEM
|
||||||
|
{
|
||||||
|
portTickType xItemValue;
|
||||||
|
volatile struct xLIST_ITEM *pxNext;
|
||||||
|
volatile struct xLIST_ITEM *pxPrevious;
|
||||||
|
};
|
||||||
|
typedef struct xMINI_LIST_ITEM xMiniListItem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Definition of the type of queue used by the scheduler.
|
||||||
|
*/
|
||||||
|
typedef struct xLIST
|
||||||
|
{
|
||||||
|
volatile unsigned portBASE_TYPE uxNumberOfItems;
|
||||||
|
volatile xListItem * pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to pvListGetOwnerOfNextEntry (). */
|
||||||
|
volatile xMiniListItem xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
|
||||||
|
} xList;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to set the owner of a list item. The owner of a list item
|
||||||
|
* is the object (usually a TCB) that contains the list item.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( pxListItem )->pvOwner = ( void * ) ( pxOwner )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to set the value of the list item. In most cases the value is
|
||||||
|
* used to sort the list in descending order.
|
||||||
|
*
|
||||||
|
* \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( pxListItem )->xItemValue = ( xValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro the retrieve the value of the list item. The value can
|
||||||
|
* represent anything - for example a the priority of a task, or the time at
|
||||||
|
* which a task should be unblocked.
|
||||||
|
*
|
||||||
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro the retrieve the value of the list item at the head of a given
|
||||||
|
* list.
|
||||||
|
*
|
||||||
|
* \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->xItemValue )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to determine if a list contains any items. The macro will
|
||||||
|
* only have the value true if the list is empty.
|
||||||
|
*
|
||||||
|
* \page listLIST_IS_EMPTY listLIST_IS_EMPTY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listLIST_IS_EMPTY( pxList ) ( ( pxList )->uxNumberOfItems == ( unsigned portBASE_TYPE ) 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access macro to return the number of items in the list.
|
||||||
|
*/
|
||||||
|
#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access function to obtain the owner of the next entry in a list.
|
||||||
|
*
|
||||||
|
* The list member pxIndex is used to walk through a list. Calling
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
|
||||||
|
* and returns that entries pxOwner parameter. Using multiple calls to this
|
||||||
|
* function it is therefore possible to move through every item contained in
|
||||||
|
* a list.
|
||||||
|
*
|
||||||
|
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||||
|
* the list item. In the scheduler this is normally a task control block.
|
||||||
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
|
* item and its owner.
|
||||||
|
*
|
||||||
|
* @param pxList The list from which the next item owner is to be returned.
|
||||||
|
*
|
||||||
|
* \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \
|
||||||
|
{ \
|
||||||
|
xList * const pxConstList = ( pxList ); \
|
||||||
|
/* Increment the index to the next item and return the item, ensuring */ \
|
||||||
|
/* we don't return the marker used at the end of the list. */ \
|
||||||
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
|
if( ( pxConstList )->pxIndex == ( xListItem * ) &( ( pxConstList )->xListEnd ) ) \
|
||||||
|
{ \
|
||||||
|
( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \
|
||||||
|
} \
|
||||||
|
( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access function to obtain the owner of the first entry in a list. Lists
|
||||||
|
* are normally sorted in ascending item value order.
|
||||||
|
*
|
||||||
|
* This function returns the pxOwner member of the first item in the list.
|
||||||
|
* The pxOwner parameter of a list item is a pointer to the object that owns
|
||||||
|
* the list item. In the scheduler this is normally a task control block.
|
||||||
|
* The pxOwner parameter effectively creates a two way link between the list
|
||||||
|
* item and its owner.
|
||||||
|
*
|
||||||
|
* @param pxList The list from which the owner of the head item is to be
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see if a list item is within a list. The list item maintains a
|
||||||
|
* "container" pointer that points to the list it is in. All this macro does
|
||||||
|
* is check to see if the container and the list match.
|
||||||
|
*
|
||||||
|
* @param pxList The list we want to know if the list item is within.
|
||||||
|
* @param pxListItem The list item we want to know if is in the list.
|
||||||
|
* @return pdTRUE is the list item is in the list, otherwise pdFALSE.
|
||||||
|
* pointer against
|
||||||
|
*/
|
||||||
|
#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( pxListItem )->pvContainer == ( void * ) ( pxList ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called before a list is used! This initialises all the members
|
||||||
|
* of the list structure and inserts the xListEnd item into the list as a
|
||||||
|
* marker to the back of the list.
|
||||||
|
*
|
||||||
|
* @param pxList Pointer to the list being initialised.
|
||||||
|
*
|
||||||
|
* \page vListInitialise vListInitialise
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInitialise( xList *pxList );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called before a list item is used. This sets the list container to
|
||||||
|
* null so the item does not think that it is already contained in a list.
|
||||||
|
*
|
||||||
|
* @param pxItem Pointer to the list item being initialised.
|
||||||
|
*
|
||||||
|
* \page vListInitialiseItem vListInitialiseItem
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInitialiseItem( xListItem *pxItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a list item into a list. The item will be inserted into the list in
|
||||||
|
* a position determined by its item value (descending item value order).
|
||||||
|
*
|
||||||
|
* @param pxList The list into which the item is to be inserted.
|
||||||
|
*
|
||||||
|
* @param pxNewListItem The item to that is to be placed in the list.
|
||||||
|
*
|
||||||
|
* \page vListInsert vListInsert
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInsert( xList *pxList, xListItem *pxNewListItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a list item into a list. The item will be inserted in a position
|
||||||
|
* such that it will be the last item within the list returned by multiple
|
||||||
|
* calls to listGET_OWNER_OF_NEXT_ENTRY.
|
||||||
|
*
|
||||||
|
* The list member pvIndex is used to walk through a list. Calling
|
||||||
|
* listGET_OWNER_OF_NEXT_ENTRY increments pvIndex to the next item in the list.
|
||||||
|
* Placing an item in a list using vListInsertEnd effectively places the item
|
||||||
|
* in the list position pointed to by pvIndex. This means that every other
|
||||||
|
* item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
|
||||||
|
* the pvIndex parameter again points to the item being inserted.
|
||||||
|
*
|
||||||
|
* @param pxList The list into which the item is to be inserted.
|
||||||
|
*
|
||||||
|
* @param pxNewListItem The list item to be inserted into the list.
|
||||||
|
*
|
||||||
|
* \page vListInsertEnd vListInsertEnd
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove an item from a list. The list item has a pointer to the list that
|
||||||
|
* it is in, so only the list item need be passed into the function.
|
||||||
|
*
|
||||||
|
* @param vListRemove The item to be removed. The item will remove itself from
|
||||||
|
* the list pointed to by it's pxContainer parameter.
|
||||||
|
*
|
||||||
|
* \page vListRemove vListRemove
|
||||||
|
* \ingroup LinkedList
|
||||||
|
*/
|
||||||
|
void vListRemove( xListItem *pxItemToRemove );
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
1287
src/os/rtos/include/rtosqueue.h.old
Normal file
1287
src/os/rtos/include/rtosqueue.h.old
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,54 +1,66 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -59,56 +71,81 @@
|
|||||||
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "portable.h"
|
/*lint -e537 This headers are only multiply included if the application code
|
||||||
#include "rtoslist.h"
|
happens to also be including task.h. */
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
/*lint +e956 */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* IDs for commands that can be sent/received on the timer queue. These are to
|
|
||||||
be used solely through the macros that make up the public software timer API,
|
|
||||||
as defined below. */
|
|
||||||
#define tmrCOMMAND_START 0
|
|
||||||
#define tmrCOMMAND_STOP 1
|
|
||||||
#define tmrCOMMAND_CHANGE_PERIOD 2
|
|
||||||
#define tmrCOMMAND_DELETE 3
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* MACROS AND DEFINITIONS
|
* MACROS AND DEFINITIONS
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||||
|
be used solely through the macros that make up the public software timer API,
|
||||||
|
as defined below. The commands that are sent from interrupts must use the
|
||||||
|
highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task
|
||||||
|
or interrupt version of the queue send function should be used. */
|
||||||
|
#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 )
|
||||||
|
#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 )
|
||||||
|
#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 )
|
||||||
|
#define tmrCOMMAND_START ( ( BaseType_t ) 1 )
|
||||||
|
#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 )
|
||||||
|
#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 )
|
||||||
|
#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 )
|
||||||
|
#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 )
|
||||||
|
|
||||||
|
#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 )
|
||||||
|
#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 )
|
||||||
|
#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 )
|
||||||
|
#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 )
|
||||||
|
#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
* Type by which software timers are referenced. For example, a call to
|
* Type by which software timers are referenced. For example, a call to
|
||||||
* xTimerCreate() returns an xTimerHandle variable that can then be used to
|
* xTimerCreate() returns an TimerHandle_t variable that can then be used to
|
||||||
* reference the subject timer in calls to other software timer API functions
|
* reference the subject timer in calls to other software timer API functions
|
||||||
* (for example, xTimerStart(), xTimerReset(), etc.).
|
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||||
*/
|
*/
|
||||||
typedef void * xTimerHandle;
|
typedef void * TimerHandle_t;
|
||||||
|
|
||||||
/* Define the prototype to which timer callback functions must conform. */
|
/*
|
||||||
//typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
|
* Defines the prototype to which timer callback functions must conform.
|
||||||
typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer,void *callback_arg ); //modify by dave
|
*/
|
||||||
|
//typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer );
|
||||||
|
typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer, void *callback_arg ); //modify by dave, thanks again dave great job !
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defines the prototype to which functions used with the
|
||||||
|
* xTimerPendFunctionCallFromISR() function must conform.
|
||||||
|
*/
|
||||||
|
typedef void (*PendedFunction_t)( void *, uint32_t );
|
||||||
|
|
||||||
/* The definition of the timers themselves. */
|
/* The definition of the timers themselves. */
|
||||||
typedef struct tmrTimerControl
|
typedef struct tmrTimerControl
|
||||||
{
|
{
|
||||||
const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */
|
const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
|
ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
|
||||||
portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
|
TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
|
||||||
unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */
|
UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */
|
||||||
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
|
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
|
||||||
tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */
|
TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
|
||||||
void *callback_arg; /*added by dave */
|
void *callback_arg; /*added by dave */
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
|
||||||
|
#endif
|
||||||
} xTIMER;
|
} xTIMER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xTimerHandle xTimerCreate( const signed char *pcTimerName,
|
* TimerHandle_t xTimerCreate( const char * const pcTimerName,
|
||||||
* portTickType xTimerPeriod,
|
* TickType_t xTimerPeriodInTicks,
|
||||||
* unsigned portBASE_TYPE uxAutoReload,
|
* UBaseType_t uxAutoReload,
|
||||||
* void * pvTimerID,
|
* void * pvTimerID,
|
||||||
* tmrTIMER_CALLBACK pxCallbackFunction );
|
* TimerCallbackFunction_t pxCallbackFunction );
|
||||||
*
|
*
|
||||||
* Creates a new software timer instance. This allocates the storage required
|
* Creates a new software timer instance. This allocates the storage required
|
||||||
* by the new timer, initialises the new timers internal state, and returns a
|
* by the new timer, initialises the new timers internal state, and returns a
|
||||||
@ -116,23 +153,24 @@ typedef struct tmrTimerControl
|
|||||||
*
|
*
|
||||||
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a
|
||||||
* active state.
|
* timer into the active state.
|
||||||
*
|
*
|
||||||
* @param pcTimerName A text name that is assigned to the timer. This is done
|
* @param pcTimerName A text name that is assigned to the timer. This is done
|
||||||
* purely to assist debugging. The kernel itself only ever references a timer by
|
* purely to assist debugging. The kernel itself only ever references a timer
|
||||||
* its handle, and never by its name.
|
* by its handle, and never by its name.
|
||||||
*
|
*
|
||||||
* @param xTimerPeriod The timer period. The time is defined in tick periods so
|
* @param xTimerPeriodInTicks The timer period. The time is defined in tick
|
||||||
* the constant portTICK_RATE_MS can be used to convert a time that has been
|
* periods so the constant portTICK_PERIOD_MS can be used to convert a time that
|
||||||
* specified in milliseconds. For example, if the timer must expire after 100
|
* has been specified in milliseconds. For example, if the timer must expire
|
||||||
* ticks, then xTimerPeriod should be set to 100. Alternatively, if the timer
|
* after 100 ticks, then xTimerPeriodInTicks should be set to 100.
|
||||||
* must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )
|
* Alternatively, if the timer must expire after 500ms, then xPeriod can be set
|
||||||
* provided configTICK_RATE_HZ is less than or equal to 1000.
|
* to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or
|
||||||
|
* equal to 1000.
|
||||||
*
|
*
|
||||||
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
||||||
* expire repeatedly with a frequency set by the xTimerPeriod parameter. If
|
* expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter.
|
||||||
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
* If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
* enter the dormant state after it expires.
|
* enter the dormant state after it expires.
|
||||||
*
|
*
|
||||||
* @param pvTimerID An identifier that is assigned to the timer being created.
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
@ -141,39 +179,38 @@ typedef struct tmrTimerControl
|
|||||||
* timer.
|
* timer.
|
||||||
*
|
*
|
||||||
* @param pxCallbackFunction The function to call when the timer expires.
|
* @param pxCallbackFunction The function to call when the timer expires.
|
||||||
* Callback functions must have the prototype defined by tmrTIMER_CALLBACK,
|
* Callback functions must have the prototype defined by TimerCallbackFunction_t,
|
||||||
* which is "void vCallbackFunction( xTimerHandle xTimer );".
|
* which is "void vCallbackFunction( TimerHandle_t xTimer );".
|
||||||
*
|
*
|
||||||
* @return If the timer is successfully create then a handle to the newly
|
* @return If the timer is successfully created then a handle to the newly
|
||||||
* created timer is returned. If the timer cannot be created (because either
|
* created timer is returned. If the timer cannot be created (because either
|
||||||
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
||||||
* structures, or the timer period was set to 0) then 0 is returned.
|
* structures, or the timer period was set to 0) then NULL is returned.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
*
|
|
||||||
* #define NUM_TIMERS 5
|
* #define NUM_TIMERS 5
|
||||||
*
|
*
|
||||||
* // An array to hold handles to the created timers.
|
* // An array to hold handles to the created timers.
|
||||||
* xTimerHandle xTimers[ NUM_TIMERS ];
|
* TimerHandle_t xTimers[ NUM_TIMERS ];
|
||||||
*
|
*
|
||||||
* // An array to hold a count of the number of times each timer expires.
|
* // An array to hold a count of the number of times each timer expires.
|
||||||
* long lExpireCounters[ NUM_TIMERS ] = { 0 };
|
* int32_t lExpireCounters[ NUM_TIMERS ] = { 0 };
|
||||||
*
|
*
|
||||||
* // Define a callback function that will be used by multiple timer instances.
|
* // Define a callback function that will be used by multiple timer instances.
|
||||||
* // The callback function does nothing but count the number of times the
|
* // The callback function does nothing but count the number of times the
|
||||||
* // associated timer expires, and stop the timer once the timer has expired
|
* // associated timer expires, and stop the timer once the timer has expired
|
||||||
* // 10 times.
|
* // 10 times.
|
||||||
* void vTimerCallback( xTimerHandle pxTimer )
|
* void vTimerCallback( TimerHandle_t pxTimer )
|
||||||
* {
|
* {
|
||||||
* long lArrayIndex;
|
* int32_t lArrayIndex;
|
||||||
* const long xMaxExpiryCountBeforeStopping = 10;
|
* const int32_t xMaxExpiryCountBeforeStopping = 10;
|
||||||
*
|
*
|
||||||
* // Optionally do something if the pxTimer parameter is NULL.
|
* // Optionally do something if the pxTimer parameter is NULL.
|
||||||
* configASSERT( pxTimer );
|
* configASSERT( pxTimer );
|
||||||
*
|
*
|
||||||
* // Which timer expired?
|
* // Which timer expired?
|
||||||
* lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );
|
* lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );
|
||||||
*
|
*
|
||||||
* // Increment the number of times that pxTimer has expired.
|
* // Increment the number of times that pxTimer has expired.
|
||||||
* lExpireCounters[ lArrayIndex ] += 1;
|
* lExpireCounters[ lArrayIndex ] += 1;
|
||||||
@ -189,18 +226,18 @@ typedef struct tmrTimerControl
|
|||||||
*
|
*
|
||||||
* void main( void )
|
* void main( void )
|
||||||
* {
|
* {
|
||||||
* long x;
|
* int32_t x;
|
||||||
*
|
*
|
||||||
* // Create then start some timers. Starting the timers before the scheduler
|
* // Create then start some timers. Starting the timers before the scheduler
|
||||||
* // has been started means the timers will start running immediately that
|
* // has been started means the timers will start running immediately that
|
||||||
* // the scheduler starts.
|
* // the scheduler starts.
|
||||||
* for( x = 0; x < NUM_TIMERS; x++ )
|
* for( x = 0; x < NUM_TIMERS; x++ )
|
||||||
* {
|
* {
|
||||||
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
||||||
* ( 100 * x ), // The timer period in ticks.
|
* ( 100 * x ), // The timer period in ticks.
|
||||||
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
||||||
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
||||||
* vTimerCallback // Each timer calls the same callback when it expires.
|
* vTimerCallback // Each timer calls the same callback when it expires.
|
||||||
* );
|
* );
|
||||||
*
|
*
|
||||||
* if( xTimers[ x ] == NULL )
|
* if( xTimers[ x ] == NULL )
|
||||||
@ -230,12 +267,12 @@ typedef struct tmrTimerControl
|
|||||||
* // Should not reach here.
|
* // Should not reach here.
|
||||||
* for( ;; );
|
* for( ;; );
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
TimerHandle_t xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
xTimerHandle xTimerCreateExt( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction, void *callback_arg );
|
TimerHandle_t xTimerCreateExt( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction, void *callback_arg ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* void *pvTimerGetTimerID( xTimerHandle xTimer );
|
* void *pvTimerGetTimerID( TimerHandle_t xTimer );
|
||||||
*
|
*
|
||||||
* Returns the ID assigned to the timer.
|
* Returns the ID assigned to the timer.
|
||||||
*
|
*
|
||||||
@ -254,16 +291,16 @@ xTimerHandle xTimerCreateExt( const signed char *pcTimerName, portTickType xTime
|
|||||||
*
|
*
|
||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );
|
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );
|
||||||
*
|
*
|
||||||
* Queries a timer to see if it is active or dormant.
|
* Queries a timer to see if it is active or dormant.
|
||||||
*
|
*
|
||||||
* A timer will be dormant if:
|
* A timer will be dormant if:
|
||||||
* 1) It has been created but not started, or
|
* 1) It has been created but not started, or
|
||||||
* 2) It is an expired on-shot timer that has not been restarted.
|
* 2) It is an expired one-shot timer that has not been restarted.
|
||||||
*
|
*
|
||||||
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
@ -276,9 +313,9 @@ void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
|||||||
* pdFALSE will be returned if the timer is active.
|
* pdFALSE will be returned if the timer is active.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This function assumes xTimer has already been created.
|
* // This function assumes xTimer has already been created.
|
||||||
* void vAFunction( xTimerHandle xTimer )
|
* void vAFunction( TimerHandle_t xTimer )
|
||||||
* {
|
* {
|
||||||
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
* {
|
* {
|
||||||
@ -289,24 +326,27 @@ void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
|||||||
* // xTimer is not active, do something else.
|
* // xTimer is not active, do something else.
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xTimerGetTimerDaemonTaskHandle() is only available if
|
* TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
*
|
||||||
|
* xTimerGetTimerDaemonTaskHandle() is only available if
|
||||||
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
|
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||||
*
|
*
|
||||||
* Simply returns the handle of the timer service/daemon task. It it not valid
|
* Simply returns the handle of the timer service/daemon task. It it not valid
|
||||||
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
||||||
*/
|
*/
|
||||||
xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
TaskHandle_t xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );
|
* BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
*
|
*
|
||||||
* Timer functionality is provided by a timer service/daemon task. Many of the
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
* public FreeRTOS timer API functions send commands to the timer service task
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
* though a queue called the timer command queue. The timer command queue is
|
* through a queue called the timer command queue. The timer command queue is
|
||||||
* private to the kernel itself and is not directly accessible to application
|
* private to the kernel itself and is not directly accessible to application
|
||||||
* code. The length of the timer command queue is set by the
|
* code. The length of the timer command queue is set by the
|
||||||
* configTIMER_QUEUE_LENGTH configuration constant.
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
@ -331,14 +371,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being started/restarted.
|
* @param xTimer The handle of the timer being started/restarted.
|
||||||
*
|
*
|
||||||
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
* @param xTicksToWait Specifies the time, in ticks, that the calling task should
|
||||||
* be held in the Blocked state to wait for the start command to be successfully
|
* be held in the Blocked state to wait for the start command to be successfully
|
||||||
* sent to the timer command queue, should the queue already be full when
|
* sent to the timer command queue, should the queue already be full when
|
||||||
* xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called
|
* xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called
|
||||||
* before the scheduler is started.
|
* before the scheduler is started.
|
||||||
*
|
*
|
||||||
* @return pdFAIL will be returned if the start command could not be sent to
|
* @return pdFAIL will be returned if the start command could not be sent to
|
||||||
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
* the timer command queue even after xTicksToWait ticks had passed. pdPASS will
|
||||||
* be returned if the command was successfully sent to the timer command queue.
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
* When the command is actually processed will depend on the priority of the
|
* When the command is actually processed will depend on the priority of the
|
||||||
* timer service/daemon task relative to other tasks in the system, although the
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
@ -351,14 +391,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );
|
* BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
*
|
*
|
||||||
* Timer functionality is provided by a timer service/daemon task. Many of the
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
* public FreeRTOS timer API functions send commands to the timer service task
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
* though a queue called the timer command queue. The timer command queue is
|
* through a queue called the timer command queue. The timer command queue is
|
||||||
* private to the kernel itself and is not directly accessible to application
|
* private to the kernel itself and is not directly accessible to application
|
||||||
* code. The length of the timer command queue is set by the
|
* code. The length of the timer command queue is set by the
|
||||||
* configTIMER_QUEUE_LENGTH configuration constant.
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
@ -374,14 +414,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being stopped.
|
* @param xTimer The handle of the timer being stopped.
|
||||||
*
|
*
|
||||||
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
* @param xTicksToWait Specifies the time, in ticks, that the calling task should
|
||||||
* be held in the Blocked state to wait for the stop command to be successfully
|
* be held in the Blocked state to wait for the stop command to be successfully
|
||||||
* sent to the timer command queue, should the queue already be full when
|
* sent to the timer command queue, should the queue already be full when
|
||||||
* xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called
|
* xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called
|
||||||
* before the scheduler is started.
|
* before the scheduler is started.
|
||||||
*
|
*
|
||||||
* @return pdFAIL will be returned if the stop command could not be sent to
|
* @return pdFAIL will be returned if the stop command could not be sent to
|
||||||
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
* the timer command queue even after xTicksToWait ticks had passed. pdPASS will
|
||||||
* be returned if the command was successfully sent to the timer command queue.
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
* When the command is actually processed will depend on the priority of the
|
* When the command is actually processed will depend on the priority of the
|
||||||
* timer service/daemon task relative to other tasks in the system. The timer
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
@ -393,16 +433,16 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* See the xTimerCreate() API function example usage scenario.
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )
|
#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,
|
* BaseType_t xTimerChangePeriod( TimerHandle_t xTimer,
|
||||||
* portTickType xNewPeriod,
|
* TickType_t xNewPeriod,
|
||||||
* portTickType xBlockTime );
|
* TickType_t xTicksToWait );
|
||||||
*
|
*
|
||||||
* Timer functionality is provided by a timer service/daemon task. Many of the
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
* public FreeRTOS timer API functions send commands to the timer service task
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
* though a queue called the timer command queue. The timer command queue is
|
* through a queue called the timer command queue. The timer command queue is
|
||||||
* private to the kernel itself and is not directly accessible to application
|
* private to the kernel itself and is not directly accessible to application
|
||||||
* code. The length of the timer command queue is set by the
|
* code. The length of the timer command queue is set by the
|
||||||
* configTIMER_QUEUE_LENGTH configuration constant.
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
@ -419,21 +459,21 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* @param xTimer The handle of the timer that is having its period changed.
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
*
|
*
|
||||||
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time
|
||||||
* that has been specified in milliseconds. For example, if the timer must
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
* ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than
|
||||||
* or equal to 1000.
|
* or equal to 1000.
|
||||||
*
|
*
|
||||||
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
* @param xTicksToWait Specifies the time, in ticks, that the calling task should
|
||||||
* be held in the Blocked state to wait for the change period command to be
|
* be held in the Blocked state to wait for the change period command to be
|
||||||
* successfully sent to the timer command queue, should the queue already be
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
* full when xTimerChangePeriod() was called. xBlockTime is ignored if
|
* full when xTimerChangePeriod() was called. xTicksToWait is ignored if
|
||||||
* xTimerChangePeriod() is called before the scheduler is started.
|
* xTimerChangePeriod() is called before the scheduler is started.
|
||||||
*
|
*
|
||||||
* @return pdFAIL will be returned if the change period command could not be
|
* @return pdFAIL will be returned if the change period command could not be
|
||||||
* sent to the timer command queue even after xBlockTime ticks had passed.
|
* sent to the timer command queue even after xTicksToWait ticks had passed.
|
||||||
* pdPASS will be returned if the command was successfully sent to the timer
|
* pdPASS will be returned if the command was successfully sent to the timer
|
||||||
* command queue. When the command is actually processed will depend on the
|
* command queue. When the command is actually processed will depend on the
|
||||||
* priority of the timer service/daemon task relative to other tasks in the
|
* priority of the timer service/daemon task relative to other tasks in the
|
||||||
@ -441,13 +481,13 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* configTIMER_TASK_PRIORITY configuration constant.
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This function assumes xTimer has already been created. If the timer
|
* // This function assumes xTimer has already been created. If the timer
|
||||||
* // referenced by xTimer is already active when it is called, then the timer
|
* // referenced by xTimer is already active when it is called, then the timer
|
||||||
* // is deleted. If the timer referenced by xTimer is not active when it is
|
* // is deleted. If the timer referenced by xTimer is not active when it is
|
||||||
* // called, then the period of the timer is set to 500ms and the timer is
|
* // called, then the period of the timer is set to 500ms and the timer is
|
||||||
* // started.
|
* // started.
|
||||||
* void vAFunction( xTimerHandle xTimer )
|
* void vAFunction( TimerHandle_t xTimer )
|
||||||
* {
|
* {
|
||||||
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
* {
|
* {
|
||||||
@ -460,7 +500,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* // cause the timer to start. Block for a maximum of 100 ticks if the
|
* // cause the timer to start. Block for a maximum of 100 ticks if the
|
||||||
* // change period command cannot immediately be sent to the timer
|
* // change period command cannot immediately be sent to the timer
|
||||||
* // command queue.
|
* // command queue.
|
||||||
* if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )
|
* if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS )
|
||||||
* {
|
* {
|
||||||
* // The command was successfully sent.
|
* // The command was successfully sent.
|
||||||
* }
|
* }
|
||||||
@ -471,27 +511,16 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )
|
#define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) )
|
||||||
/**
|
|
||||||
* Returns the time in ticks at which the timer will expire. If this is less
|
|
||||||
* than the current tick count then the expiry time has overflowed from the
|
|
||||||
* current time.
|
|
||||||
*
|
|
||||||
* @param xTimer The handle of the timer being queried.
|
|
||||||
*
|
|
||||||
* @return If the timer is running then the time in ticks at which the timer
|
|
||||||
* will next expire is returned. If the timer is not running then the return
|
|
||||||
* value is undefined.
|
|
||||||
*/
|
|
||||||
TickType_t xTimerGetExpiryTime( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );
|
* BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
*
|
*
|
||||||
* Timer functionality is provided by a timer service/daemon task. Many of the
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
* public FreeRTOS timer API functions send commands to the timer service task
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
* though a queue called the timer command queue. The timer command queue is
|
* through a queue called the timer command queue. The timer command queue is
|
||||||
* private to the kernel itself and is not directly accessible to application
|
* private to the kernel itself and is not directly accessible to application
|
||||||
* code. The length of the timer command queue is set by the
|
* code. The length of the timer command queue is set by the
|
||||||
* configTIMER_QUEUE_LENGTH configuration constant.
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
@ -504,14 +533,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being deleted.
|
* @param xTimer The handle of the timer being deleted.
|
||||||
*
|
*
|
||||||
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
* @param xTicksToWait Specifies the time, in ticks, that the calling task should
|
||||||
* be held in the Blocked state to wait for the delete command to be
|
* be held in the Blocked state to wait for the delete command to be
|
||||||
* successfully sent to the timer command queue, should the queue already be
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
* full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()
|
* full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete()
|
||||||
* is called before the scheduler is started.
|
* is called before the scheduler is started.
|
||||||
*
|
*
|
||||||
* @return pdFAIL will be returned if the delete command could not be sent to
|
* @return pdFAIL will be returned if the delete command could not be sent to
|
||||||
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
* the timer command queue even after xTicksToWait ticks had passed. pdPASS will
|
||||||
* be returned if the command was successfully sent to the timer command queue.
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
* When the command is actually processed will depend on the priority of the
|
* When the command is actually processed will depend on the priority of the
|
||||||
* timer service/daemon task relative to other tasks in the system. The timer
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
@ -522,14 +551,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* See the xTimerChangePeriod() API function example usage scenario.
|
* See the xTimerChangePeriod() API function example usage scenario.
|
||||||
*/
|
*/
|
||||||
#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )
|
#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );
|
* BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait );
|
||||||
*
|
*
|
||||||
* Timer functionality is provided by a timer service/daemon task. Many of the
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
* public FreeRTOS timer API functions send commands to the timer service task
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
* though a queue called the timer command queue. The timer command queue is
|
* through a queue called the timer command queue. The timer command queue is
|
||||||
* private to the kernel itself and is not directly accessible to application
|
* private to the kernel itself and is not directly accessible to application
|
||||||
* code. The length of the timer command queue is set by the
|
* code. The length of the timer command queue is set by the
|
||||||
* configTIMER_QUEUE_LENGTH configuration constant.
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
@ -556,14 +585,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* @param xTimer The handle of the timer being reset/started/restarted.
|
* @param xTimer The handle of the timer being reset/started/restarted.
|
||||||
*
|
*
|
||||||
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
* @param xTicksToWait Specifies the time, in ticks, that the calling task should
|
||||||
* be held in the Blocked state to wait for the reset command to be successfully
|
* be held in the Blocked state to wait for the reset command to be successfully
|
||||||
* sent to the timer command queue, should the queue already be full when
|
* sent to the timer command queue, should the queue already be full when
|
||||||
* xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called
|
* xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called
|
||||||
* before the scheduler is started.
|
* before the scheduler is started.
|
||||||
*
|
*
|
||||||
* @return pdFAIL will be returned if the reset command could not be sent to
|
* @return pdFAIL will be returned if the reset command could not be sent to
|
||||||
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
* the timer command queue even after xTicksToWait ticks had passed. pdPASS will
|
||||||
* be returned if the command was successfully sent to the timer command queue.
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
* When the command is actually processed will depend on the priority of the
|
* When the command is actually processed will depend on the priority of the
|
||||||
* timer service/daemon task relative to other tasks in the system, although the
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
@ -572,16 +601,16 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* configuration constant.
|
* configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
* // without a key being pressed, then the LCD back-light is switched off. In
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
* // this case, the timer is a one-shot timer.
|
* // this case, the timer is a one-shot timer.
|
||||||
*
|
*
|
||||||
* xTimerHandle xBacklightTimer = NULL;
|
* TimerHandle_t xBacklightTimer = NULL;
|
||||||
*
|
*
|
||||||
* // The callback function assigned to the one-shot timer. In this case the
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
* // parameter is not used.
|
* // parameter is not used.
|
||||||
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
* void vBacklightTimerCallback( TimerHandle_t pxTimer )
|
||||||
* {
|
* {
|
||||||
* // The timer expired, therefore 5 seconds must have passed since a key
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
* // was pressed. Switch off the LCD back-light.
|
* // was pressed. Switch off the LCD back-light.
|
||||||
@ -607,12 +636,12 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* void main( void )
|
* void main( void )
|
||||||
* {
|
* {
|
||||||
* long x;
|
* int32_t x;
|
||||||
*
|
*
|
||||||
* // Create then start the one-shot timer that is responsible for turning
|
* // Create then start the one-shot timer that is responsible for turning
|
||||||
* // the back-light off if no keys are pressed within a 5 second period.
|
* // the back-light off if no keys are pressed within a 5 second period.
|
||||||
* xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.
|
* xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.
|
||||||
* ( 5000 / portTICK_RATE_MS), // The timer period in ticks.
|
* ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks.
|
||||||
* pdFALSE, // The timer is a one-shot timer.
|
* pdFALSE, // The timer is a one-shot timer.
|
||||||
* 0, // The id is not used by the callback so can take any value.
|
* 0, // The id is not used by the callback so can take any value.
|
||||||
* vBacklightTimerCallback // The callback function that switches the LCD back-light off.
|
* vBacklightTimerCallback // The callback function that switches the LCD back-light off.
|
||||||
@ -644,12 +673,13 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* // Should not reach here.
|
* // Should not reach here.
|
||||||
* for( ;; );
|
* for( ;; );
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,
|
* BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
|
||||||
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
*
|
*
|
||||||
* A version of xTimerStart() that can be called from an interrupt service
|
* A version of xTimerStart() that can be called from an interrupt service
|
||||||
* routine.
|
* routine.
|
||||||
@ -673,11 +703,12 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* successfully sent to the timer command queue. When the command is actually
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
* processed will depend on the priority of the timer service/daemon task
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
* relative to other tasks in the system, although the timers expiry time is
|
* relative to other tasks in the system, although the timers expiry time is
|
||||||
* relative to when xTimerStartFromISR() is actually called. The timer service/daemon
|
* relative to when xTimerStartFromISR() is actually called. The timer
|
||||||
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This scenario assumes xBacklightTimer has already been created. When a
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
* // without a key being pressed, then the LCD back-light is switched off. In
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
@ -687,7 +718,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* // The callback function assigned to the one-shot timer. In this case the
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
* // parameter is not used.
|
* // parameter is not used.
|
||||||
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
* void vBacklightTimerCallback( TimerHandle_t pxTimer )
|
||||||
* {
|
* {
|
||||||
* // The timer expired, therefore 5 seconds must have passed since a key
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
* // was pressed. Switch off the LCD back-light.
|
* // was pressed. Switch off the LCD back-light.
|
||||||
@ -697,7 +728,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* // The key press interrupt service routine.
|
* // The key press interrupt service routine.
|
||||||
* void vKeyPressEventInterruptHandler( void )
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
* {
|
* {
|
||||||
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
*
|
*
|
||||||
* // Ensure the LCD back-light is on, then restart the timer that is
|
* // Ensure the LCD back-light is on, then restart the timer that is
|
||||||
* // responsible for turning the back-light off after 5 seconds of
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
@ -723,17 +754,18 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* // compiler. Inspect the demos for the port you are using to find the
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
* // actual syntax required.
|
* // actual syntax required.
|
||||||
* if( xHigherPriorityTaskWoken != pdFALSE )
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
*
|
* {
|
||||||
* // Call the interrupt safe yield function here (actual function
|
* // Call the interrupt safe yield function here (actual function
|
||||||
* // depends on the FreeRTOS port being used.{
|
* // depends on the FreeRTOS port being used).
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,
|
* BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
|
||||||
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
*
|
*
|
||||||
* A version of xTimerStop() that can be called from an interrupt service
|
* A version of xTimerStop() that can be called from an interrupt service
|
||||||
* routine.
|
* routine.
|
||||||
@ -760,14 +792,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This scenario assumes xTimer has already been created and started. When
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
* // an interrupt occurs, the timer should be simply stopped.
|
* // an interrupt occurs, the timer should be simply stopped.
|
||||||
*
|
*
|
||||||
* // The interrupt service routine that stops the timer.
|
* // The interrupt service routine that stops the timer.
|
||||||
* void vAnExampleInterruptServiceRoutine( void )
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
* {
|
* {
|
||||||
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
*
|
*
|
||||||
* // The interrupt has occurred - simply stop the timer.
|
* // The interrupt has occurred - simply stop the timer.
|
||||||
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
@ -787,16 +819,17 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* if( xHigherPriorityTaskWoken != pdFALSE )
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
* {
|
* {
|
||||||
* // Call the interrupt safe yield function here (actual function
|
* // Call the interrupt safe yield function here (actual function
|
||||||
* // depends on the FreeRTOS port being used.
|
* // depends on the FreeRTOS port being used).
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,
|
* BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer,
|
||||||
* portTickType xNewPeriod,
|
* TickType_t xNewPeriod,
|
||||||
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
*
|
*
|
||||||
* A version of xTimerChangePeriod() that can be called from an interrupt
|
* A version of xTimerChangePeriod() that can be called from an interrupt
|
||||||
* service routine.
|
* service routine.
|
||||||
@ -804,11 +837,11 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* @param xTimer The handle of the timer that is having its period changed.
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
*
|
*
|
||||||
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
* tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time
|
||||||
* that has been specified in milliseconds. For example, if the timer must
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
* ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than
|
||||||
* or equal to 1000.
|
* or equal to 1000.
|
||||||
*
|
*
|
||||||
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
@ -832,14 +865,14 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This scenario assumes xTimer has already been created and started. When
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
|
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
|
||||||
*
|
*
|
||||||
* // The interrupt service routine that changes the period of xTimer.
|
* // The interrupt service routine that changes the period of xTimer.
|
||||||
* void vAnExampleInterruptServiceRoutine( void )
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
* {
|
* {
|
||||||
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
*
|
*
|
||||||
* // The interrupt has occurred - change the period of xTimer to 500ms.
|
* // The interrupt has occurred - change the period of xTimer to 500ms.
|
||||||
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
@ -859,15 +892,16 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* if( xHigherPriorityTaskWoken != pdFALSE )
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
* {
|
* {
|
||||||
* // Call the interrupt safe yield function here (actual function
|
* // Call the interrupt safe yield function here (actual function
|
||||||
* // depends on the FreeRTOS port being used.
|
* // depends on the FreeRTOS port being used).
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,
|
* BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
|
||||||
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
*
|
*
|
||||||
* A version of xTimerReset() that can be called from an interrupt service
|
* A version of xTimerReset() that can be called from an interrupt service
|
||||||
* routine.
|
* routine.
|
||||||
@ -896,7 +930,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
* @verbatim
|
||||||
* // This scenario assumes xBacklightTimer has already been created. When a
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
* // without a key being pressed, then the LCD back-light is switched off. In
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
@ -906,7 +940,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
*
|
*
|
||||||
* // The callback function assigned to the one-shot timer. In this case the
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
* // parameter is not used.
|
* // parameter is not used.
|
||||||
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
* void vBacklightTimerCallback( TimerHandle_t pxTimer )
|
||||||
* {
|
* {
|
||||||
* // The timer expired, therefore 5 seconds must have passed since a key
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
* // was pressed. Switch off the LCD back-light.
|
* // was pressed. Switch off the LCD back-light.
|
||||||
@ -916,7 +950,7 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* // The key press interrupt service routine.
|
* // The key press interrupt service routine.
|
||||||
* void vKeyPressEventInterruptHandler( void )
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
* {
|
* {
|
||||||
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
* BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
*
|
*
|
||||||
* // Ensure the LCD back-light is on, then reset the timer that is
|
* // Ensure the LCD back-light is on, then reset the timer that is
|
||||||
* // responsible for turning the back-light off after 5 seconds of
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
@ -944,18 +978,144 @@ xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
|||||||
* if( xHigherPriorityTaskWoken != pdFALSE )
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
* {
|
* {
|
||||||
* // Call the interrupt safe yield function here (actual function
|
* // Call the interrupt safe yield function here (actual function
|
||||||
* // depends on the FreeRTOS port being used.
|
* // depends on the FreeRTOS port being used).
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
* @endverbatim
|
||||||
*/
|
*/
|
||||||
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend,
|
||||||
|
* void *pvParameter1,
|
||||||
|
* uint32_t ulParameter2,
|
||||||
|
* BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Used from application interrupt service routines to defer the execution of a
|
||||||
|
* function to the RTOS daemon task (the timer service task, hence this function
|
||||||
|
* is implemented in timers.c and is prefixed with 'Timer').
|
||||||
|
*
|
||||||
|
* Ideally an interrupt service routine (ISR) is kept as short as possible, but
|
||||||
|
* sometimes an ISR either has a lot of processing to do, or needs to perform
|
||||||
|
* processing that is not deterministic. In these cases
|
||||||
|
* xTimerPendFunctionCallFromISR() can be used to defer processing of a function
|
||||||
|
* to the RTOS daemon task.
|
||||||
|
*
|
||||||
|
* A mechanism is provided that allows the interrupt to return directly to the
|
||||||
|
* task that will subsequently execute the pended callback function. This
|
||||||
|
* allows the callback function to execute contiguously in time with the
|
||||||
|
* interrupt - just as if the callback had executed in the interrupt itself.
|
||||||
|
*
|
||||||
|
* @param xFunctionToPend The function to execute from the timer service/
|
||||||
|
* daemon task. The function must conform to the PendedFunction_t
|
||||||
|
* prototype.
|
||||||
|
*
|
||||||
|
* @param pvParameter1 The value of the callback function's first parameter.
|
||||||
|
* The parameter has a void * type to allow it to be used to pass any type.
|
||||||
|
* For example, unsigned longs can be cast to a void *, or the void * can be
|
||||||
|
* used to point to a structure.
|
||||||
|
*
|
||||||
|
* @param ulParameter2 The value of the callback function's second parameter.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken As mentioned above, calling this function
|
||||||
|
* will result in a message being sent to the timer daemon task. If the
|
||||||
|
* priority of the timer daemon task (which is set using
|
||||||
|
* configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of
|
||||||
|
* the currently running task (the task the interrupt interrupted) then
|
||||||
|
* *pxHigherPriorityTaskWoken will be set to pdTRUE within
|
||||||
|
* xTimerPendFunctionCallFromISR(), indicating that a context switch should be
|
||||||
|
* requested before the interrupt exits. For that reason
|
||||||
|
* *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the
|
||||||
|
* example code below.
|
||||||
|
*
|
||||||
|
* @return pdPASS is returned if the message was successfully sent to the
|
||||||
|
* timer daemon task, otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
* @verbatim
|
||||||
|
*
|
||||||
|
* // The callback function that will execute in the context of the daemon task.
|
||||||
|
* // Note callback functions must all use this same prototype.
|
||||||
|
* void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 )
|
||||||
|
* {
|
||||||
|
* BaseType_t xInterfaceToService;
|
||||||
|
*
|
||||||
|
* // The interface that requires servicing is passed in the second
|
||||||
|
* // parameter. The first parameter is not used in this case.
|
||||||
|
* xInterfaceToService = ( BaseType_t ) ulParameter2;
|
||||||
|
*
|
||||||
|
* // ...Perform the processing here...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // An ISR that receives data packets from multiple interfaces
|
||||||
|
* void vAnISR( void )
|
||||||
|
* {
|
||||||
|
* BaseType_t xInterfaceToService, xHigherPriorityTaskWoken;
|
||||||
|
*
|
||||||
|
* // Query the hardware to determine which interface needs processing.
|
||||||
|
* xInterfaceToService = prvCheckInterfaces();
|
||||||
|
*
|
||||||
|
* // The actual processing is to be deferred to a task. Request the
|
||||||
|
* // vProcessInterface() callback function is executed, passing in the
|
||||||
|
* // number of the interface that needs processing. The interface to
|
||||||
|
* // service is passed in the second parameter. The first parameter is
|
||||||
|
* // not used in this case.
|
||||||
|
* xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
* xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
|
||||||
|
* // switch should be requested. The macro used is port specific and will
|
||||||
|
* // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to
|
||||||
|
* // the documentation page for the port being used.
|
||||||
|
* portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* @endverbatim
|
||||||
|
*/
|
||||||
|
BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend,
|
||||||
|
* void *pvParameter1,
|
||||||
|
* uint32_t ulParameter2,
|
||||||
|
* TickType_t xTicksToWait );
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Used to defer the execution of a function to the RTOS daemon task (the timer
|
||||||
|
* service task, hence this function is implemented in timers.c and is prefixed
|
||||||
|
* with 'Timer').
|
||||||
|
*
|
||||||
|
* @param xFunctionToPend The function to execute from the timer service/
|
||||||
|
* daemon task. The function must conform to the PendedFunction_t
|
||||||
|
* prototype.
|
||||||
|
*
|
||||||
|
* @param pvParameter1 The value of the callback function's first parameter.
|
||||||
|
* The parameter has a void * type to allow it to be used to pass any type.
|
||||||
|
* For example, unsigned longs can be cast to a void *, or the void * can be
|
||||||
|
* used to point to a structure.
|
||||||
|
*
|
||||||
|
* @param ulParameter2 The value of the callback function's second parameter.
|
||||||
|
*
|
||||||
|
* @param xTicksToWait Calling this function will result in a message being
|
||||||
|
* sent to the timer daemon task on a queue. xTicksToWait is the amount of
|
||||||
|
* time the calling task should remain in the Blocked state (so not using any
|
||||||
|
* processing time) for space to become available on the timer queue if the
|
||||||
|
* queue is found to be full.
|
||||||
|
*
|
||||||
|
* @return pdPASS is returned if the message was successfully sent to the
|
||||||
|
* timer daemon task, otherwise pdFALSE is returned.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions beyond this part are not part of the public API and are intended
|
* Functions beyond this part are not part of the public API and are intended
|
||||||
* for use by the kernel only.
|
* for use by the kernel only.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
|
BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
966
src/os/rtos/include/rtostimers.h.old
Normal file
966
src/os/rtos/include/rtostimers.h.old
Normal file
@ -0,0 +1,966 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TIMERS_H
|
||||||
|
#define TIMERS_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "include FreeRTOS.h must appear in source files before include timers.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "portable.h"
|
||||||
|
#include "rtoslist.h"
|
||||||
|
#include "task.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IDs for commands that can be sent/received on the timer queue. These are to
|
||||||
|
be used solely through the macros that make up the public software timer API,
|
||||||
|
as defined below. */
|
||||||
|
#define tmrCOMMAND_START 0
|
||||||
|
#define tmrCOMMAND_STOP 1
|
||||||
|
#define tmrCOMMAND_CHANGE_PERIOD 2
|
||||||
|
#define tmrCOMMAND_DELETE 3
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* MACROS AND DEFINITIONS
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type by which software timers are referenced. For example, a call to
|
||||||
|
* xTimerCreate() returns an xTimerHandle variable that can then be used to
|
||||||
|
* reference the subject timer in calls to other software timer API functions
|
||||||
|
* (for example, xTimerStart(), xTimerReset(), etc.).
|
||||||
|
*/
|
||||||
|
typedef void * xTimerHandle;
|
||||||
|
|
||||||
|
/* Define the prototype to which timer callback functions must conform. */
|
||||||
|
//typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer );
|
||||||
|
typedef void (*tmrTIMER_CALLBACK)( xTimerHandle xTimer,void *callback_arg ); //modify by dave
|
||||||
|
|
||||||
|
/* The definition of the timers themselves. */
|
||||||
|
typedef struct tmrTimerControl
|
||||||
|
{
|
||||||
|
const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */
|
||||||
|
xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
|
||||||
|
portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
|
||||||
|
unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */
|
||||||
|
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
|
||||||
|
tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */
|
||||||
|
void *callback_arg; /*added by dave */
|
||||||
|
} xTIMER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xTimerHandle xTimerCreate( const signed char *pcTimerName,
|
||||||
|
* portTickType xTimerPeriod,
|
||||||
|
* unsigned portBASE_TYPE uxAutoReload,
|
||||||
|
* void * pvTimerID,
|
||||||
|
* tmrTIMER_CALLBACK pxCallbackFunction );
|
||||||
|
*
|
||||||
|
* Creates a new software timer instance. This allocates the storage required
|
||||||
|
* by the new timer, initialises the new timers internal state, and returns a
|
||||||
|
* handle by which the new timer can be referenced.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
|
||||||
|
* active state.
|
||||||
|
*
|
||||||
|
* @param pcTimerName A text name that is assigned to the timer. This is done
|
||||||
|
* purely to assist debugging. The kernel itself only ever references a timer by
|
||||||
|
* its handle, and never by its name.
|
||||||
|
*
|
||||||
|
* @param xTimerPeriod The timer period. The time is defined in tick periods so
|
||||||
|
* the constant portTICK_RATE_MS can be used to convert a time that has been
|
||||||
|
* specified in milliseconds. For example, if the timer must expire after 100
|
||||||
|
* ticks, then xTimerPeriod should be set to 100. Alternatively, if the timer
|
||||||
|
* must expire after 500ms, then xPeriod can be set to ( 500 / portTICK_RATE_MS )
|
||||||
|
* provided configTICK_RATE_HZ is less than or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will
|
||||||
|
* expire repeatedly with a frequency set by the xTimerPeriod parameter. If
|
||||||
|
* uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and
|
||||||
|
* enter the dormant state after it expires.
|
||||||
|
*
|
||||||
|
* @param pvTimerID An identifier that is assigned to the timer being created.
|
||||||
|
* Typically this would be used in the timer callback function to identify which
|
||||||
|
* timer expired when the same callback function is assigned to more than one
|
||||||
|
* timer.
|
||||||
|
*
|
||||||
|
* @param pxCallbackFunction The function to call when the timer expires.
|
||||||
|
* Callback functions must have the prototype defined by tmrTIMER_CALLBACK,
|
||||||
|
* which is "void vCallbackFunction( xTimerHandle xTimer );".
|
||||||
|
*
|
||||||
|
* @return If the timer is successfully create then a handle to the newly
|
||||||
|
* created timer is returned. If the timer cannot be created (because either
|
||||||
|
* there is insufficient FreeRTOS heap remaining to allocate the timer
|
||||||
|
* structures, or the timer period was set to 0) then 0 is returned.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* #define NUM_TIMERS 5
|
||||||
|
*
|
||||||
|
* // An array to hold handles to the created timers.
|
||||||
|
* xTimerHandle xTimers[ NUM_TIMERS ];
|
||||||
|
*
|
||||||
|
* // An array to hold a count of the number of times each timer expires.
|
||||||
|
* long lExpireCounters[ NUM_TIMERS ] = { 0 };
|
||||||
|
*
|
||||||
|
* // Define a callback function that will be used by multiple timer instances.
|
||||||
|
* // The callback function does nothing but count the number of times the
|
||||||
|
* // associated timer expires, and stop the timer once the timer has expired
|
||||||
|
* // 10 times.
|
||||||
|
* void vTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* long lArrayIndex;
|
||||||
|
* const long xMaxExpiryCountBeforeStopping = 10;
|
||||||
|
*
|
||||||
|
* // Optionally do something if the pxTimer parameter is NULL.
|
||||||
|
* configASSERT( pxTimer );
|
||||||
|
*
|
||||||
|
* // Which timer expired?
|
||||||
|
* lArrayIndex = ( long ) pvTimerGetTimerID( pxTimer );
|
||||||
|
*
|
||||||
|
* // Increment the number of times that pxTimer has expired.
|
||||||
|
* lExpireCounters[ lArrayIndex ] += 1;
|
||||||
|
*
|
||||||
|
* // If the timer has expired 10 times then stop it from running.
|
||||||
|
* if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping )
|
||||||
|
* {
|
||||||
|
* // Do not use a block time if calling a timer API function from a
|
||||||
|
* // timer callback function, as doing so could cause a deadlock!
|
||||||
|
* xTimerStop( pxTimer, 0 );
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* long x;
|
||||||
|
*
|
||||||
|
* // Create then start some timers. Starting the timers before the scheduler
|
||||||
|
* // has been started means the timers will start running immediately that
|
||||||
|
* // the scheduler starts.
|
||||||
|
* for( x = 0; x < NUM_TIMERS; x++ )
|
||||||
|
* {
|
||||||
|
* xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel.
|
||||||
|
* ( 100 * x ), // The timer period in ticks.
|
||||||
|
* pdTRUE, // The timers will auto-reload themselves when they expire.
|
||||||
|
* ( void * ) x, // Assign each timer a unique id equal to its array index.
|
||||||
|
* vTimerCallback // Each timer calls the same callback when it expires.
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* if( xTimers[ x ] == NULL )
|
||||||
|
* {
|
||||||
|
* // The timer was not created.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // Start the timer. No block time is specified, and even if one was
|
||||||
|
* // it would be ignored because the scheduler has not yet been
|
||||||
|
* // started.
|
||||||
|
* if( xTimerStart( xTimers[ x ], 0 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The timer could not be set into the Active state.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timers running as they have already
|
||||||
|
* // been set into the active state.
|
||||||
|
* xTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void * pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction ) PRIVILEGED_FUNCTION;
|
||||||
|
xTimerHandle xTimerCreateExt( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction, void *callback_arg );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* void *pvTimerGetTimerID( xTimerHandle xTimer );
|
||||||
|
*
|
||||||
|
* Returns the ID assigned to the timer.
|
||||||
|
*
|
||||||
|
* IDs are assigned to timers using the pvTimerID parameter of the call to
|
||||||
|
* xTimerCreated() that was used to create the timer.
|
||||||
|
*
|
||||||
|
* If the same callback function is assigned to multiple timers then the timer
|
||||||
|
* ID can be used within the callback function to identify which timer actually
|
||||||
|
* expired.
|
||||||
|
*
|
||||||
|
* @param xTimer The timer being queried.
|
||||||
|
*
|
||||||
|
* @return The ID assigned to the timer being queried.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*/
|
||||||
|
void *pvTimerGetTimerID( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer );
|
||||||
|
*
|
||||||
|
* Queries a timer to see if it is active or dormant.
|
||||||
|
*
|
||||||
|
* A timer will be dormant if:
|
||||||
|
* 1) It has been created but not started, or
|
||||||
|
* 2) It is an expired on-shot timer that has not been restarted.
|
||||||
|
*
|
||||||
|
* Timers are created in the dormant state. The xTimerStart(), xTimerReset(),
|
||||||
|
* xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and
|
||||||
|
* xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the
|
||||||
|
* active state.
|
||||||
|
*
|
||||||
|
* @param xTimer The timer being queried.
|
||||||
|
*
|
||||||
|
* @return pdFALSE will be returned if the timer is dormant. A value other than
|
||||||
|
* pdFALSE will be returned if the timer is active.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This function assumes xTimer has already been created.
|
||||||
|
* void vAFunction( xTimerHandle xTimer )
|
||||||
|
* {
|
||||||
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
|
* {
|
||||||
|
* // xTimer is active, do something.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // xTimer is not active, do something else.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xTimerGetTimerDaemonTaskHandle() is only available if
|
||||||
|
* INCLUDE_xTimerGetTimerDaemonTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||||
|
*
|
||||||
|
* Simply returns the handle of the timer service/daemon task. It it not valid
|
||||||
|
* to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started.
|
||||||
|
*/
|
||||||
|
xTaskHandle xTimerGetTimerDaemonTaskHandle( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStart( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerStart() starts a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function. If the timer had already been started and was
|
||||||
|
* already in the active state, then xTimerStart() has equivalent functionality
|
||||||
|
* to the xTimerReset() API function.
|
||||||
|
*
|
||||||
|
* Starting a timer ensures the timer is in the active state. If the timer
|
||||||
|
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||||
|
* associated with the timer will get called 'n' ticks after xTimerStart() was
|
||||||
|
* called, where 'n' is the timers defined period.
|
||||||
|
*
|
||||||
|
* It is valid to call xTimerStart() before the scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the scheduler is
|
||||||
|
* started, and the timers expiry time will be relative to when the scheduler is
|
||||||
|
* started, not relative to when xTimerStart() was called.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being started/restarted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the start command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerStart() was called. xBlockTime is ignored if xTimerStart() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the start command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
|
* timers expiry time is relative to when xTimerStart() is actually called. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xTimerStart( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStop( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerStop() stops a timer that was previously started using either of the
|
||||||
|
* The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(),
|
||||||
|
* xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions.
|
||||||
|
*
|
||||||
|
* Stopping a timer ensures the timer is not in the active state.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being stopped.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the stop command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerStop() was called. xBlockTime is ignored if xTimerStop() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the stop command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
|
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerCreate() API function example usage scenario.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xTimerStop( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerChangePeriod( xTimerHandle xTimer,
|
||||||
|
* portTickType xNewPeriod,
|
||||||
|
* portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerChangePeriod() changes the period of a timer that was previously
|
||||||
|
* created using the xTimerCreate() API function.
|
||||||
|
*
|
||||||
|
* xTimerChangePeriod() can be called to change the period of an active or
|
||||||
|
* dormant state timer.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for
|
||||||
|
* xTimerChangePeriod() to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
|
*
|
||||||
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
||||||
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
|
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
||||||
|
* or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the change period command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when xTimerChangePeriod() was called. xBlockTime is ignored if
|
||||||
|
* xTimerChangePeriod() is called before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the change period command could not be
|
||||||
|
* sent to the timer command queue even after xBlockTime ticks had passed.
|
||||||
|
* pdPASS will be returned if the command was successfully sent to the timer
|
||||||
|
* command queue. When the command is actually processed will depend on the
|
||||||
|
* priority of the timer service/daemon task relative to other tasks in the
|
||||||
|
* system. The timer service/daemon task priority is set by the
|
||||||
|
* configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This function assumes xTimer has already been created. If the timer
|
||||||
|
* // referenced by xTimer is already active when it is called, then the timer
|
||||||
|
* // is deleted. If the timer referenced by xTimer is not active when it is
|
||||||
|
* // called, then the period of the timer is set to 500ms and the timer is
|
||||||
|
* // started.
|
||||||
|
* void vAFunction( xTimerHandle xTimer )
|
||||||
|
* {
|
||||||
|
* if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )"
|
||||||
|
* {
|
||||||
|
* // xTimer is already active - delete it.
|
||||||
|
* xTimerDelete( xTimer );
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // xTimer is not active, change its period to 500ms. This will also
|
||||||
|
* // cause the timer to start. Block for a maximum of 100 ticks if the
|
||||||
|
* // change period command cannot immediately be sent to the timer
|
||||||
|
* // command queue.
|
||||||
|
* if( xTimerChangePeriod( xTimer, 500 / portTICK_RATE_MS, 100 ) == pdPASS )
|
||||||
|
* {
|
||||||
|
* // The command was successfully sent.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // The command could not be sent, even after waiting for 100 ticks
|
||||||
|
* // to pass. Take appropriate action here.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerChangePeriod( xTimer, xNewPeriod, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xBlockTime ) )
|
||||||
|
/**
|
||||||
|
* Returns the time in ticks at which the timer will expire. If this is less
|
||||||
|
* than the current tick count then the expiry time has overflowed from the
|
||||||
|
* current time.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being queried.
|
||||||
|
*
|
||||||
|
* @return If the timer is running then the time in ticks at which the timer
|
||||||
|
* will next expire is returned. If the timer is not running then the return
|
||||||
|
* value is undefined.
|
||||||
|
*/
|
||||||
|
TickType_t xTimerGetExpiryTime( xTimerHandle xTimer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerDelete( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerDelete() deletes a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for
|
||||||
|
* xTimerDelete() to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being deleted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the delete command to be
|
||||||
|
* successfully sent to the timer command queue, should the queue already be
|
||||||
|
* full when xTimerDelete() was called. xBlockTime is ignored if xTimerDelete()
|
||||||
|
* is called before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the delete command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system. The timer
|
||||||
|
* service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* See the xTimerChangePeriod() API function example usage scenario.
|
||||||
|
*/
|
||||||
|
#define xTimerDelete( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerReset( xTimerHandle xTimer, portTickType xBlockTime );
|
||||||
|
*
|
||||||
|
* Timer functionality is provided by a timer service/daemon task. Many of the
|
||||||
|
* public FreeRTOS timer API functions send commands to the timer service task
|
||||||
|
* though a queue called the timer command queue. The timer command queue is
|
||||||
|
* private to the kernel itself and is not directly accessible to application
|
||||||
|
* code. The length of the timer command queue is set by the
|
||||||
|
* configTIMER_QUEUE_LENGTH configuration constant.
|
||||||
|
*
|
||||||
|
* xTimerReset() re-starts a timer that was previously created using the
|
||||||
|
* xTimerCreate() API function. If the timer had already been started and was
|
||||||
|
* already in the active state, then xTimerReset() will cause the timer to
|
||||||
|
* re-evaluate its expiry time so that it is relative to when xTimerReset() was
|
||||||
|
* called. If the timer was in the dormant state then xTimerReset() has
|
||||||
|
* equivalent functionality to the xTimerStart() API function.
|
||||||
|
*
|
||||||
|
* Resetting a timer ensures the timer is in the active state. If the timer
|
||||||
|
* is not stopped, deleted, or reset in the mean time, the callback function
|
||||||
|
* associated with the timer will get called 'n' ticks after xTimerReset() was
|
||||||
|
* called, where 'n' is the timers defined period.
|
||||||
|
*
|
||||||
|
* It is valid to call xTimerReset() before the scheduler has been started, but
|
||||||
|
* when this is done the timer will not actually start until the scheduler is
|
||||||
|
* started, and the timers expiry time will be relative to when the scheduler is
|
||||||
|
* started, not relative to when xTimerReset() was called.
|
||||||
|
*
|
||||||
|
* The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset()
|
||||||
|
* to be available.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being reset/started/restarted.
|
||||||
|
*
|
||||||
|
* @param xBlockTime Specifies the time, in ticks, that the calling task should
|
||||||
|
* be held in the Blocked state to wait for the reset command to be successfully
|
||||||
|
* sent to the timer command queue, should the queue already be full when
|
||||||
|
* xTimerReset() was called. xBlockTime is ignored if xTimerReset() is called
|
||||||
|
* before the scheduler is started.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the reset command could not be sent to
|
||||||
|
* the timer command queue even after xBlockTime ticks had passed. pdPASS will
|
||||||
|
* be returned if the command was successfully sent to the timer command queue.
|
||||||
|
* When the command is actually processed will depend on the priority of the
|
||||||
|
* timer service/daemon task relative to other tasks in the system, although the
|
||||||
|
* timers expiry time is relative to when xTimerStart() is actually called. The
|
||||||
|
* timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY
|
||||||
|
* configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer.
|
||||||
|
*
|
||||||
|
* xTimerHandle xBacklightTimer = NULL;
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press event handler.
|
||||||
|
* void vKeyPressEventHandler( char cKey )
|
||||||
|
* {
|
||||||
|
* // Ensure the LCD back-light is on, then reset the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. Wait 10 ticks for the command to be successfully sent
|
||||||
|
* // if it cannot be sent immediately.
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
* if( xTimerReset( xBacklightTimer, 100 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The reset command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void main( void )
|
||||||
|
* {
|
||||||
|
* long x;
|
||||||
|
*
|
||||||
|
* // Create then start the one-shot timer that is responsible for turning
|
||||||
|
* // the back-light off if no keys are pressed within a 5 second period.
|
||||||
|
* xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel.
|
||||||
|
* ( 5000 / portTICK_RATE_MS), // The timer period in ticks.
|
||||||
|
* pdFALSE, // The timer is a one-shot timer.
|
||||||
|
* 0, // The id is not used by the callback so can take any value.
|
||||||
|
* vBacklightTimerCallback // The callback function that switches the LCD back-light off.
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* if( xBacklightTimer == NULL )
|
||||||
|
* {
|
||||||
|
* // The timer was not created.
|
||||||
|
* }
|
||||||
|
* else
|
||||||
|
* {
|
||||||
|
* // Start the timer. No block time is specified, and even if one was
|
||||||
|
* // it would be ignored because the scheduler has not yet been
|
||||||
|
* // started.
|
||||||
|
* if( xTimerStart( xBacklightTimer, 0 ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The timer could not be set into the Active state.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* // Create tasks here.
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* // Starting the scheduler will start the timer running as it has already
|
||||||
|
* // been set into the active state.
|
||||||
|
* xTaskStartScheduler();
|
||||||
|
*
|
||||||
|
* // Should not reach here.
|
||||||
|
* for( ;; );
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerReset( xTimer, xBlockTime ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xBlockTime ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStartFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerStart() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being started/restarted.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerStartFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerStartFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerStartFromISR() function. If
|
||||||
|
* xTimerStartFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the start command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system, although the timers expiry time is
|
||||||
|
* relative to when xTimerStartFromISR() is actually called. The timer service/daemon
|
||||||
|
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer, and unlike the example given for
|
||||||
|
* // the xTimerReset() function, the key press event handler is an interrupt
|
||||||
|
* // service routine.
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press interrupt service routine.
|
||||||
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // Ensure the LCD back-light is on, then restart the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. This is an interrupt service routine so can only
|
||||||
|
* // call FreeRTOS API functions that end in "FromISR".
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
*
|
||||||
|
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
|
||||||
|
* // as both cause the timer to re-calculate its expiry time.
|
||||||
|
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
|
||||||
|
* // declared (in this function).
|
||||||
|
* if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The start command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
*
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.{
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerStopFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerStop() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer being stopped.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerStopFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerStopFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerStopFromISR() function. If
|
||||||
|
* xTimerStopFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the stop command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system. The timer service/daemon task
|
||||||
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
|
* // an interrupt occurs, the timer should be simply stopped.
|
||||||
|
*
|
||||||
|
* // The interrupt service routine that stops the timer.
|
||||||
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // The interrupt has occurred - simply stop the timer.
|
||||||
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
|
* // (within this function). As this is an interrupt service routine, only
|
||||||
|
* // FreeRTOS API functions that end in "FromISR" can be used.
|
||||||
|
* if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The stop command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0, ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerChangePeriodFromISR( xTimerHandle xTimer,
|
||||||
|
* portTickType xNewPeriod,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerChangePeriod() that can be called from an interrupt
|
||||||
|
* service routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is having its period changed.
|
||||||
|
*
|
||||||
|
* @param xNewPeriod The new period for xTimer. Timer periods are specified in
|
||||||
|
* tick periods, so the constant portTICK_RATE_MS can be used to convert a time
|
||||||
|
* that has been specified in milliseconds. For example, if the timer must
|
||||||
|
* expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively,
|
||||||
|
* if the timer must expire after 500ms, then xNewPeriod can be set to
|
||||||
|
* ( 500 / portTICK_RATE_MS ) provided configTICK_RATE_HZ is less than
|
||||||
|
* or equal to 1000.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerChangePeriodFromISR() writes a message to the
|
||||||
|
* timer command queue, so has the potential to transition the timer service/
|
||||||
|
* daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR()
|
||||||
|
* causes the timer service/daemon task to leave the Blocked state, and the
|
||||||
|
* timer service/daemon task has a priority equal to or greater than the
|
||||||
|
* currently executing task (the task that was interrupted), then
|
||||||
|
* *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the
|
||||||
|
* xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets
|
||||||
|
* this value to pdTRUE then a context switch should be performed before the
|
||||||
|
* interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the command to change the timers period
|
||||||
|
* could not be sent to the timer command queue. pdPASS will be returned if the
|
||||||
|
* command was successfully sent to the timer command queue. When the command
|
||||||
|
* is actually processed will depend on the priority of the timer service/daemon
|
||||||
|
* task relative to other tasks in the system. The timer service/daemon task
|
||||||
|
* priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xTimer has already been created and started. When
|
||||||
|
* // an interrupt occurs, the period of xTimer should be changed to 500ms.
|
||||||
|
*
|
||||||
|
* // The interrupt service routine that changes the period of xTimer.
|
||||||
|
* void vAnExampleInterruptServiceRoutine( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // The interrupt has occurred - change the period of xTimer to 500ms.
|
||||||
|
* // xHigherPriorityTaskWoken was set to pdFALSE where it was defined
|
||||||
|
* // (within this function). As this is an interrupt service routine, only
|
||||||
|
* // FreeRTOS API functions that end in "FromISR" can be used.
|
||||||
|
* if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The command to change the timers period was not executed
|
||||||
|
* // successfully. Take appropriate action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* portBASE_TYPE xTimerResetFromISR( xTimerHandle xTimer,
|
||||||
|
* portBASE_TYPE *pxHigherPriorityTaskWoken );
|
||||||
|
*
|
||||||
|
* A version of xTimerReset() that can be called from an interrupt service
|
||||||
|
* routine.
|
||||||
|
*
|
||||||
|
* @param xTimer The handle of the timer that is to be started, reset, or
|
||||||
|
* restarted.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken The timer service/daemon task spends most
|
||||||
|
* of its time in the Blocked state, waiting for messages to arrive on the timer
|
||||||
|
* command queue. Calling xTimerResetFromISR() writes a message to the timer
|
||||||
|
* command queue, so has the potential to transition the timer service/daemon
|
||||||
|
* task out of the Blocked state. If calling xTimerResetFromISR() causes the
|
||||||
|
* timer service/daemon task to leave the Blocked state, and the timer service/
|
||||||
|
* daemon task has a priority equal to or greater than the currently executing
|
||||||
|
* task (the task that was interrupted), then *pxHigherPriorityTaskWoken will
|
||||||
|
* get set to pdTRUE internally within the xTimerResetFromISR() function. If
|
||||||
|
* xTimerResetFromISR() sets this value to pdTRUE then a context switch should
|
||||||
|
* be performed before the interrupt exits.
|
||||||
|
*
|
||||||
|
* @return pdFAIL will be returned if the reset command could not be sent to
|
||||||
|
* the timer command queue. pdPASS will be returned if the command was
|
||||||
|
* successfully sent to the timer command queue. When the command is actually
|
||||||
|
* processed will depend on the priority of the timer service/daemon task
|
||||||
|
* relative to other tasks in the system, although the timers expiry time is
|
||||||
|
* relative to when xTimerResetFromISR() is actually called. The timer service/daemon
|
||||||
|
* task priority is set by the configTIMER_TASK_PRIORITY configuration constant.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
*
|
||||||
|
* // This scenario assumes xBacklightTimer has already been created. When a
|
||||||
|
* // key is pressed, an LCD back-light is switched on. If 5 seconds pass
|
||||||
|
* // without a key being pressed, then the LCD back-light is switched off. In
|
||||||
|
* // this case, the timer is a one-shot timer, and unlike the example given for
|
||||||
|
* // the xTimerReset() function, the key press event handler is an interrupt
|
||||||
|
* // service routine.
|
||||||
|
*
|
||||||
|
* // The callback function assigned to the one-shot timer. In this case the
|
||||||
|
* // parameter is not used.
|
||||||
|
* void vBacklightTimerCallback( xTimerHandle pxTimer )
|
||||||
|
* {
|
||||||
|
* // The timer expired, therefore 5 seconds must have passed since a key
|
||||||
|
* // was pressed. Switch off the LCD back-light.
|
||||||
|
* vSetBacklightState( BACKLIGHT_OFF );
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // The key press interrupt service routine.
|
||||||
|
* void vKeyPressEventInterruptHandler( void )
|
||||||
|
* {
|
||||||
|
* portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
*
|
||||||
|
* // Ensure the LCD back-light is on, then reset the timer that is
|
||||||
|
* // responsible for turning the back-light off after 5 seconds of
|
||||||
|
* // key inactivity. This is an interrupt service routine so can only
|
||||||
|
* // call FreeRTOS API functions that end in "FromISR".
|
||||||
|
* vSetBacklightState( BACKLIGHT_ON );
|
||||||
|
*
|
||||||
|
* // xTimerStartFromISR() or xTimerResetFromISR() could be called here
|
||||||
|
* // as both cause the timer to re-calculate its expiry time.
|
||||||
|
* // xHigherPriorityTaskWoken was initialised to pdFALSE when it was
|
||||||
|
* // declared (in this function).
|
||||||
|
* if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS )
|
||||||
|
* {
|
||||||
|
* // The reset command was not executed successfully. Take appropriate
|
||||||
|
* // action here.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // Perform the rest of the key processing here.
|
||||||
|
*
|
||||||
|
* // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch
|
||||||
|
* // should be performed. The syntax required to perform a context switch
|
||||||
|
* // from inside an ISR varies from port to port, and from compiler to
|
||||||
|
* // compiler. Inspect the demos for the port you are using to find the
|
||||||
|
* // actual syntax required.
|
||||||
|
* if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
* {
|
||||||
|
* // Call the interrupt safe yield function here (actual function
|
||||||
|
* // depends on the FreeRTOS port being used.
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Functions beyond this part are not part of the public API and are intended
|
||||||
|
* for use by the kernel only.
|
||||||
|
*/
|
||||||
|
portBASE_TYPE xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION;
|
||||||
|
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* TIMERS_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,75 +1,94 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SEMAPHORE_H
|
#ifndef SEMAPHORE_H
|
||||||
#define SEMAPHORE_H
|
#define SEMAPHORE_H
|
||||||
|
|
||||||
#ifndef INC_FREERTOS_H
|
#ifndef INC_FREERTOS_H
|
||||||
#error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
|
#error "include FreeRTOS.h" must appear in source files before "include semphr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "rtosqueue.h"
|
#include "rtosqueue.h"
|
||||||
|
|
||||||
typedef xQueueHandle xSemaphoreHandle;
|
typedef QueueHandle_t SemaphoreHandle_t;
|
||||||
|
|
||||||
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )
|
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U )
|
||||||
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )
|
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
|
||||||
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )
|
#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
|
* <pre>vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )</pre>
|
||||||
|
*
|
||||||
|
* This old vSemaphoreCreateBinary() macro is now deprecated in favour of the
|
||||||
|
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
||||||
|
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
||||||
|
* first call to 'take' the semaphore would pass, whereas binary semaphores
|
||||||
|
* created using xSemaphoreCreateBinary() are created in a state such that the
|
||||||
|
* the semaphore must first be 'given' before it can be 'taken'.
|
||||||
*
|
*
|
||||||
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
|
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
|
||||||
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
||||||
@ -83,11 +102,11 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* semaphore does not use a priority inheritance mechanism. For an alternative
|
* semaphore does not use a priority inheritance mechanism. For an alternative
|
||||||
* that does use priority inheritance see xSemaphoreCreateMutex().
|
* that does use priority inheritance see xSemaphoreCreateMutex().
|
||||||
*
|
*
|
||||||
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
|
* @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore;
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
@ -98,26 +117,74 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xSemaphore != NULL )
|
if( xSemaphore != NULL )
|
||||||
{
|
{
|
||||||
// The semaphore was created successfully.
|
// The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
// The semaphore can now be used.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define vSemaphoreCreateBinary( xSemaphore ) { \
|
#define vSemaphoreCreateBinary( xSemaphore ) \
|
||||||
( xSemaphore ) = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
|
{ \
|
||||||
if( ( xSemaphore ) != NULL ) \
|
( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \
|
||||||
{ \
|
if( ( xSemaphore ) != NULL ) \
|
||||||
xSemaphoreGive( ( xSemaphore ) ); \
|
{ \
|
||||||
} \
|
( void ) xSemaphoreGive( ( xSemaphore ) ); \
|
||||||
}
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreTake(
|
* <pre>SemaphoreHandle_t xSemaphoreCreateBinary( void )</pre>
|
||||||
* xSemaphoreHandle xSemaphore,
|
*
|
||||||
* portTickType xBlockTime
|
* The old vSemaphoreCreateBinary() macro is now deprecated in favour of this
|
||||||
|
* xSemaphoreCreateBinary() function. Note that binary semaphores created using
|
||||||
|
* the vSemaphoreCreateBinary() macro are created in a state such that the
|
||||||
|
* first call to 'take' the semaphore would pass, whereas binary semaphores
|
||||||
|
* created using xSemaphoreCreateBinary() are created in a state such that the
|
||||||
|
* the semaphore must first be 'given' before it can be 'taken'.
|
||||||
|
*
|
||||||
|
* Function that creates a semaphore by using the existing queue mechanism.
|
||||||
|
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
||||||
|
* as nothing is actually stored - all that is important is whether the queue is
|
||||||
|
* empty or full (the binary semaphore is available or not).
|
||||||
|
*
|
||||||
|
* This type of semaphore can be used for pure synchronisation between tasks or
|
||||||
|
* between an interrupt and a task. The semaphore need not be given back once
|
||||||
|
* obtained, so one task/interrupt can continuously 'give' the semaphore while
|
||||||
|
* another continuously 'takes' the semaphore. For this reason this type of
|
||||||
|
* semaphore does not use a priority inheritance mechanism. For an alternative
|
||||||
|
* that does use priority inheritance see xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* @return Handle to the created semaphore.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
xSemaphore = xSemaphoreCreateBinary();
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreTake(
|
||||||
|
* SemaphoreHandle_t xSemaphore,
|
||||||
|
* TickType_t xBlockTime
|
||||||
* )</pre>
|
* )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
|
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
|
||||||
@ -128,7 +195,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* the semaphore was created.
|
* the semaphore was created.
|
||||||
*
|
*
|
||||||
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||||
* real time. A block time of zero can be used to poll the semaphore. A block
|
* real time. A block time of zero can be used to poll the semaphore. A block
|
||||||
* time of portMAX_DELAY can be used to block indefinitely (provided
|
* time of portMAX_DELAY can be used to block indefinitely (provided
|
||||||
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
|
||||||
@ -138,7 +205,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore = NULL;
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
// A task that creates a semaphore.
|
// A task that creates a semaphore.
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
@ -155,15 +222,15 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xSemaphore != NULL )
|
if( xSemaphore != NULL )
|
||||||
{
|
{
|
||||||
// See if we can obtain the semaphore. If the semaphore is not available
|
// See if we can obtain the semaphore. If the semaphore is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
// wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
{
|
||||||
// We were able to obtain the semaphore and can now access the
|
// We were able to obtain the semaphore and can now access the
|
||||||
// shared resource.
|
// shared resource.
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
// We have finished accessing the shared resource. Release the
|
// We have finished accessing the shared resource. Release the
|
||||||
// semaphore.
|
// semaphore.
|
||||||
xSemaphoreGive( xSemaphore );
|
xSemaphoreGive( xSemaphore );
|
||||||
}
|
}
|
||||||
@ -178,30 +245,28 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* \defgroup xSemaphoreTake xSemaphoreTake
|
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* xSemaphoreTakeRecursive(
|
* xSemaphoreTakeRecursive(
|
||||||
* xSemaphoreHandle xMutex,
|
* SemaphoreHandle_t xMutex,
|
||||||
* portTickType xBlockTime
|
* TickType_t xBlockTime
|
||||||
* )
|
* )
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
|
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
|
||||||
* The mutex must have previously been created using a call to
|
* The mutex must have previously been created using a call to
|
||||||
* xSemaphoreCreateRecursiveMutex();
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
*
|
*
|
||||||
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
* macro to be available.
|
* macro to be available.
|
||||||
*
|
*
|
||||||
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
*
|
*
|
||||||
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
* doesn't become available again until the owner has called
|
* doesn't become available again until the owner has called
|
||||||
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
* not be available to any other task until it has also 'given' the mutex back
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
* exactly five times.
|
* exactly five times.
|
||||||
*
|
*
|
||||||
@ -209,17 +274,17 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* handle returned by xSemaphoreCreateRecursiveMutex();
|
* handle returned by xSemaphoreCreateRecursiveMutex();
|
||||||
*
|
*
|
||||||
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
* available. The macro portTICK_PERIOD_MS can be used to convert this to a
|
||||||
* real time. A block time of zero can be used to poll the semaphore. If
|
* real time. A block time of zero can be used to poll the semaphore. If
|
||||||
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
|
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
|
||||||
* return immediately no matter what the value of xBlockTime.
|
* return immediately no matter what the value of xBlockTime.
|
||||||
*
|
*
|
||||||
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
|
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
|
||||||
* expired without the semaphore becoming available.
|
* expired without the semaphore becoming available.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xMutex = NULL;
|
SemaphoreHandle_t xMutex = NULL;
|
||||||
|
|
||||||
// A task that creates a mutex.
|
// A task that creates a mutex.
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
@ -236,22 +301,22 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xMutex != NULL )
|
if( xMutex != NULL )
|
||||||
{
|
{
|
||||||
// See if we can obtain the mutex. If the mutex is not available
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
// wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
{
|
||||||
// We were able to obtain the mutex and can now access the
|
// We were able to obtain the mutex and can now access the
|
||||||
// shared resource.
|
// shared resource.
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
// For some reason due to the nature of the code further calls to
|
// For some reason due to the nature of the code further calls to
|
||||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
// code these would not be just sequential calls as this would make
|
// code these would not be just sequential calls as this would make
|
||||||
// no sense. Instead the calls are likely to be buried inside
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
// a more complex call structure.
|
// a more complex call structure.
|
||||||
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
|
|
||||||
// The mutex has now been 'taken' three times, so will not be
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
// available to another task until it has also been given back
|
// available to another task until it has also been given back
|
||||||
// three times. Again it is unlikely that real code would have
|
// three times. Again it is unlikely that real code would have
|
||||||
// these calls sequentially, but instead buried in a more complex
|
// these calls sequentially, but instead buried in a more complex
|
||||||
@ -276,23 +341,23 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
|
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
|
||||||
*
|
*
|
||||||
* The source code that implements the alternative (Alt) API is much
|
* The source code that implements the alternative (Alt) API is much
|
||||||
* simpler because it executes everything from within a critical section.
|
* simpler because it executes everything from within a critical section.
|
||||||
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
* preferred fully featured API too. The fully featured API has more
|
* preferred fully featured API too. The fully featured API has more
|
||||||
* complex code that takes longer to execute, but makes much less use of
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
* critical sections. Therefore the alternative API sacrifices interrupt
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
* responsiveness to gain execution speed, whereas the fully featured API
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
* sacrifices execution speed to ensure better interrupt responsiveness.
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
|
* <pre>xSemaphoreGive( SemaphoreHandle_t xSemaphore )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
||||||
@ -301,7 +366,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
|
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
|
||||||
* an alternative which can be used from an ISR.
|
* an alternative which can be used from an ISR.
|
||||||
*
|
*
|
||||||
* This macro must also not be used on semaphores created using
|
* This macro must also not be used on semaphores created using
|
||||||
* xSemaphoreCreateRecursiveMutex().
|
* xSemaphoreCreateRecursiveMutex().
|
||||||
*
|
*
|
||||||
* @param xSemaphore A handle to the semaphore being released. This is the
|
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||||
@ -309,12 +374,12 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
*
|
*
|
||||||
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
|
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
|
||||||
* Semaphores are implemented using queues. An error can occur if there is
|
* Semaphores are implemented using queues. An error can occur if there is
|
||||||
* no space on the queue to post a message - indicating that the
|
* no space on the queue to post a message - indicating that the
|
||||||
* semaphore was not first obtained correctly.
|
* semaphore was not first obtained correctly.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore = NULL;
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
@ -331,7 +396,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
|
|
||||||
// Obtain the semaphore - don't block if the semaphore is not
|
// Obtain the semaphore - don't block if the semaphore is not
|
||||||
// immediately available.
|
// immediately available.
|
||||||
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
|
if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
|
||||||
{
|
{
|
||||||
// We now have the semaphore and can access the shared resource.
|
// We now have the semaphore and can access the shared resource.
|
||||||
|
|
||||||
@ -351,37 +416,25 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* \defgroup xSemaphoreGive xSemaphoreGive
|
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
/**
|
|
||||||
* semphr.h
|
|
||||||
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>
|
|
||||||
*
|
|
||||||
* If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
|
|
||||||
* its current count value. If the semaphore is a binary semaphore then
|
|
||||||
* uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
|
|
||||||
* semaphore is not available.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define xSemaphoreGetCount( xSemaphore ) xQueueMessagesWaiting( ( xQueueHandle ) ( xSemaphore ) )
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
|
* <pre>xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
|
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
|
||||||
* The mutex must have previously been created using a call to
|
* The mutex must have previously been created using a call to
|
||||||
* xSemaphoreCreateRecursiveMutex();
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
*
|
*
|
||||||
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
* macro to be available.
|
* macro to be available.
|
||||||
*
|
*
|
||||||
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
*
|
*
|
||||||
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
* doesn't become available again until the owner has called
|
* doesn't become available again until the owner has called
|
||||||
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
* not be available to any other task until it has also 'given' the mutex back
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
* exactly five times.
|
* exactly five times.
|
||||||
*
|
*
|
||||||
@ -392,7 +445,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xMutex = NULL;
|
SemaphoreHandle_t xMutex = NULL;
|
||||||
|
|
||||||
// A task that creates a mutex.
|
// A task that creates a mutex.
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
@ -409,22 +462,22 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xMutex != NULL )
|
if( xMutex != NULL )
|
||||||
{
|
{
|
||||||
// See if we can obtain the mutex. If the mutex is not available
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
// wait 10 ticks to see if it becomes free.
|
// wait 10 ticks to see if it becomes free.
|
||||||
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
|
if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
|
||||||
{
|
{
|
||||||
// We were able to obtain the mutex and can now access the
|
// We were able to obtain the mutex and can now access the
|
||||||
// shared resource.
|
// shared resource.
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
// For some reason due to the nature of the code further calls to
|
// For some reason due to the nature of the code further calls to
|
||||||
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
// code these would not be just sequential calls as this would make
|
// code these would not be just sequential calls as this would make
|
||||||
// no sense. Instead the calls are likely to be buried inside
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
// a more complex call structure.
|
// a more complex call structure.
|
||||||
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
|
||||||
|
|
||||||
// The mutex has now been 'taken' three times, so will not be
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
// available to another task until it has also been given back
|
// available to another task until it has also been given back
|
||||||
// three times. Again it is unlikely that real code would have
|
// three times. Again it is unlikely that real code would have
|
||||||
// these calls sequentially, it would be more likely that the calls
|
// these calls sequentially, it would be more likely that the calls
|
||||||
@ -449,26 +502,26 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
*/
|
*/
|
||||||
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
|
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
|
||||||
*
|
*
|
||||||
* The source code that implements the alternative (Alt) API is much
|
* The source code that implements the alternative (Alt) API is much
|
||||||
* simpler because it executes everything from within a critical section.
|
* simpler because it executes everything from within a critical section.
|
||||||
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
* preferred fully featured API too. The fully featured API has more
|
* preferred fully featured API too. The fully featured API has more
|
||||||
* complex code that takes longer to execute, but makes much less use of
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
* critical sections. Therefore the alternative API sacrifices interrupt
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
* responsiveness to gain execution speed, whereas the fully featured API
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
* sacrifices execution speed to ensure better interrupt responsiveness.
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>
|
* <pre>
|
||||||
xSemaphoreGiveFromISR(
|
xSemaphoreGiveFromISR(
|
||||||
xSemaphoreHandle xSemaphore,
|
SemaphoreHandle_t xSemaphore,
|
||||||
signed portBASE_TYPE *pxHigherPriorityTaskWoken
|
BaseType_t *pxHigherPriorityTaskWoken
|
||||||
)</pre>
|
)</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
@ -494,14 +547,14 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
<pre>
|
<pre>
|
||||||
\#define LONG_TIME 0xffff
|
\#define LONG_TIME 0xffff
|
||||||
\#define TICKS_TO_WAIT 10
|
\#define TICKS_TO_WAIT 10
|
||||||
xSemaphoreHandle xSemaphore = NULL;
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
// Repetitive task.
|
// Repetitive task.
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
// We want this task to run every 10 ticks of a timer. The semaphore
|
// We want this task to run every 10 ticks of a timer. The semaphore
|
||||||
// was created before this task was started.
|
// was created before this task was started.
|
||||||
|
|
||||||
// Block waiting for the semaphore to become available.
|
// Block waiting for the semaphore to become available.
|
||||||
@ -512,7 +565,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
// ...
|
// ...
|
||||||
|
|
||||||
// We have finished our task. Return to the top of the loop where
|
// We have finished our task. Return to the top of the loop where
|
||||||
// we will block on the semaphore until it is time to execute
|
// we will block on the semaphore until it is time to execute
|
||||||
// again. Note when using the semaphore for synchronisation with an
|
// again. Note when using the semaphore for synchronisation with an
|
||||||
// ISR in this manner there is no need to 'give' the semaphore back.
|
// ISR in this manner there is no need to 'give' the semaphore back.
|
||||||
}
|
}
|
||||||
@ -522,8 +575,8 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
// Timer ISR
|
// Timer ISR
|
||||||
void vTimerISR( void * pvParameters )
|
void vTimerISR( void * pvParameters )
|
||||||
{
|
{
|
||||||
static unsigned char ucLocalTickCount = 0;
|
static uint8_t ucLocalTickCount = 0;
|
||||||
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
static BaseType_t xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
// A timer tick has occurred.
|
// A timer tick has occurred.
|
||||||
|
|
||||||
@ -552,36 +605,70 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
|
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
|
* <pre>
|
||||||
|
xSemaphoreTakeFromISR(
|
||||||
|
SemaphoreHandle_t xSemaphore,
|
||||||
|
BaseType_t *pxHigherPriorityTaskWoken
|
||||||
|
)</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
|
* <i>Macro</i> to take a semaphore from an ISR. The semaphore must have
|
||||||
|
* previously been created with a call to vSemaphoreCreateBinary() or
|
||||||
|
* xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
|
||||||
|
* must not be used with this macro.
|
||||||
|
*
|
||||||
|
* This macro can be used from an ISR, however taking a semaphore from an ISR
|
||||||
|
* is not a common operation. It is likely to only be useful when taking a
|
||||||
|
* counting semaphore when an interrupt is obtaining an object from a resource
|
||||||
|
* pool (when the semaphore count indicates the number of resources available).
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being taken. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task
|
||||||
|
* to unblock, and the unblocked task has a priority higher than the currently
|
||||||
|
* running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then
|
||||||
|
* a context switch should be requested before the interrupt is exited.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was successfully taken, otherwise
|
||||||
|
* pdFALSE
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>SemaphoreHandle_t xSemaphoreCreateMutex( void )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
|
||||||
* mechanism.
|
* mechanism.
|
||||||
*
|
*
|
||||||
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
|
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
|
||||||
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
|
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
|
||||||
* xSemaphoreGiveRecursive() macros should not be used.
|
* xSemaphoreGiveRecursive() macros should not be used.
|
||||||
*
|
|
||||||
* This type of semaphore uses a priority inheritance mechanism so a task
|
|
||||||
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
|
||||||
* semaphore it is no longer required.
|
|
||||||
*
|
*
|
||||||
* Mutex type semaphores cannot be used from within interrupt service routines.
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
*
|
*
|
||||||
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
*
|
||||||
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
* service routines.
|
* service routines.
|
||||||
*
|
*
|
||||||
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
* xSemaphoreHandle.
|
* SemaphoreHandle_t.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore;
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
@ -592,51 +679,51 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xSemaphore != NULL )
|
if( xSemaphore != NULL )
|
||||||
{
|
{
|
||||||
// The semaphore was created successfully.
|
// The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
// The semaphore can now be used.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreCreateMutex() xQueueCreateMutex()
|
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
|
* <pre>SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> that implements a recursive mutex by using the existing queue
|
* <i>Macro</i> that implements a recursive mutex by using the existing queue
|
||||||
* mechanism.
|
* mechanism.
|
||||||
*
|
*
|
||||||
* Mutexes created using this macro can be accessed using the
|
* Mutexes created using this macro can be accessed using the
|
||||||
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
|
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
|
||||||
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
|
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
|
||||||
*
|
*
|
||||||
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
* doesn't become available again until the owner has called
|
* doesn't become available again until the owner has called
|
||||||
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
* not be available to any other task until it has also 'given' the mutex back
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
* exactly five times.
|
* exactly five times.
|
||||||
*
|
|
||||||
* This type of semaphore uses a priority inheritance mechanism so a task
|
|
||||||
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
|
||||||
* semaphore it is no longer required.
|
|
||||||
*
|
*
|
||||||
* Mutex type semaphores cannot be used from within interrupt service routines.
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
*
|
*
|
||||||
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
*
|
||||||
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
* service routines.
|
* service routines.
|
||||||
*
|
*
|
||||||
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
* xSemaphoreHandle.
|
* SemaphoreHandle_t.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore;
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
@ -647,45 +734,45 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xSemaphore != NULL )
|
if( xSemaphore != NULL )
|
||||||
{
|
{
|
||||||
// The semaphore was created successfully.
|
// The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
// The semaphore can now be used.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
|
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
|
* <pre>SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )</pre>
|
||||||
*
|
*
|
||||||
* <i>Macro</i> that creates a counting semaphore by using the existing
|
* <i>Macro</i> that creates a counting semaphore by using the existing
|
||||||
* queue mechanism.
|
* queue mechanism.
|
||||||
*
|
*
|
||||||
* Counting semaphores are typically used for two things:
|
* Counting semaphores are typically used for two things:
|
||||||
*
|
*
|
||||||
* 1) Counting events.
|
* 1) Counting events.
|
||||||
*
|
*
|
||||||
* In this usage scenario an event handler will 'give' a semaphore each time
|
* In this usage scenario an event handler will 'give' a semaphore each time
|
||||||
* an event occurs (incrementing the semaphore count value), and a handler
|
* an event occurs (incrementing the semaphore count value), and a handler
|
||||||
* task will 'take' a semaphore each time it processes an event
|
* task will 'take' a semaphore each time it processes an event
|
||||||
* (decrementing the semaphore count value). The count value is therefore
|
* (decrementing the semaphore count value). The count value is therefore
|
||||||
* the difference between the number of events that have occurred and the
|
* the difference between the number of events that have occurred and the
|
||||||
* number that have been processed. In this case it is desirable for the
|
* number that have been processed. In this case it is desirable for the
|
||||||
* initial count value to be zero.
|
* initial count value to be zero.
|
||||||
*
|
*
|
||||||
* 2) Resource management.
|
* 2) Resource management.
|
||||||
*
|
*
|
||||||
* In this usage scenario the count value indicates the number of resources
|
* In this usage scenario the count value indicates the number of resources
|
||||||
* available. To obtain control of a resource a task must first obtain a
|
* available. To obtain control of a resource a task must first obtain a
|
||||||
* semaphore - decrementing the semaphore count value. When the count value
|
* semaphore - decrementing the semaphore count value. When the count value
|
||||||
* reaches zero there are no free resources. When a task finishes with the
|
* reaches zero there are no free resources. When a task finishes with the
|
||||||
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
||||||
* value. In this case it is desirable for the initial count value to be
|
* value. In this case it is desirable for the initial count value to be
|
||||||
* equal to the maximum count value, indicating that all resources are free.
|
* equal to the maximum count value, indicating that all resources are free.
|
||||||
*
|
*
|
||||||
* @param uxMaxCount The maximum count value that can be reached. When the
|
* @param uxMaxCount The maximum count value that can be reached. When the
|
||||||
* semaphore reaches this value it can no longer be 'given'.
|
* semaphore reaches this value it can no longer be 'given'.
|
||||||
*
|
*
|
||||||
* @param uxInitialCount The count value assigned to the semaphore when it is
|
* @param uxInitialCount The count value assigned to the semaphore when it is
|
||||||
@ -693,14 +780,14 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
*
|
*
|
||||||
* @return Handle to the created semaphore. Null if the semaphore could not be
|
* @return Handle to the created semaphore. Null if the semaphore could not be
|
||||||
* created.
|
* created.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
<pre>
|
<pre>
|
||||||
xSemaphoreHandle xSemaphore;
|
SemaphoreHandle_t xSemaphore;
|
||||||
|
|
||||||
void vATask( void * pvParameters )
|
void vATask( void * pvParameters )
|
||||||
{
|
{
|
||||||
xSemaphoreHandle xSemaphore = NULL;
|
SemaphoreHandle_t xSemaphore = NULL;
|
||||||
|
|
||||||
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||||
// The max value to which the semaphore can count should be 10, and the
|
// The max value to which the semaphore can count should be 10, and the
|
||||||
@ -710,7 +797,7 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
if( xSemaphore != NULL )
|
if( xSemaphore != NULL )
|
||||||
{
|
{
|
||||||
// The semaphore was created successfully.
|
// The semaphore was created successfully.
|
||||||
// The semaphore can now be used.
|
// The semaphore can now be used.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
@ -721,17 +808,32 @@ typedef xQueueHandle xSemaphoreHandle;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* semphr. h
|
* semphr. h
|
||||||
* <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>
|
* <pre>void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );</pre>
|
||||||
*
|
*
|
||||||
* Delete a semaphore. This function must be used with care. For example,
|
* Delete a semaphore. This function must be used with care. For example,
|
||||||
* do not delete a mutex type semaphore if the mutex is held by a task.
|
* do not delete a mutex type semaphore if the mutex is held by a task.
|
||||||
*
|
*
|
||||||
* @param xSemaphore A handle to the semaphore to be deleted.
|
* @param xSemaphore A handle to the semaphore to be deleted.
|
||||||
*
|
*
|
||||||
* \page vSemaphoreDelete vSemaphoreDelete
|
* \defgroup vSemaphoreDelete vSemaphoreDelete
|
||||||
* \ingroup Semaphores
|
* \ingroup Semaphores
|
||||||
*/
|
*/
|
||||||
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) xSemaphore )
|
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr.h
|
||||||
|
* <pre>TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );</pre>
|
||||||
|
*
|
||||||
|
* If xMutex is indeed a mutex type semaphore, return the current mutex holder.
|
||||||
|
* If xMutex is not a mutex type semaphore, or the mutex is available (not held
|
||||||
|
* by a task), return NULL.
|
||||||
|
*
|
||||||
|
* Note: This is a good way of determining if the calling task is the mutex
|
||||||
|
* holder, but not a good way of determining the identity of the mutex holder as
|
||||||
|
* the holder may change between the function exiting and the returned value
|
||||||
|
* being tested.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) )
|
||||||
|
|
||||||
#endif /* SEMAPHORE_H */
|
#endif /* SEMAPHORE_H */
|
||||||
|
|
||||||
|
|||||||
738
src/os/rtos/include/semphr.h.old
Normal file
738
src/os/rtos/include/semphr.h.old
Normal file
@ -0,0 +1,738 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SEMAPHORE_H
|
||||||
|
#define SEMAPHORE_H
|
||||||
|
|
||||||
|
#ifndef INC_FREERTOS_H
|
||||||
|
#error "#include FreeRTOS.h" must appear in source files before "#include semphr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rtosqueue.h"
|
||||||
|
|
||||||
|
typedef xQueueHandle xSemaphoreHandle;
|
||||||
|
|
||||||
|
#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( unsigned char ) 1U )
|
||||||
|
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( unsigned char ) 0U )
|
||||||
|
#define semGIVE_BLOCK_TIME ( ( portTickType ) 0U )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a semaphore by using the existing queue mechanism.
|
||||||
|
* The queue length is 1 as this is a binary semaphore. The data size is 0
|
||||||
|
* as we don't want to actually store any data - we just want to know if the
|
||||||
|
* queue is empty or full.
|
||||||
|
*
|
||||||
|
* This type of semaphore can be used for pure synchronisation between tasks or
|
||||||
|
* between an interrupt and a task. The semaphore need not be given back once
|
||||||
|
* obtained, so one task/interrupt can continuously 'give' the semaphore while
|
||||||
|
* another continuously 'takes' the semaphore. For this reason this type of
|
||||||
|
* semaphore does not use a priority inheritance mechanism. For an alternative
|
||||||
|
* that does use priority inheritance see xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* @param xSemaphore Handle to the created semaphore. Should be of type xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define vSemaphoreCreateBinary( xSemaphore ) { \
|
||||||
|
( xSemaphore ) = xQueueCreate( ( unsigned portBASE_TYPE ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH ); \
|
||||||
|
if( ( xSemaphore ) != NULL ) \
|
||||||
|
{ \
|
||||||
|
xSemaphoreGive( ( xSemaphore ) ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreTake(
|
||||||
|
* xSemaphoreHandle xSemaphore,
|
||||||
|
* portTickType xBlockTime
|
||||||
|
* )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to obtain a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
||||||
|
* xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being taken - obtained when
|
||||||
|
* the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
|
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the semaphore. A block
|
||||||
|
* time of portMAX_DELAY can be used to block indefinitely (provided
|
||||||
|
* INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was obtained. pdFALSE
|
||||||
|
* if xBlockTime expired without the semaphore becoming available.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// A task that creates a semaphore.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the semaphore to guard a shared resource.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the semaphore.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the semaphore. If the semaphore is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the semaphore and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished accessing the shared resource. Release the
|
||||||
|
// semaphore.
|
||||||
|
xSemaphoreGive( xSemaphore );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the semaphore and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreTake xSemaphoreTake
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
|
#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* xSemaphoreTakeRecursive(
|
||||||
|
* xSemaphoreHandle xMutex,
|
||||||
|
* portTickType xBlockTime
|
||||||
|
* )
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to recursively obtain, or 'take', a mutex type semaphore.
|
||||||
|
* The mutex must have previously been created using a call to
|
||||||
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
|
* macro to be available.
|
||||||
|
*
|
||||||
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* @param xMutex A handle to the mutex being obtained. This is the
|
||||||
|
* handle returned by xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* @param xBlockTime The time in ticks to wait for the semaphore to become
|
||||||
|
* available. The macro portTICK_RATE_MS can be used to convert this to a
|
||||||
|
* real time. A block time of zero can be used to poll the semaphore. If
|
||||||
|
* the task already owns the semaphore then xSemaphoreTakeRecursive() will
|
||||||
|
* return immediately no matter what the value of xBlockTime.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime
|
||||||
|
* expired without the semaphore becoming available.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xMutex = NULL;
|
||||||
|
|
||||||
|
// A task that creates a mutex.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the mutex to guard a shared resource.
|
||||||
|
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the mutex.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTakeRecursive( xSemaphore, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the mutex and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
// For some reason due to the nature of the code further calls to
|
||||||
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
|
// code these would not be just sequential calls as this would make
|
||||||
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
|
// a more complex call structure.
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
|
||||||
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
|
// available to another task until it has also been given back
|
||||||
|
// three times. Again it is unlikely that real code would have
|
||||||
|
// these calls sequentially, but instead buried in a more complex
|
||||||
|
// call structure. This is just for illustrative purposes.
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
|
||||||
|
// Now the mutex can be taken by other tasks.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the mutex and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xSemaphoreAltTake() is an alternative version of xSemaphoreTake().
|
||||||
|
*
|
||||||
|
* The source code that implements the alternative (Alt) API is much
|
||||||
|
* simpler because it executes everything from within a critical section.
|
||||||
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
|
* preferred fully featured API too. The fully featured API has more
|
||||||
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( xQueueHandle ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreGive( xSemaphoreHandle xSemaphore )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or
|
||||||
|
* xSemaphoreCreateCounting(). and obtained using sSemaphoreTake().
|
||||||
|
*
|
||||||
|
* This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for
|
||||||
|
* an alternative which can be used from an ISR.
|
||||||
|
*
|
||||||
|
* This macro must also not be used on semaphores created using
|
||||||
|
* xSemaphoreCreateRecursiveMutex().
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was released. pdFALSE if an error occurred.
|
||||||
|
* Semaphores are implemented using queues. An error can occur if there is
|
||||||
|
* no space on the queue to post a message - indicating that the
|
||||||
|
* semaphore was not first obtained correctly.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the semaphore to guard a shared resource.
|
||||||
|
vSemaphoreCreateBinary( xSemaphore );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
|
{
|
||||||
|
// We would expect this call to fail because we cannot give
|
||||||
|
// a semaphore without first "taking" it!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain the semaphore - don't block if the semaphore is not
|
||||||
|
// immediately available.
|
||||||
|
if( xSemaphoreTake( xSemaphore, ( portTickType ) 0 ) )
|
||||||
|
{
|
||||||
|
// We now have the semaphore and can access the shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished accessing the shared resource so can free the
|
||||||
|
// semaphore.
|
||||||
|
if( xSemaphoreGive( xSemaphore ) != pdTRUE )
|
||||||
|
{
|
||||||
|
// We would not expect this call to fail because we must have
|
||||||
|
// obtained the semaphore to get here.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGive xSemaphoreGive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr.h
|
||||||
|
* <pre>UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );</pre>
|
||||||
|
*
|
||||||
|
* If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns
|
||||||
|
* its current count value. If the semaphore is a binary semaphore then
|
||||||
|
* uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the
|
||||||
|
* semaphore is not available.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGetCount( xSemaphore ) xQueueMessagesWaiting( ( xQueueHandle ) ( xSemaphore ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to recursively release, or 'give', a mutex type semaphore.
|
||||||
|
* The mutex must have previously been created using a call to
|
||||||
|
* xSemaphoreCreateRecursiveMutex();
|
||||||
|
*
|
||||||
|
* configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this
|
||||||
|
* macro to be available.
|
||||||
|
*
|
||||||
|
* This macro must not be used on mutexes created using xSemaphoreCreateMutex().
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* @param xMutex A handle to the mutex being released, or 'given'. This is the
|
||||||
|
* handle returned by xSemaphoreCreateMutex();
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was given.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xMutex = NULL;
|
||||||
|
|
||||||
|
// A task that creates a mutex.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Create the mutex to guard a shared resource.
|
||||||
|
xMutex = xSemaphoreCreateRecursiveMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A task that uses the mutex.
|
||||||
|
void vAnotherTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// ... Do other things.
|
||||||
|
|
||||||
|
if( xMutex != NULL )
|
||||||
|
{
|
||||||
|
// See if we can obtain the mutex. If the mutex is not available
|
||||||
|
// wait 10 ticks to see if it becomes free.
|
||||||
|
if( xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// We were able to obtain the mutex and can now access the
|
||||||
|
// shared resource.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
// For some reason due to the nature of the code further calls to
|
||||||
|
// xSemaphoreTakeRecursive() are made on the same mutex. In real
|
||||||
|
// code these would not be just sequential calls as this would make
|
||||||
|
// no sense. Instead the calls are likely to be buried inside
|
||||||
|
// a more complex call structure.
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
xSemaphoreTakeRecursive( xMutex, ( portTickType ) 10 );
|
||||||
|
|
||||||
|
// The mutex has now been 'taken' three times, so will not be
|
||||||
|
// available to another task until it has also been given back
|
||||||
|
// three times. Again it is unlikely that real code would have
|
||||||
|
// these calls sequentially, it would be more likely that the calls
|
||||||
|
// to xSemaphoreGiveRecursive() would be called as a call stack
|
||||||
|
// unwound. This is just for demonstrative purposes.
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
xSemaphoreGiveRecursive( xMutex );
|
||||||
|
|
||||||
|
// Now the mutex can be taken by other tasks.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We could not obtain the mutex and can therefore not access
|
||||||
|
// the shared resource safely.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xSemaphoreAltGive() is an alternative version of xSemaphoreGive().
|
||||||
|
*
|
||||||
|
* The source code that implements the alternative (Alt) API is much
|
||||||
|
* simpler because it executes everything from within a critical section.
|
||||||
|
* This is the approach taken by many other RTOSes, but FreeRTOS.org has the
|
||||||
|
* preferred fully featured API too. The fully featured API has more
|
||||||
|
* complex code that takes longer to execute, but makes much less use of
|
||||||
|
* critical sections. Therefore the alternative API sacrifices interrupt
|
||||||
|
* responsiveness to gain execution speed, whereas the fully featured API
|
||||||
|
* sacrifices execution speed to ensure better interrupt responsiveness.
|
||||||
|
*/
|
||||||
|
#define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( xQueueHandle ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>
|
||||||
|
xSemaphoreGiveFromISR(
|
||||||
|
xSemaphoreHandle xSemaphore,
|
||||||
|
signed portBASE_TYPE *pxHigherPriorityTaskWoken
|
||||||
|
)</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> to release a semaphore. The semaphore must have previously been
|
||||||
|
* created with a call to vSemaphoreCreateBinary() or xSemaphoreCreateCounting().
|
||||||
|
*
|
||||||
|
* Mutex type semaphores (those created using a call to xSemaphoreCreateMutex())
|
||||||
|
* must not be used with this macro.
|
||||||
|
*
|
||||||
|
* This macro can be used from an ISR.
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore being released. This is the
|
||||||
|
* handle returned when the semaphore was created.
|
||||||
|
*
|
||||||
|
* @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set
|
||||||
|
* *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task
|
||||||
|
* to unblock, and the unblocked task has a priority higher than the currently
|
||||||
|
* running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then
|
||||||
|
* a context switch should be requested before the interrupt is exited.
|
||||||
|
*
|
||||||
|
* @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
\#define LONG_TIME 0xffff
|
||||||
|
\#define TICKS_TO_WAIT 10
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// Repetitive task.
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
// We want this task to run every 10 ticks of a timer. The semaphore
|
||||||
|
// was created before this task was started.
|
||||||
|
|
||||||
|
// Block waiting for the semaphore to become available.
|
||||||
|
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
|
||||||
|
{
|
||||||
|
// It is time to execute.
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// We have finished our task. Return to the top of the loop where
|
||||||
|
// we will block on the semaphore until it is time to execute
|
||||||
|
// again. Note when using the semaphore for synchronisation with an
|
||||||
|
// ISR in this manner there is no need to 'give' the semaphore back.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer ISR
|
||||||
|
void vTimerISR( void * pvParameters )
|
||||||
|
{
|
||||||
|
static unsigned char ucLocalTickCount = 0;
|
||||||
|
static signed portBASE_TYPE xHigherPriorityTaskWoken;
|
||||||
|
|
||||||
|
// A timer tick has occurred.
|
||||||
|
|
||||||
|
// ... Do other time functions.
|
||||||
|
|
||||||
|
// Is it time for vATask () to run?
|
||||||
|
xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
ucLocalTickCount++;
|
||||||
|
if( ucLocalTickCount >= TICKS_TO_WAIT )
|
||||||
|
{
|
||||||
|
// Unblock the task by releasing the semaphore.
|
||||||
|
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
// Reset the count so we release the semaphore again in 10 ticks time.
|
||||||
|
ucLocalTickCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xHigherPriorityTaskWoken != pdFALSE )
|
||||||
|
{
|
||||||
|
// We can force a context switch here. Context switching from an
|
||||||
|
// ISR uses port specific syntax. Check the demo task for your port
|
||||||
|
// to find the syntax required.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueueHandle ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateMutex( void )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a mutex semaphore by using the existing queue
|
||||||
|
* mechanism.
|
||||||
|
*
|
||||||
|
* Mutexes created using this macro can be accessed using the xSemaphoreTake()
|
||||||
|
* and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and
|
||||||
|
* xSemaphoreGiveRecursive() macros should not be used.
|
||||||
|
*
|
||||||
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
|
*
|
||||||
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
|
*
|
||||||
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
|
* service routines.
|
||||||
|
*
|
||||||
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
|
* xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
xSemaphore = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateMutex() xQueueCreateMutex()
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that implements a recursive mutex by using the existing queue
|
||||||
|
* mechanism.
|
||||||
|
*
|
||||||
|
* Mutexes created using this macro can be accessed using the
|
||||||
|
* xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The
|
||||||
|
* xSemaphoreTake() and xSemaphoreGive() macros should not be used.
|
||||||
|
*
|
||||||
|
* A mutex used recursively can be 'taken' repeatedly by the owner. The mutex
|
||||||
|
* doesn't become available again until the owner has called
|
||||||
|
* xSemaphoreGiveRecursive() for each successful 'take' request. For example,
|
||||||
|
* if a task successfully 'takes' the same mutex 5 times then the mutex will
|
||||||
|
* not be available to any other task until it has also 'given' the mutex back
|
||||||
|
* exactly five times.
|
||||||
|
*
|
||||||
|
* This type of semaphore uses a priority inheritance mechanism so a task
|
||||||
|
* 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the
|
||||||
|
* semaphore it is no longer required.
|
||||||
|
*
|
||||||
|
* Mutex type semaphores cannot be used from within interrupt service routines.
|
||||||
|
*
|
||||||
|
* See vSemaphoreCreateBinary() for an alternative implementation that can be
|
||||||
|
* used for pure synchronisation (where one task or interrupt always 'gives' the
|
||||||
|
* semaphore and another always 'takes' the semaphore) and from within interrupt
|
||||||
|
* service routines.
|
||||||
|
*
|
||||||
|
* @return xSemaphore Handle to the created mutex semaphore. Should be of type
|
||||||
|
* xSemaphoreHandle.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateMutex().
|
||||||
|
// This is a macro so pass the variable in directly.
|
||||||
|
xSemaphore = xSemaphoreCreateRecursiveMutex();
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup vSemaphoreCreateMutex vSemaphoreCreateMutex
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>xSemaphoreHandle xSemaphoreCreateCounting( unsigned portBASE_TYPE uxMaxCount, unsigned portBASE_TYPE uxInitialCount )</pre>
|
||||||
|
*
|
||||||
|
* <i>Macro</i> that creates a counting semaphore by using the existing
|
||||||
|
* queue mechanism.
|
||||||
|
*
|
||||||
|
* Counting semaphores are typically used for two things:
|
||||||
|
*
|
||||||
|
* 1) Counting events.
|
||||||
|
*
|
||||||
|
* In this usage scenario an event handler will 'give' a semaphore each time
|
||||||
|
* an event occurs (incrementing the semaphore count value), and a handler
|
||||||
|
* task will 'take' a semaphore each time it processes an event
|
||||||
|
* (decrementing the semaphore count value). The count value is therefore
|
||||||
|
* the difference between the number of events that have occurred and the
|
||||||
|
* number that have been processed. In this case it is desirable for the
|
||||||
|
* initial count value to be zero.
|
||||||
|
*
|
||||||
|
* 2) Resource management.
|
||||||
|
*
|
||||||
|
* In this usage scenario the count value indicates the number of resources
|
||||||
|
* available. To obtain control of a resource a task must first obtain a
|
||||||
|
* semaphore - decrementing the semaphore count value. When the count value
|
||||||
|
* reaches zero there are no free resources. When a task finishes with the
|
||||||
|
* resource it 'gives' the semaphore back - incrementing the semaphore count
|
||||||
|
* value. In this case it is desirable for the initial count value to be
|
||||||
|
* equal to the maximum count value, indicating that all resources are free.
|
||||||
|
*
|
||||||
|
* @param uxMaxCount The maximum count value that can be reached. When the
|
||||||
|
* semaphore reaches this value it can no longer be 'given'.
|
||||||
|
*
|
||||||
|
* @param uxInitialCount The count value assigned to the semaphore when it is
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* @return Handle to the created semaphore. Null if the semaphore could not be
|
||||||
|
* created.
|
||||||
|
*
|
||||||
|
* Example usage:
|
||||||
|
<pre>
|
||||||
|
xSemaphoreHandle xSemaphore;
|
||||||
|
|
||||||
|
void vATask( void * pvParameters )
|
||||||
|
{
|
||||||
|
xSemaphoreHandle xSemaphore = NULL;
|
||||||
|
|
||||||
|
// Semaphore cannot be used before a call to xSemaphoreCreateCounting().
|
||||||
|
// The max value to which the semaphore can count should be 10, and the
|
||||||
|
// initial value assigned to the count should be 0.
|
||||||
|
xSemaphore = xSemaphoreCreateCounting( 10, 0 );
|
||||||
|
|
||||||
|
if( xSemaphore != NULL )
|
||||||
|
{
|
||||||
|
// The semaphore was created successfully.
|
||||||
|
// The semaphore can now be used.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</pre>
|
||||||
|
* \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* semphr. h
|
||||||
|
* <pre>void vSemaphoreDelete( xSemaphoreHandle xSemaphore );</pre>
|
||||||
|
*
|
||||||
|
* Delete a semaphore. This function must be used with care. For example,
|
||||||
|
* do not delete a mutex type semaphore if the mutex is held by a task.
|
||||||
|
*
|
||||||
|
* @param xSemaphore A handle to the semaphore to be deleted.
|
||||||
|
*
|
||||||
|
* \page vSemaphoreDelete vSemaphoreDelete
|
||||||
|
* \ingroup Semaphores
|
||||||
|
*/
|
||||||
|
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( xQueueHandle ) xSemaphore )
|
||||||
|
|
||||||
|
#endif /* SEMAPHORE_H */
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
1318
src/os/rtos/include/task.h.old
Normal file
1318
src/os/rtos/include/task.h.old
Normal file
File diff suppressed because it is too large
Load Diff
@ -199,7 +199,7 @@ void xPortSysTickHandler( void )
|
|||||||
|
|
||||||
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
{
|
{
|
||||||
vTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
portYIELD_FROM_ISR(pdTRUE);
|
portYIELD_FROM_ISR(pdTRUE);
|
||||||
}
|
}
|
||||||
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );
|
||||||
|
|||||||
@ -1,62 +1,72 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "croutine.h"
|
#include "croutine.h"
|
||||||
#include "wm_config.h"
|
|
||||||
|
|
||||||
#if TLS_OS_FREERTOS
|
|
||||||
/*
|
/*
|
||||||
* Some kernel aware debuggers require data to be viewed to be global, rather
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
* than file scope.
|
* than file scope.
|
||||||
@ -67,17 +77,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Lists for ready and blocked co-routines. --------------------*/
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
||||||
static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
/* Other file private variables. --------------------------------*/
|
/* Other file private variables. --------------------------------*/
|
||||||
corCRCB * pxCurrentCoRoutine = NULL;
|
CRCB_t * pxCurrentCoRoutine = NULL;
|
||||||
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
|
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
|
||||||
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
/* The initial state of the co-routine when it is created. */
|
/* The initial state of the co-routine when it is created. */
|
||||||
#define corINITIAL_STATE ( 0 )
|
#define corINITIAL_STATE ( 0 )
|
||||||
@ -95,8 +105,8 @@ static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks =
|
|||||||
{ \
|
{ \
|
||||||
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
} \
|
} \
|
||||||
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utility to ready all the lists used by the scheduler. This is called
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
@ -124,13 +134,13 @@ static void prvCheckDelayedList( void );
|
|||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
|
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
BaseType_t xReturn;
|
||||||
corCRCB *pxCoRoutine;
|
CRCB_t *pxCoRoutine;
|
||||||
|
|
||||||
/* Allocate the memory that will store the co-routine control block. */
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
|
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||||
if( pxCoRoutine )
|
if( pxCoRoutine )
|
||||||
{
|
{
|
||||||
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
@ -157,15 +167,15 @@ corCRCB *pxCoRoutine;
|
|||||||
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||||
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
/* Set the co-routine control block as a link back from the xListItem.
|
/* Set the co-routine control block as a link back from the ListItem_t.
|
||||||
This is so we can get back to the containing CRCB from a generic item
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
in a list. */
|
in a list. */
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
/* Event lists are always in priority order. */
|
/* Event lists are always in priority order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
|
||||||
|
|
||||||
/* Now the co-routine has been initialised it can be added to the ready
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
list at the correct priority. */
|
list at the correct priority. */
|
||||||
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
@ -173,17 +183,17 @@ corCRCB *pxCoRoutine;
|
|||||||
xReturn = pdPASS;
|
xReturn = pdPASS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
|
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
|
||||||
{
|
{
|
||||||
portTickType xTimeToWake;
|
TickType_t xTimeToWake;
|
||||||
|
|
||||||
/* Calculate the time to wake - this may overflow but this is
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
not a problem. */
|
not a problem. */
|
||||||
@ -192,7 +202,7 @@ portTickType xTimeToWake;
|
|||||||
/* We must remove ourselves from the ready list before adding
|
/* We must remove ourselves from the ready list before adding
|
||||||
ourselves to the blocked list as the same list item is used for
|
ourselves to the blocked list as the same list item is used for
|
||||||
both lists. */
|
both lists. */
|
||||||
vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
/* The list item will be inserted in wake time order. */
|
/* The list item will be inserted in wake time order. */
|
||||||
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||||
@ -201,13 +211,13 @@ portTickType xTimeToWake;
|
|||||||
{
|
{
|
||||||
/* Wake time has overflowed. Place this item in the
|
/* Wake time has overflowed. Place this item in the
|
||||||
overflow list. */
|
overflow list. */
|
||||||
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The wake time has not overflowed, so we can use the
|
/* The wake time has not overflowed, so we can use the
|
||||||
current block list. */
|
current block list. */
|
||||||
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pxEventList )
|
if( pxEventList )
|
||||||
@ -226,25 +236,25 @@ static void prvCheckPendingReadyList( void )
|
|||||||
the ready lists itself. */
|
the ready lists itself. */
|
||||||
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
corCRCB *pxUnblockedCRCB;
|
CRCB_t *pxUnblockedCRCB;
|
||||||
|
|
||||||
/* The pending ready list can be accessed by an ISR. */
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
||||||
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
vListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
static void prvCheckDelayedList( void )
|
static void prvCheckDelayedList( void )
|
||||||
{
|
{
|
||||||
corCRCB *pxCRCB;
|
CRCB_t *pxCRCB;
|
||||||
|
|
||||||
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
while( xPassedTicks )
|
while( xPassedTicks )
|
||||||
@ -255,7 +265,7 @@ corCRCB *pxCRCB;
|
|||||||
/* If the tick count has overflowed we need to swap the ready lists. */
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
if( xCoRoutineTickCount == 0 )
|
if( xCoRoutineTickCount == 0 )
|
||||||
{
|
{
|
||||||
xList * pxTemp;
|
List_t * pxTemp;
|
||||||
|
|
||||||
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
any items in pxDelayedCoRoutineList here then there is an error! */
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
@ -267,13 +277,13 @@ corCRCB *pxCRCB;
|
|||||||
/* See if this tick has made a timeout expire. */
|
/* See if this tick has made a timeout expire. */
|
||||||
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||||
{
|
{
|
||||||
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||||
|
|
||||||
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||||
{
|
{
|
||||||
/* Timeout not yet expired. */
|
/* Timeout not yet expired. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
portDISABLE_INTERRUPTS();
|
portDISABLE_INTERRUPTS();
|
||||||
{
|
{
|
||||||
@ -282,18 +292,18 @@ corCRCB *pxCRCB;
|
|||||||
have been moved to the pending ready list and the following
|
have been moved to the pending ready list and the following
|
||||||
line is still valid. Also the pvContainer parameter will have
|
line is still valid. Also the pvContainer parameter will have
|
||||||
been set to NULL so the following lines are also valid. */
|
been set to NULL so the following lines are also valid. */
|
||||||
vListRemove( &( pxCRCB->xGenericListItem ) );
|
uxListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
/* Is the co-routine waiting on an event also? */
|
/* Is the co-routine waiting on an event also? */
|
||||||
if( pxCRCB->xEventListItem.pvContainer )
|
if( pxCRCB->xEventListItem.pvContainer )
|
||||||
{
|
{
|
||||||
vListRemove( &( pxCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
portENABLE_INTERRUPTS();
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
prvAddCoRoutineToReadyQueue( pxCRCB );
|
prvAddCoRoutineToReadyQueue( pxCRCB );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xLastTickCount = xCoRoutineTickCount;
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
@ -332,16 +342,16 @@ void vCoRoutineSchedule( void )
|
|||||||
|
|
||||||
static void prvInitialiseCoRoutineLists( void )
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
{
|
{
|
||||||
unsigned portBASE_TYPE uxPriority;
|
UBaseType_t uxPriority;
|
||||||
|
|
||||||
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
{
|
{
|
||||||
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
|
||||||
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
|
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
|
||||||
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
|
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
/* Start with pxDelayedCoRoutineList using list1 and the
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
pxOverflowDelayedCoRoutineList using list2. */
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
@ -350,17 +360,17 @@ unsigned portBASE_TYPE uxPriority;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
|
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
|
||||||
{
|
{
|
||||||
corCRCB *pxUnblockedCRCB;
|
CRCB_t *pxUnblockedCRCB;
|
||||||
signed portBASE_TYPE xReturn;
|
BaseType_t xReturn;
|
||||||
|
|
||||||
/* This function is called from within an interrupt. It can only access
|
/* This function is called from within an interrupt. It can only access
|
||||||
event lists and the pending ready list. This function assumes that a
|
event lists and the pending ready list. This function assumes that a
|
||||||
check has already been made to ensure pxEventList is not empty. */
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
||||||
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||||
{
|
{
|
||||||
@ -373,4 +383,4 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
return xReturn;
|
return xReturn;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|||||||
376
src/os/rtos/source/croutine.c.old
Normal file
376
src/os/rtos/source/croutine.c.old
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "croutine.h"
|
||||||
|
#include "wm_config.h"
|
||||||
|
|
||||||
|
#if TLS_OS_FREERTOS
|
||||||
|
/*
|
||||||
|
* Some kernel aware debuggers require data to be viewed to be global, rather
|
||||||
|
* than file scope.
|
||||||
|
*/
|
||||||
|
#ifdef portREMOVE_STATIC_QUALIFIER
|
||||||
|
#define static
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Lists for ready and blocked co-routines. --------------------*/
|
||||||
|
static xList pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
|
||||||
|
static xList xDelayedCoRoutineList1; /*< Delayed co-routines. */
|
||||||
|
static xList xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
|
||||||
|
static xList * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
|
||||||
|
static xList * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
|
||||||
|
static xList xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
|
||||||
|
|
||||||
|
/* Other file private variables. --------------------------------*/
|
||||||
|
corCRCB * pxCurrentCoRoutine = NULL;
|
||||||
|
static unsigned portBASE_TYPE uxTopCoRoutineReadyPriority = 0;
|
||||||
|
static portTickType xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
|
||||||
|
|
||||||
|
/* The initial state of the co-routine when it is created. */
|
||||||
|
#define corINITIAL_STATE ( 0 )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Place the co-routine represented by pxCRCB into the appropriate ready queue
|
||||||
|
* for the priority. It is inserted at the end of the list.
|
||||||
|
*
|
||||||
|
* This macro accesses the co-routine ready lists and therefore must not be
|
||||||
|
* used from within an ISR.
|
||||||
|
*/
|
||||||
|
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
|
||||||
|
{ \
|
||||||
|
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
|
||||||
|
{ \
|
||||||
|
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
|
||||||
|
} \
|
||||||
|
vListInsertEnd( ( xList * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility to ready all the lists used by the scheduler. This is called
|
||||||
|
* automatically upon the creation of the first co-routine.
|
||||||
|
*/
|
||||||
|
static void prvInitialiseCoRoutineLists( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Co-routines that are readied by an interrupt cannot be placed directly into
|
||||||
|
* the ready lists (there is no mutual exclusion). Instead they are placed in
|
||||||
|
* in the pending ready list in order that they can later be moved to the ready
|
||||||
|
* list by the co-routine scheduler.
|
||||||
|
*/
|
||||||
|
static void prvCheckPendingReadyList( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macro that looks at the list of co-routines that are currently delayed to
|
||||||
|
* see if any require waking.
|
||||||
|
*
|
||||||
|
* Co-routines are stored in the queue in the order of their wake time -
|
||||||
|
* meaning once one co-routine has been found whose timer has not expired
|
||||||
|
* we need not look any further down the list.
|
||||||
|
*/
|
||||||
|
static void prvCheckDelayedList( void );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex )
|
||||||
|
{
|
||||||
|
signed portBASE_TYPE xReturn;
|
||||||
|
corCRCB *pxCoRoutine;
|
||||||
|
|
||||||
|
/* Allocate the memory that will store the co-routine control block. */
|
||||||
|
pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) );
|
||||||
|
if( pxCoRoutine )
|
||||||
|
{
|
||||||
|
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
|
||||||
|
be created and the co-routine data structures need initialising. */
|
||||||
|
if( pxCurrentCoRoutine == NULL )
|
||||||
|
{
|
||||||
|
pxCurrentCoRoutine = pxCoRoutine;
|
||||||
|
prvInitialiseCoRoutineLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the priority is within limits. */
|
||||||
|
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
|
||||||
|
{
|
||||||
|
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill out the co-routine control block from the function parameters. */
|
||||||
|
pxCoRoutine->uxState = corINITIAL_STATE;
|
||||||
|
pxCoRoutine->uxPriority = uxPriority;
|
||||||
|
pxCoRoutine->uxIndex = uxIndex;
|
||||||
|
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
|
||||||
|
|
||||||
|
/* Initialise all the other co-routine control block parameters. */
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
|
||||||
|
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
|
||||||
|
|
||||||
|
/* Set the co-routine control block as a link back from the xListItem.
|
||||||
|
This is so we can get back to the containing CRCB from a generic item
|
||||||
|
in a list. */
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
|
||||||
|
|
||||||
|
/* Event lists are always in priority order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), configMAX_PRIORITIES - ( portTickType ) uxPriority );
|
||||||
|
|
||||||
|
/* Now the co-routine has been initialised it can be added to the ready
|
||||||
|
list at the correct priority. */
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCoRoutine );
|
||||||
|
|
||||||
|
xReturn = pdPASS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineAddToDelayedList( portTickType xTicksToDelay, xList *pxEventList )
|
||||||
|
{
|
||||||
|
portTickType xTimeToWake;
|
||||||
|
|
||||||
|
/* Calculate the time to wake - this may overflow but this is
|
||||||
|
not a problem. */
|
||||||
|
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
|
||||||
|
|
||||||
|
/* We must remove ourselves from the ready list before adding
|
||||||
|
ourselves to the blocked list as the same list item is used for
|
||||||
|
both lists. */
|
||||||
|
vListRemove( ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* The list item will be inserted in wake time order. */
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
|
||||||
|
|
||||||
|
if( xTimeToWake < xCoRoutineTickCount )
|
||||||
|
{
|
||||||
|
/* Wake time has overflowed. Place this item in the
|
||||||
|
overflow list. */
|
||||||
|
vListInsert( ( xList * ) pxOverflowDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The wake time has not overflowed, so we can use the
|
||||||
|
current block list. */
|
||||||
|
vListInsert( ( xList * ) pxDelayedCoRoutineList, ( xListItem * ) &( pxCurrentCoRoutine->xGenericListItem ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pxEventList )
|
||||||
|
{
|
||||||
|
/* Also add the co-routine to an event list. If this is done then the
|
||||||
|
function must be called with interrupts disabled. */
|
||||||
|
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckPendingReadyList( void )
|
||||||
|
{
|
||||||
|
/* Are there any co-routines waiting to get moved to the ready list? These
|
||||||
|
are co-routines that have been readied by an ISR. The ISR cannot access
|
||||||
|
the ready lists itself. */
|
||||||
|
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
corCRCB *pxUnblockedCRCB;
|
||||||
|
|
||||||
|
/* The pending ready list can be accessed by an ISR. */
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
|
||||||
|
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
vListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
|
||||||
|
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckDelayedList( void )
|
||||||
|
{
|
||||||
|
corCRCB *pxCRCB;
|
||||||
|
|
||||||
|
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
|
||||||
|
while( xPassedTicks )
|
||||||
|
{
|
||||||
|
xCoRoutineTickCount++;
|
||||||
|
xPassedTicks--;
|
||||||
|
|
||||||
|
/* If the tick count has overflowed we need to swap the ready lists. */
|
||||||
|
if( xCoRoutineTickCount == 0 )
|
||||||
|
{
|
||||||
|
xList * pxTemp;
|
||||||
|
|
||||||
|
/* Tick count has overflowed so we need to swap the delay lists. If there are
|
||||||
|
any items in pxDelayedCoRoutineList here then there is an error! */
|
||||||
|
pxTemp = pxDelayedCoRoutineList;
|
||||||
|
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
|
||||||
|
pxOverflowDelayedCoRoutineList = pxTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if this tick has made a timeout expire. */
|
||||||
|
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
pxCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
|
||||||
|
|
||||||
|
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
|
||||||
|
{
|
||||||
|
/* Timeout not yet expired. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
{
|
||||||
|
/* The event could have occurred just before this critical
|
||||||
|
section. If this is the case then the generic list item will
|
||||||
|
have been moved to the pending ready list and the following
|
||||||
|
line is still valid. Also the pvContainer parameter will have
|
||||||
|
been set to NULL so the following lines are also valid. */
|
||||||
|
vListRemove( &( pxCRCB->xGenericListItem ) );
|
||||||
|
|
||||||
|
/* Is the co-routine waiting on an event also? */
|
||||||
|
if( pxCRCB->xEventListItem.pvContainer )
|
||||||
|
{
|
||||||
|
vListRemove( &( pxCRCB->xEventListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
prvAddCoRoutineToReadyQueue( pxCRCB );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastTickCount = xCoRoutineTickCount;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vCoRoutineSchedule( void )
|
||||||
|
{
|
||||||
|
/* See if any co-routines readied by events need moving to the ready lists. */
|
||||||
|
prvCheckPendingReadyList();
|
||||||
|
|
||||||
|
/* See if any delayed co-routines have timed out. */
|
||||||
|
prvCheckDelayedList();
|
||||||
|
|
||||||
|
/* Find the highest priority queue that contains ready co-routines. */
|
||||||
|
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
|
||||||
|
{
|
||||||
|
if( uxTopCoRoutineReadyPriority == 0 )
|
||||||
|
{
|
||||||
|
/* No more co-routines to check. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
--uxTopCoRoutineReadyPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
|
||||||
|
of the same priority get an equal share of the processor time. */
|
||||||
|
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
|
||||||
|
|
||||||
|
/* Call the co-routine. */
|
||||||
|
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvInitialiseCoRoutineLists( void )
|
||||||
|
{
|
||||||
|
unsigned portBASE_TYPE uxPriority;
|
||||||
|
|
||||||
|
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
|
||||||
|
{
|
||||||
|
vListInitialise( ( xList * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
vListInitialise( ( xList * ) &xDelayedCoRoutineList1 );
|
||||||
|
vListInitialise( ( xList * ) &xDelayedCoRoutineList2 );
|
||||||
|
vListInitialise( ( xList * ) &xPendingReadyCoRoutineList );
|
||||||
|
|
||||||
|
/* Start with pxDelayedCoRoutineList using list1 and the
|
||||||
|
pxOverflowDelayedCoRoutineList using list2. */
|
||||||
|
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
|
||||||
|
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
signed portBASE_TYPE xCoRoutineRemoveFromEventList( const xList *pxEventList )
|
||||||
|
{
|
||||||
|
corCRCB *pxUnblockedCRCB;
|
||||||
|
signed portBASE_TYPE xReturn;
|
||||||
|
|
||||||
|
/* This function is called from within an interrupt. It can only access
|
||||||
|
event lists and the pending ready list. This function assumes that a
|
||||||
|
check has already been made to ensure pxEventList is not empty. */
|
||||||
|
pxUnblockedCRCB = ( corCRCB * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
|
||||||
|
vListRemove( &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
vListInsertEnd( ( xList * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
|
||||||
|
|
||||||
|
if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
|
||||||
|
{
|
||||||
|
xReturn = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
654
src/os/rtos/source/event_groups.c
Normal file
654
src/os/rtos/source/event_groups.c
Normal file
@ -0,0 +1,654 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
|
>>! kernel.
|
||||||
|
|
||||||
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
all the API functions to use the MPU wrappers. That should only be done when
|
||||||
|
task.h is included from an application file. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "rtostimers.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
|
||||||
|
/* Lint e961 and e750 are suppressed as a MISRA exception justified because the
|
||||||
|
MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the
|
||||||
|
header files above, but not in this file, in order to generate the correct
|
||||||
|
privileged Vs unprivileged linkage and placement. */
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||||
|
|
||||||
|
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( configUSE_TIMERS == 0 )
|
||||||
|
#error configUSE_TIMERS must be set to 1 to make the xEventGroupSetBitFromISR() function available.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ( INCLUDE_xEventGroupSetBitFromISR == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 0 )
|
||||||
|
#error INCLUDE_xTimerPendFunctionCall must also be set to one to make the xEventGroupSetBitFromISR() function available.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The following bit fields convey control information in a task's event list
|
||||||
|
item value. It is important they don't clash with the
|
||||||
|
taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
|
||||||
|
#if configUSE_16_BIT_TICKS == 1
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x0400U
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff00U
|
||||||
|
#else
|
||||||
|
#define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL
|
||||||
|
#define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL
|
||||||
|
#define eventWAIT_FOR_ALL_BITS 0x04000000UL
|
||||||
|
#define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct xEventGroupDefinition
|
||||||
|
{
|
||||||
|
EventBits_t uxEventBits;
|
||||||
|
List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */
|
||||||
|
|
||||||
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
|
UBaseType_t uxEventGroupNumber;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} EventGroup_t;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test the bits set in uxCurrentEventBits to see if the wait condition is met.
|
||||||
|
* The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is
|
||||||
|
* pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
|
||||||
|
* are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the
|
||||||
|
* wait condition is met if any of the bits set in uxBitsToWait for are also set
|
||||||
|
* in uxCurrentEventBits.
|
||||||
|
*/
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventGroupHandle_t xEventGroupCreate( void )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits;
|
||||||
|
|
||||||
|
pxEventBits = pvPortMalloc( sizeof( EventGroup_t ) );
|
||||||
|
if( pxEventBits != NULL )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits = 0;
|
||||||
|
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
|
||||||
|
traceEVENT_GROUP_CREATE( pxEventBits );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( EventGroupHandle_t ) pxEventBits;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventBits_t uxOriginalBitValue, uxReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
uxOriginalBitValue = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
/* All the rendezvous bits are now set - no need to block. */
|
||||||
|
uxReturn = ( uxOriginalBitValue | uxBitsToSet );
|
||||||
|
|
||||||
|
/* Rendezvous always clear the bits. They will have been cleared
|
||||||
|
already unless this is the only task in the rendezvous. */
|
||||||
|
pxEventBits->uxEventBits &= uxBitsToWaitFor;
|
||||||
|
|
||||||
|
xTicksToWait = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This assignment is obsolete as uxReturn will get set after
|
||||||
|
the task unblocks, but some compilers mistakenly generate a
|
||||||
|
warning about uxReturn being returned without being set if the
|
||||||
|
assignment is omitted. */
|
||||||
|
uxReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The rendezvous bits were not set, but no block time was
|
||||||
|
specified - just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Although the task got here because it timed out before the
|
||||||
|
bits it was waiting for were set, it is possible that since it
|
||||||
|
unblocked another task has set the bits. If this is the case
|
||||||
|
then it may be required to clear the bits before exiting. */
|
||||||
|
if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xTimeoutOccurred = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. Clear the control
|
||||||
|
bits before returning the value. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn, uxControlBits = 0;
|
||||||
|
BaseType_t xWaitConditionMet, xAlreadyYielded;
|
||||||
|
BaseType_t xTimeoutOccurred = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to wait on the bits used by the kernel
|
||||||
|
itself, and that at least one bit is being requested. */
|
||||||
|
configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
configASSERT( uxBitsToWaitFor != 0 );
|
||||||
|
#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
|
||||||
|
{
|
||||||
|
configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Check to see if the wait condition is already met or not. */
|
||||||
|
xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
|
||||||
|
|
||||||
|
if( xWaitConditionMet != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The wait condition has already been met so there is no need to
|
||||||
|
block. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
xTicksToWait = ( TickType_t ) 0;
|
||||||
|
|
||||||
|
/* Clear the wait bits if requested to do so. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( xTicksToWait == ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* The wait condition has not been met, but no block time was
|
||||||
|
specified, so just return the current value. */
|
||||||
|
uxReturn = uxCurrentEventBits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task is going to block to wait for its required bits to be
|
||||||
|
set. uxControlBits are used to remember the specified behaviour of
|
||||||
|
this call to xEventGroupWaitBits() - for use when the event bits
|
||||||
|
unblock the task. */
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xWaitForAllBits != pdFALSE )
|
||||||
|
{
|
||||||
|
uxControlBits |= eventWAIT_FOR_ALL_BITS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the bits that the calling task is waiting for in the
|
||||||
|
task's event list item so the kernel knows when a match is
|
||||||
|
found. Then enter the blocked state. */
|
||||||
|
vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
|
||||||
|
|
||||||
|
/* This is obsolete as it will get set after the task unblocks, but
|
||||||
|
some compilers mistakenly generate a warning about the variable
|
||||||
|
being returned without being set if it is not done. */
|
||||||
|
uxReturn = 0;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xAlreadyYielded = xTaskResumeAll();
|
||||||
|
|
||||||
|
if( xTicksToWait != ( TickType_t ) 0 )
|
||||||
|
{
|
||||||
|
if( xAlreadyYielded == pdFALSE )
|
||||||
|
{
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task blocked to wait for its required bits to be set - at this
|
||||||
|
point either the required bits were set or the block time expired. If
|
||||||
|
the required bits were set they will have been stored in the task's
|
||||||
|
event list item, and they should now be retrieved then cleared. */
|
||||||
|
uxReturn = uxTaskResetEventItemValue();
|
||||||
|
|
||||||
|
if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* The task timed out, just return the current event bit value. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* It is possible that the event bits were updated between this
|
||||||
|
task leaving the Blocked state and running again. */
|
||||||
|
if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
|
||||||
|
{
|
||||||
|
if( xClearOnExit != pdFALSE )
|
||||||
|
{
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
xTimeoutOccurred = pdFALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The task unblocked because the bits were set. Clear the control
|
||||||
|
bits before returning the value. */
|
||||||
|
uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
|
/* The value returned is the event group value prior to the bits being
|
||||||
|
cleared. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Clear the bits. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
|
||||||
|
{
|
||||||
|
UBaseType_t uxSavedInterruptStatus;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
EventBits_t uxReturn;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to clear the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
|
||||||
|
|
||||||
|
/* The value returned is the event group value prior to the bits being
|
||||||
|
cleared. */
|
||||||
|
uxReturn = pxEventBits->uxEventBits;
|
||||||
|
|
||||||
|
/* Clear the bits. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );
|
||||||
|
|
||||||
|
return uxReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
|
||||||
|
{
|
||||||
|
ListItem_t *pxListItem, *pxNext;
|
||||||
|
ListItem_t const *pxListEnd;
|
||||||
|
List_t *pxList;
|
||||||
|
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
BaseType_t xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Check the user is not attempting to set the bits used by the kernel
|
||||||
|
itself. */
|
||||||
|
configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
|
||||||
|
|
||||||
|
pxList = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
|
||||||
|
|
||||||
|
pxListItem = listGET_HEAD_ENTRY( pxList );
|
||||||
|
|
||||||
|
/* Set the bits. */
|
||||||
|
pxEventBits->uxEventBits |= uxBitsToSet;
|
||||||
|
|
||||||
|
/* See if the new bit value should unblock any tasks. */
|
||||||
|
while( pxListItem != pxListEnd )
|
||||||
|
{
|
||||||
|
pxNext = listGET_NEXT( pxListItem );
|
||||||
|
uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
|
||||||
|
xMatchFound = pdFALSE;
|
||||||
|
|
||||||
|
/* Split the bits waited for from the control bits. */
|
||||||
|
uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
|
||||||
|
|
||||||
|
if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Just looking for single bit being set. */
|
||||||
|
if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
|
||||||
|
{
|
||||||
|
/* All bits are set. */
|
||||||
|
xMatchFound = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Need all bits to be set, but not all the bits were set. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if( xMatchFound != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The bits match. Should the bits be cleared on exit? */
|
||||||
|
if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
uxBitsToClear |= uxBitsWaitedFor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store the actual event flag value in the task's event list
|
||||||
|
item before removing the task from the event list. The
|
||||||
|
eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
|
||||||
|
that is was unblocked due to its required bits matching, rather
|
||||||
|
than because it timed out. */
|
||||||
|
( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move onto the next list item. Note pxListItem->pxNext is not
|
||||||
|
used here as the list item may have been removed from the event list
|
||||||
|
and inserted into the ready/pending reading list. */
|
||||||
|
pxListItem = pxNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
|
||||||
|
bit was set in the control word. */
|
||||||
|
pxEventBits->uxEventBits &= ~uxBitsToClear;
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
|
||||||
|
return pxEventBits->uxEventBits;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vEventGroupDelete( EventGroupHandle_t xEventGroup )
|
||||||
|
{
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
traceEVENT_GROUP_DELETE( xEventGroup );
|
||||||
|
|
||||||
|
while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
|
||||||
|
{
|
||||||
|
/* Unblock the task, returning 0 as the event list is being deleted
|
||||||
|
and cannot therefore have any bits set. */
|
||||||
|
configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
|
||||||
|
( void ) xTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
|
||||||
|
}
|
||||||
|
|
||||||
|
vPortFree( pxEventBits );
|
||||||
|
}
|
||||||
|
( void ) xTaskResumeAll();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For internal use only - execute a 'set bits' command that was pended from
|
||||||
|
an interrupt. */
|
||||||
|
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
|
||||||
|
{
|
||||||
|
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits )
|
||||||
|
{
|
||||||
|
BaseType_t xWaitConditionMet = pdFALSE;
|
||||||
|
|
||||||
|
if( xWaitForAllBits == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Task only has to wait for one bit within uxBitsToWaitFor to be
|
||||||
|
set. Is one already set? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Task has to wait for all the bits in uxBitsToWaitFor to be set.
|
||||||
|
Are they set already? */
|
||||||
|
if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
|
||||||
|
{
|
||||||
|
xWaitConditionMet = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xWaitConditionMet;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
|
||||||
|
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
|
||||||
|
{
|
||||||
|
BaseType_t xReturn;
|
||||||
|
|
||||||
|
traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
|
||||||
|
xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if (configUSE_TRACE_FACILITY == 1)
|
||||||
|
UBaseType_t uxEventGroupGetNumber( void* xEventGroup )
|
||||||
|
{
|
||||||
|
UBaseType_t xReturn;
|
||||||
|
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
|
||||||
|
|
||||||
|
if( xEventGroup == NULL )
|
||||||
|
{
|
||||||
|
xReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = pxEventBits->uxEventGroupNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ task.h is included from an application file. */
|
|||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "wm_config.h"
|
#include "wm_config.h"
|
||||||
//#include "wm_mem.h"
|
#include "wm_mem.h"
|
||||||
|
|
||||||
|
|
||||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|||||||
@ -1,73 +1,83 @@
|
|||||||
/*
|
/*
|
||||||
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
* *
|
* *
|
||||||
* FreeRTOS tutorial books are available in pdf and paperback. *
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
* Complete, revised, and edited pdf reference manuals are also *
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
* available. *
|
* platform software that has become a de facto standard. *
|
||||||
* *
|
* *
|
||||||
* Purchasing FreeRTOS documentation will not only help you, by *
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
* ensuring you get running as quickly as possible and with an *
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
* the FreeRTOS project to continue with its mission of providing *
|
|
||||||
* professional grade, cross platform, de facto standard solutions *
|
|
||||||
* for microcontrollers - completely free of charge! *
|
|
||||||
* *
|
* *
|
||||||
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
* Thank you! *
|
||||||
* *
|
|
||||||
* Thank you for using FreeRTOS, and thank you for your support! *
|
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
This file is part of the FreeRTOS distribution.
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
the terms of the GNU General Public License (version 2) as published by the
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
>>>NOTE<<< The modification to the GPL is included to allow you to
|
|
||||||
distribute a combined work that includes FreeRTOS without being obliged to
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
provide the source code for proprietary components outside of the FreeRTOS
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
>>! kernel.
|
||||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details. You should have received a copy of the GNU General Public
|
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||||
by writing to Richard Barry, contact details for whom are available on the
|
link: http://www.freertos.org/a00114.html
|
||||||
FreeRTOS WEB site.
|
|
||||||
|
|
||||||
1 tab == 4 spaces!
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
http://www.FreeRTOS.org - Documentation, latest information, license and
|
***************************************************************************
|
||||||
contact details.
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
http://www.SafeRTOS.com - A version that is certified for use in safety
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
critical systems.
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
http://www.OpenRTOS.com - Commercial support, development, porting,
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
licensing and training services.
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
#include "rtoslist.h"
|
#include "rtoslist.h"
|
||||||
#include "wm_config.h"
|
|
||||||
|
|
||||||
#if TLS_OS_FREERTOS
|
|
||||||
/*-----------------------------------------------------------
|
/*-----------------------------------------------------------
|
||||||
* PUBLIC LIST API documented in list.h
|
* PUBLIC LIST API documented in list.h
|
||||||
*----------------------------------------------------------*/
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialise( xList *pxList )
|
void vListInitialise( List_t * const pxList )
|
||||||
{
|
{
|
||||||
/* The list structure contains a list item which is used to mark the
|
/* The list structure contains a list item which is used to mark the
|
||||||
end of the list. To initialise the list the list end is inserted
|
end of the list. To initialise the list the list end is inserted
|
||||||
as the only list entry. */
|
as the only list entry. */
|
||||||
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
|
pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
/* The list end value is the highest possible value in the list to
|
/* The list end value is the highest possible value in the list to
|
||||||
ensure it remains at the end of the list. */
|
ensure it remains at the end of the list. */
|
||||||
@ -75,35 +85,31 @@ void vListInitialise( xList *pxList )
|
|||||||
|
|
||||||
/* The list end next and previous pointers point to itself so we know
|
/* The list end next and previous pointers point to itself so we know
|
||||||
when the list is empty. */
|
when the list is empty. */
|
||||||
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
|
pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
|
pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
|
|
||||||
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
|
pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInitialiseItem( xListItem *pxItem )
|
void vListInitialiseItem( ListItem_t * const pxItem )
|
||||||
{
|
{
|
||||||
/* Make sure the list item is not recorded as being on a list. */
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
pxItem->pvContainer = NULL;
|
pxItem->pvContainer = NULL;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
|
void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
volatile xListItem * pxIndex;
|
ListItem_t * const pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
/* Insert a new list item into pxList, but rather than sort the list,
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
makes the new list item the last item to be removed by a call to
|
makes the new list item the last item to be removed by a call to
|
||||||
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
|
listGET_OWNER_OF_NEXT_ENTRY(). */
|
||||||
the pxIndex member. */
|
pxNewListItem->pxNext = pxIndex;
|
||||||
pxIndex = pxList->pxIndex;
|
pxNewListItem->pxPrevious = pxIndex->pxPrevious;
|
||||||
|
pxIndex->pxPrevious->pxNext = pxNewListItem;
|
||||||
pxNewListItem->pxNext = pxIndex->pxNext;
|
pxIndex->pxPrevious = pxNewListItem;
|
||||||
pxNewListItem->pxPrevious = pxList->pxIndex;
|
|
||||||
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
|
||||||
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
|
|
||||||
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
|
|
||||||
|
|
||||||
/* Remember which list the item is in. */
|
/* Remember which list the item is in. */
|
||||||
pxNewListItem->pvContainer = ( void * ) pxList;
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
@ -112,17 +118,16 @@ volatile xListItem * pxIndex;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListInsert( xList *pxList, xListItem *pxNewListItem )
|
void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
|
||||||
{
|
{
|
||||||
volatile xListItem *pxIterator;
|
ListItem_t *pxIterator;
|
||||||
portTickType xValueOfInsertion;
|
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
/* Insert the new list item into the list, sorted in ulListItem order. */
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
xValueOfInsertion = pxNewListItem->xItemValue;
|
|
||||||
|
|
||||||
/* If the list already contains a list item with the same item value then
|
If the list already contains a list item with the same item value then
|
||||||
the new list item should be placed after it. This ensures that TCB's which
|
the new list item should be placed after it. This ensures that TCB's which
|
||||||
are stored in ready lists (all of which have the same ulListItem value)
|
are stored in ready lists (all of which have the same xItemValue value)
|
||||||
get an equal share of the CPU. However, if the xItemValue is the same as
|
get an equal share of the CPU. However, if the xItemValue is the same as
|
||||||
the back marker the iteration loop below will not end. This means we need
|
the back marker the iteration loop below will not end. This means we need
|
||||||
to guard against this by checking the value first and modifying the
|
to guard against this by checking the value first and modifying the
|
||||||
@ -142,14 +147,16 @@ portTickType xValueOfInsertion;
|
|||||||
interrupt priories, which can seem counter intuitive. See
|
interrupt priories, which can seem counter intuitive. See
|
||||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||||
3) Calling an API function from within a critical section or when
|
3) Calling an API function from within a critical section or when
|
||||||
the scheduler is suspended.
|
the scheduler is suspended, or calling an API function that does
|
||||||
|
not end in "FromISR" from an interrupt.
|
||||||
4) Using a queue or semaphore before it has been initialised or
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
before the scheduler has been started (are interrupts firing
|
before the scheduler has been started (are interrupts firing
|
||||||
before vTaskStartScheduler() has been called?).
|
before vTaskStartScheduler() has been called?).
|
||||||
See http://www.freertos.org/FAQHelp.html for more tips.
|
See http://www.freertos.org/FAQHelp.html for more tips, and ensure
|
||||||
|
configASSERT() is defined! http://www.freertos.org/a00110.html#configASSERT
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
|
for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 The mini list structure is used as the list end to save RAM. This is checked and valid. */
|
||||||
{
|
{
|
||||||
/* There is nothing to do here, we are just iterating to the
|
/* There is nothing to do here, we are just iterating to the
|
||||||
wanted insertion position. */
|
wanted insertion position. */
|
||||||
@ -157,9 +164,9 @@ portTickType xValueOfInsertion;
|
|||||||
}
|
}
|
||||||
|
|
||||||
pxNewListItem->pxNext = pxIterator->pxNext;
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
pxNewListItem->pxNext->pxPrevious = pxNewListItem;
|
||||||
pxNewListItem->pxPrevious = pxIterator;
|
pxNewListItem->pxPrevious = pxIterator;
|
||||||
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
|
pxIterator->pxNext = pxNewListItem;
|
||||||
|
|
||||||
/* Remember which list the item is in. This allows fast removal of the
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
item later. */
|
item later. */
|
||||||
@ -169,26 +176,29 @@ portTickType xValueOfInsertion;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vListRemove( xListItem *pxItemToRemove )
|
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
|
||||||
{
|
{
|
||||||
xList * pxList;
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
|
item. */
|
||||||
|
List_t * const pxList = ( List_t * ) pxItemToRemove->pvContainer;
|
||||||
|
|
||||||
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
||||||
/* The list item knows which list it is in. Obtain the list from the list
|
|
||||||
item. */
|
|
||||||
pxList = ( xList * ) pxItemToRemove->pvContainer;
|
|
||||||
|
|
||||||
/* Make sure the index is left pointing to a valid item. */
|
/* Make sure the index is left pointing to a valid item. */
|
||||||
if( pxList->pxIndex == pxItemToRemove )
|
if( pxList->pxIndex == pxItemToRemove )
|
||||||
{
|
{
|
||||||
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
|
||||||
pxItemToRemove->pvContainer = NULL;
|
pxItemToRemove->pvContainer = NULL;
|
||||||
( pxList->uxNumberOfItems )--;
|
( pxList->uxNumberOfItems )--;
|
||||||
|
|
||||||
|
return pxList->uxNumberOfItems;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
194
src/os/rtos/source/list.c.old
Normal file
194
src/os/rtos/source/list.c.old
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "rtoslist.h"
|
||||||
|
#include "wm_config.h"
|
||||||
|
|
||||||
|
#if TLS_OS_FREERTOS
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* PUBLIC LIST API documented in list.h
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInitialise( xList *pxList )
|
||||||
|
{
|
||||||
|
/* The list structure contains a list item which is used to mark the
|
||||||
|
end of the list. To initialise the list the list end is inserted
|
||||||
|
as the only list entry. */
|
||||||
|
pxList->pxIndex = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
/* The list end value is the highest possible value in the list to
|
||||||
|
ensure it remains at the end of the list. */
|
||||||
|
pxList->xListEnd.xItemValue = portMAX_DELAY;
|
||||||
|
|
||||||
|
/* The list end next and previous pointers point to itself so we know
|
||||||
|
when the list is empty. */
|
||||||
|
pxList->xListEnd.pxNext = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
pxList->xListEnd.pxPrevious = ( xListItem * ) &( pxList->xListEnd );
|
||||||
|
|
||||||
|
pxList->uxNumberOfItems = ( unsigned portBASE_TYPE ) 0U;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInitialiseItem( xListItem *pxItem )
|
||||||
|
{
|
||||||
|
/* Make sure the list item is not recorded as being on a list. */
|
||||||
|
pxItem->pvContainer = NULL;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInsertEnd( xList *pxList, xListItem *pxNewListItem )
|
||||||
|
{
|
||||||
|
volatile xListItem * pxIndex;
|
||||||
|
|
||||||
|
/* Insert a new list item into pxList, but rather than sort the list,
|
||||||
|
makes the new list item the last item to be removed by a call to
|
||||||
|
pvListGetOwnerOfNextEntry. This means it has to be the item pointed to by
|
||||||
|
the pxIndex member. */
|
||||||
|
pxIndex = pxList->pxIndex;
|
||||||
|
|
||||||
|
pxNewListItem->pxNext = pxIndex->pxNext;
|
||||||
|
pxNewListItem->pxPrevious = pxList->pxIndex;
|
||||||
|
pxIndex->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxIndex->pxNext = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxList->pxIndex = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
|
||||||
|
/* Remember which list the item is in. */
|
||||||
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
|
|
||||||
|
( pxList->uxNumberOfItems )++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListInsert( xList *pxList, xListItem *pxNewListItem )
|
||||||
|
{
|
||||||
|
volatile xListItem *pxIterator;
|
||||||
|
portTickType xValueOfInsertion;
|
||||||
|
|
||||||
|
/* Insert the new list item into the list, sorted in ulListItem order. */
|
||||||
|
xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
|
|
||||||
|
/* If the list already contains a list item with the same item value then
|
||||||
|
the new list item should be placed after it. This ensures that TCB's which
|
||||||
|
are stored in ready lists (all of which have the same ulListItem value)
|
||||||
|
get an equal share of the CPU. However, if the xItemValue is the same as
|
||||||
|
the back marker the iteration loop below will not end. This means we need
|
||||||
|
to guard against this by checking the value first and modifying the
|
||||||
|
algorithm slightly if necessary. */
|
||||||
|
if( xValueOfInsertion == portMAX_DELAY )
|
||||||
|
{
|
||||||
|
pxIterator = pxList->xListEnd.pxPrevious;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* *** NOTE ***********************************************************
|
||||||
|
If you find your application is crashing here then likely causes are:
|
||||||
|
1) Stack overflow -
|
||||||
|
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||||
|
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
||||||
|
parts where numerically high priority values denote low actual
|
||||||
|
interrupt priories, which can seem counter intuitive. See
|
||||||
|
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||||
|
3) Calling an API function from within a critical section or when
|
||||||
|
the scheduler is suspended.
|
||||||
|
4) Using a queue or semaphore before it has been initialised or
|
||||||
|
before the scheduler has been started (are interrupts firing
|
||||||
|
before vTaskStartScheduler() has been called?).
|
||||||
|
See http://www.freertos.org/FAQHelp.html for more tips.
|
||||||
|
**********************************************************************/
|
||||||
|
|
||||||
|
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
|
||||||
|
{
|
||||||
|
/* There is nothing to do here, we are just iterating to the
|
||||||
|
wanted insertion position. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pxNewListItem->pxNext = pxIterator->pxNext;
|
||||||
|
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
pxNewListItem->pxPrevious = pxIterator;
|
||||||
|
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
|
||||||
|
|
||||||
|
/* Remember which list the item is in. This allows fast removal of the
|
||||||
|
item later. */
|
||||||
|
pxNewListItem->pvContainer = ( void * ) pxList;
|
||||||
|
|
||||||
|
( pxList->uxNumberOfItems )++;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vListRemove( xListItem *pxItemToRemove )
|
||||||
|
{
|
||||||
|
xList * pxList;
|
||||||
|
|
||||||
|
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
|
||||||
|
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
|
||||||
|
|
||||||
|
/* The list item knows which list it is in. Obtain the list from the list
|
||||||
|
item. */
|
||||||
|
pxList = ( xList * ) pxItemToRemove->pvContainer;
|
||||||
|
|
||||||
|
/* Make sure the index is left pointing to a valid item. */
|
||||||
|
if( pxList->pxIndex == pxItemToRemove )
|
||||||
|
{
|
||||||
|
pxList->pxIndex = pxItemToRemove->pxPrevious;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxItemToRemove->pvContainer = NULL;
|
||||||
|
( pxList->uxNumberOfItems )--;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
1623
src/os/rtos/source/queue.c.old
Normal file
1623
src/os/rtos/source/queue.c.old
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
735
src/os/rtos/source/rtostimers.c.old
Normal file
735
src/os/rtos/source/rtostimers.c.old
Normal file
@ -0,0 +1,735 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.0.2 - Copyright (C) 2011 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, latest information, license and
|
||||||
|
contact details.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - A version that is certified for use in safety
|
||||||
|
critical systems.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Commercial support, development, porting,
|
||||||
|
licensing and training services.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
|
||||||
|
all the API functions to use the MPU wrappers. That should only be done when
|
||||||
|
task.h is included from an application file. */
|
||||||
|
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "rtosqueue.h"
|
||||||
|
#include "rtostimers.h"
|
||||||
|
#include "wm_config.h"
|
||||||
|
|
||||||
|
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
|
||||||
|
#if TLS_OS_FREERTOS
|
||||||
|
/* This entire source file will be skipped if the application is not configured
|
||||||
|
to include software timer functionality. This #if is closed at the very bottom
|
||||||
|
of this file. If you want to include software timer functionality then ensure
|
||||||
|
configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
|
||||||
|
#if ( configUSE_TIMERS == 1 )
|
||||||
|
|
||||||
|
/* Misc definitions. */
|
||||||
|
#define tmrNO_DELAY ( portTickType ) 0U
|
||||||
|
#if 0
|
||||||
|
/* The definition of the timers themselves. */
|
||||||
|
typedef struct tmrTimerControl
|
||||||
|
{
|
||||||
|
const signed char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */
|
||||||
|
xListItem xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
|
||||||
|
portTickType xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
|
||||||
|
unsigned portBASE_TYPE uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one shot timer. */
|
||||||
|
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
|
||||||
|
tmrTIMER_CALLBACK pxCallbackFunction; /*<< The function that will be called when the timer expires. */
|
||||||
|
void *callback_arg; /*added by dave */
|
||||||
|
} xTIMER;
|
||||||
|
#endif
|
||||||
|
/* The definition of messages that can be sent and received on the timer
|
||||||
|
queue. */
|
||||||
|
typedef struct tmrTimerQueueMessage
|
||||||
|
{
|
||||||
|
portBASE_TYPE xMessageID; /*<< The command being sent to the timer service task. */
|
||||||
|
portTickType xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */
|
||||||
|
xTIMER * pxTimer; /*<< The timer to which the command will be applied. */
|
||||||
|
} xTIMER_MESSAGE;
|
||||||
|
|
||||||
|
|
||||||
|
/* The list in which active timers are stored. Timers are referenced in expire
|
||||||
|
time order, with the nearest expiry time at the front of the list. Only the
|
||||||
|
timer service task is allowed to access xActiveTimerList. */
|
||||||
|
PRIVILEGED_DATA static xList xActiveTimerList1;
|
||||||
|
PRIVILEGED_DATA static xList xActiveTimerList2;
|
||||||
|
PRIVILEGED_DATA static xList *pxCurrentTimerList;
|
||||||
|
PRIVILEGED_DATA static xList *pxOverflowTimerList;
|
||||||
|
|
||||||
|
/* A queue that is used to send commands to the timer service task. */
|
||||||
|
PRIVILEGED_DATA static xQueueHandle xTimerQueue = NULL;
|
||||||
|
|
||||||
|
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
||||||
|
|
||||||
|
PRIVILEGED_DATA static xTaskHandle xTimerTaskHandle = NULL;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialise the infrastructure used by the timer service task if it has not
|
||||||
|
* been initialised already.
|
||||||
|
*/
|
||||||
|
static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The timer service task (daemon). Timer functionality is controlled by this
|
||||||
|
* task. Other tasks communicate with the timer service task using the
|
||||||
|
* xTimerQueue queue.
|
||||||
|
*/
|
||||||
|
static void prvTimerTask( void *pvParameters ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by the timer service task to interpret and process a command it
|
||||||
|
* received on the timer queue.
|
||||||
|
*/
|
||||||
|
static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert the timer into either xActiveTimerList1, or xActiveTimerList2,
|
||||||
|
* depending on if the expire time causes a timer counter overflow.
|
||||||
|
*/
|
||||||
|
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An active timer has reached its expire time. Reload the timer if it is an
|
||||||
|
* auto reload timer, then call its callback.
|
||||||
|
*/
|
||||||
|
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The tick count has overflowed. Switch the timer lists after ensuring the
|
||||||
|
* current timer list does not still reference some timers.
|
||||||
|
*/
|
||||||
|
static void prvSwitchTimerLists( portTickType xLastTime ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE
|
||||||
|
* if a tick count overflow occurred since prvSampleTimeNow() was last called.
|
||||||
|
*/
|
||||||
|
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the timer list contains any active timers then return the expire time of
|
||||||
|
* the timer that will expire first and set *pxListWasEmpty to false. If the
|
||||||
|
* timer list does not contain any timers then return 0 and set *pxListWasEmpty
|
||||||
|
* to pdTRUE.
|
||||||
|
*/
|
||||||
|
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a timer has expired, process it. Otherwise, block the timer service task
|
||||||
|
* until either a timer does expire or a command is received.
|
||||||
|
*/
|
||||||
|
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xTimerCreateTimerTask( void )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn = pdFAIL;
|
||||||
|
|
||||||
|
/* This function is called when the scheduler is started if
|
||||||
|
configUSE_TIMERS is set to 1. Check that the infrastructure used by the
|
||||||
|
timer service task has been created/initialised. If timers have already
|
||||||
|
been created then the initialisation will already have been performed. */
|
||||||
|
prvCheckForValidListAndQueue();
|
||||||
|
|
||||||
|
if( xTimerQueue != NULL )
|
||||||
|
{
|
||||||
|
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
||||||
|
{
|
||||||
|
/* Create the timer task, storing its handle in xTimerTaskHandle so
|
||||||
|
it can be returned by the xTimerGetTimerDaemonTaskHandle() function. */
|
||||||
|
xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, &xTimerTaskHandle );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
/* Create the timer task without storing its handle. */
|
||||||
|
xReturn = xTaskCreate( prvTimerTask, ( const signed char * ) "Tmr Svc", ( unsigned short ) configTIMER_TASK_STACK_DEPTH, NULL, ( unsigned portBASE_TYPE ) configTIMER_TASK_PRIORITY, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
configASSERT( xReturn );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
xTimerHandle xTimerCreate( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction )
|
||||||
|
{
|
||||||
|
xTIMER *pxNewTimer;
|
||||||
|
|
||||||
|
/* Allocate the timer structure. */
|
||||||
|
if( xTimerPeriodInTicks == ( portTickType ) 0U )
|
||||||
|
{
|
||||||
|
pxNewTimer = NULL;
|
||||||
|
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );
|
||||||
|
if( pxNewTimer != NULL )
|
||||||
|
{
|
||||||
|
/* Ensure the infrastructure used by the timer service task has been
|
||||||
|
created/initialised. */
|
||||||
|
prvCheckForValidListAndQueue();
|
||||||
|
|
||||||
|
/* Initialise the timer structure members using the function parameters. */
|
||||||
|
pxNewTimer->pcTimerName = pcTimerName;
|
||||||
|
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
|
||||||
|
pxNewTimer->uxAutoReload = uxAutoReload;
|
||||||
|
pxNewTimer->pvTimerID = pvTimerID;
|
||||||
|
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
||||||
|
pxNewTimer->callback_arg = NULL; //add by dave
|
||||||
|
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
||||||
|
|
||||||
|
traceTIMER_CREATE( pxNewTimer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceTIMER_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( xTimerHandle ) pxNewTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
xTimerHandle xTimerCreateExt( const signed char *pcTimerName, portTickType xTimerPeriodInTicks, unsigned portBASE_TYPE uxAutoReload, void *pvTimerID, tmrTIMER_CALLBACK pxCallbackFunction, void *callback_arg )
|
||||||
|
{
|
||||||
|
xTIMER *pxNewTimer;
|
||||||
|
|
||||||
|
/* Allocate the timer structure. */
|
||||||
|
if( xTimerPeriodInTicks == ( portTickType ) 0U )
|
||||||
|
{
|
||||||
|
pxNewTimer = NULL;
|
||||||
|
configASSERT( ( xTimerPeriodInTicks > 0 ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pxNewTimer = ( xTIMER * ) pvPortMalloc( sizeof( xTIMER ) );
|
||||||
|
if( pxNewTimer != NULL )
|
||||||
|
{
|
||||||
|
/* Ensure the infrastructure used by the timer service task has been
|
||||||
|
created/initialised. */
|
||||||
|
prvCheckForValidListAndQueue();
|
||||||
|
|
||||||
|
/* Initialise the timer structure members using the function parameters. */
|
||||||
|
pxNewTimer->pcTimerName = pcTimerName;
|
||||||
|
pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks;
|
||||||
|
pxNewTimer->uxAutoReload = uxAutoReload;
|
||||||
|
pxNewTimer->pvTimerID = pvTimerID;
|
||||||
|
pxNewTimer->pxCallbackFunction = pxCallbackFunction;
|
||||||
|
pxNewTimer->callback_arg = callback_arg; //add by dave
|
||||||
|
vListInitialiseItem( &( pxNewTimer->xTimerListItem ) );
|
||||||
|
|
||||||
|
traceTIMER_CREATE( pxNewTimer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
traceTIMER_CREATE_FAILED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( xTimerHandle ) pxNewTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
TickType_t xTimerGetExpiryTime( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
xTIMER * pxTimer = ( xTIMER * ) xTimer;
|
||||||
|
TickType_t xReturn;
|
||||||
|
|
||||||
|
configASSERT( xTimer );
|
||||||
|
xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xTimerGenericCommand( xTimerHandle xTimer, portBASE_TYPE xCommandID, portTickType xOptionalValue, portBASE_TYPE *pxHigherPriorityTaskWoken, portTickType xBlockTime )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn = pdFAIL;
|
||||||
|
xTIMER_MESSAGE xMessage;
|
||||||
|
|
||||||
|
/* Send a message to the timer service task to perform a particular action
|
||||||
|
on a particular timer definition. */
|
||||||
|
if( xTimerQueue != NULL )
|
||||||
|
{
|
||||||
|
/* Send a command to the timer service task to start the xTimer timer. */
|
||||||
|
xMessage.xMessageID = xCommandID;
|
||||||
|
xMessage.xMessageValue = xOptionalValue;
|
||||||
|
xMessage.pxTimer = ( xTIMER * ) xTimer;
|
||||||
|
|
||||||
|
if( pxHigherPriorityTaskWoken == NULL )
|
||||||
|
{
|
||||||
|
if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING )
|
||||||
|
{
|
||||||
|
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xBlockTime );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
|
||||||
|
}
|
||||||
|
|
||||||
|
traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn );
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( INCLUDE_xTimerGetTimerDaemonTaskHandle == 1 )
|
||||||
|
|
||||||
|
xTaskHandle xTimerGetTimerDaemonTaskHandle( void )
|
||||||
|
{
|
||||||
|
/* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been
|
||||||
|
started, then xTimerTaskHandle will be NULL. */
|
||||||
|
configASSERT( ( xTimerTaskHandle != NULL ) );
|
||||||
|
return xTimerTaskHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvProcessExpiredTimer( portTickType xNextExpireTime, portTickType xTimeNow )
|
||||||
|
{
|
||||||
|
xTIMER *pxTimer;
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
/* Remove the timer from the list of active timers. A check has already
|
||||||
|
been performed to ensure the list is not empty. */
|
||||||
|
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||||
|
vListRemove( &( pxTimer->xTimerListItem ) );
|
||||||
|
traceTIMER_EXPIRED( pxTimer );
|
||||||
|
|
||||||
|
/* If the timer is an auto reload timer then calculate the next
|
||||||
|
expiry time and re-insert the timer in the list of active timers. */
|
||||||
|
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
|
||||||
|
{
|
||||||
|
/* This is the only time a timer is inserted into a list using
|
||||||
|
a time relative to anything other than the current time. It
|
||||||
|
will therefore be inserted into the correct list relative to
|
||||||
|
the time this task thinks it is now, even if a command to
|
||||||
|
switch lists due to a tick count overflow is already waiting in
|
||||||
|
the timer queue. */
|
||||||
|
if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* The timer expired before it was added to the active timer
|
||||||
|
list. Reload it now. */
|
||||||
|
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
|
||||||
|
configASSERT( xResult );
|
||||||
|
( void ) xResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the timer callback. */
|
||||||
|
//pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
|
||||||
|
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer, pxTimer->callback_arg ); //modify by dave
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvTimerTask( void *pvParameters )
|
||||||
|
{
|
||||||
|
portTickType xNextExpireTime;
|
||||||
|
portBASE_TYPE xListWasEmpty;
|
||||||
|
|
||||||
|
/* Just to avoid compiler warnings. */
|
||||||
|
( void ) pvParameters;
|
||||||
|
|
||||||
|
for( ;; )
|
||||||
|
{
|
||||||
|
/* Query the timers list to see if it contains any timers, and if so,
|
||||||
|
obtain the time at which the next timer will expire. */
|
||||||
|
xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty );
|
||||||
|
|
||||||
|
/* If a timer has expired, process it. Otherwise, block this task
|
||||||
|
until either a timer does expire, or a command is received. */
|
||||||
|
prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty );
|
||||||
|
|
||||||
|
/* Empty the command queue. */
|
||||||
|
prvProcessReceivedCommands();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvProcessTimerOrBlockTask( portTickType xNextExpireTime, portBASE_TYPE xListWasEmpty )
|
||||||
|
{
|
||||||
|
portTickType xTimeNow;
|
||||||
|
portBASE_TYPE xTimerListsWereSwitched;
|
||||||
|
|
||||||
|
vTaskSuspendAll();
|
||||||
|
{
|
||||||
|
/* Obtain the time now to make an assessment as to whether the timer
|
||||||
|
has expired or not. If obtaining the time causes the lists to switch
|
||||||
|
then don't process this timer as any timers that remained in the list
|
||||||
|
when the lists were switched will have been processed within the
|
||||||
|
prvSampelTimeNow() function. */
|
||||||
|
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
|
||||||
|
if( xTimerListsWereSwitched == pdFALSE )
|
||||||
|
{
|
||||||
|
/* The tick count has not overflowed, has the timer expired? */
|
||||||
|
if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) )
|
||||||
|
{
|
||||||
|
xTaskResumeAll();
|
||||||
|
prvProcessExpiredTimer( xNextExpireTime, xTimeNow );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The tick count has not overflowed, and the next expire
|
||||||
|
time has not been reached yet. This task should therefore
|
||||||
|
block to wait for the next expire time or a command to be
|
||||||
|
received - whichever comes first. The following line cannot
|
||||||
|
be reached unless xNextExpireTime > xTimeNow, except in the
|
||||||
|
case when the current timer list is empty. */
|
||||||
|
vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );
|
||||||
|
|
||||||
|
if( xTaskResumeAll() == pdFALSE )
|
||||||
|
{
|
||||||
|
/* Yield to wait for either a command to arrive, or the block time
|
||||||
|
to expire. If a command arrived between the critical section being
|
||||||
|
exited and this yield then the yield will not cause the task
|
||||||
|
to block. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xTaskResumeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTickType prvGetNextExpireTime( portBASE_TYPE *pxListWasEmpty )
|
||||||
|
{
|
||||||
|
portTickType xNextExpireTime;
|
||||||
|
|
||||||
|
/* Timers are listed in expiry time order, with the head of the list
|
||||||
|
referencing the task that will expire first. Obtain the time at which
|
||||||
|
the timer with the nearest expiry time will expire. If there are no
|
||||||
|
active timers then just set the next expire time to 0. That will cause
|
||||||
|
this task to unblock when the tick count overflows, at which point the
|
||||||
|
timer lists will be switched and the next expiry time can be
|
||||||
|
re-assessed. */
|
||||||
|
*pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList );
|
||||||
|
if( *pxListWasEmpty == pdFALSE )
|
||||||
|
{
|
||||||
|
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ensure the task unblocks when the tick count rolls over. */
|
||||||
|
xNextExpireTime = ( portTickType ) 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xNextExpireTime;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portTickType prvSampleTimeNow( portBASE_TYPE *pxTimerListsWereSwitched )
|
||||||
|
{
|
||||||
|
portTickType xTimeNow;
|
||||||
|
static portTickType xLastTime = ( portTickType ) 0U;
|
||||||
|
|
||||||
|
xTimeNow = xTaskGetTickCount();
|
||||||
|
if( xTimeNow < xLastTime )
|
||||||
|
{
|
||||||
|
prvSwitchTimerLists( xLastTime );
|
||||||
|
*pxTimerListsWereSwitched = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pxTimerListsWereSwitched = pdFALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
xLastTime = xTimeNow;
|
||||||
|
|
||||||
|
return xTimeNow;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portBASE_TYPE prvInsertTimerInActiveList( xTIMER *pxTimer, portTickType xNextExpiryTime, portTickType xTimeNow, portTickType xCommandTime )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xProcessTimerNow = pdFALSE;
|
||||||
|
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime );
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
|
||||||
|
|
||||||
|
if( xNextExpiryTime <= xTimeNow )
|
||||||
|
{
|
||||||
|
/* Has the expiry time elapsed between the command to start/reset a
|
||||||
|
timer was issued, and the time the command was processed? */
|
||||||
|
if( ( ( portTickType ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks )
|
||||||
|
{
|
||||||
|
/* The time between a command being issued and the command being
|
||||||
|
processed actually exceeds the timers period. */
|
||||||
|
xProcessTimerNow = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) )
|
||||||
|
{
|
||||||
|
/* If, since the command was issued, the tick count has overflowed
|
||||||
|
but the expiry time has not, then the timer must have already passed
|
||||||
|
its expiry time and should be processed immediately. */
|
||||||
|
xProcessTimerNow = pdTRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xProcessTimerNow;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvProcessReceivedCommands( void )
|
||||||
|
{
|
||||||
|
xTIMER_MESSAGE xMessage;
|
||||||
|
xTIMER *pxTimer;
|
||||||
|
portBASE_TYPE xTimerListsWereSwitched, xResult;
|
||||||
|
portTickType xTimeNow;
|
||||||
|
|
||||||
|
/* In this case the xTimerListsWereSwitched parameter is not used, but it
|
||||||
|
must be present in the function call. */
|
||||||
|
//xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
|
||||||
|
|
||||||
|
while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL )
|
||||||
|
{
|
||||||
|
xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched );
|
||||||
|
pxTimer = xMessage.pxTimer;
|
||||||
|
|
||||||
|
/* Is the timer already in a list of active timers? When the command
|
||||||
|
is trmCOMMAND_PROCESS_TIMER_OVERFLOW, the timer will be NULL as the
|
||||||
|
command is to the task rather than to an individual timer. */
|
||||||
|
if( pxTimer != NULL )
|
||||||
|
{
|
||||||
|
if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
/* The timer is in a list, remove it. */
|
||||||
|
vListRemove( &( pxTimer->xTimerListItem ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.xMessageValue );
|
||||||
|
|
||||||
|
switch( xMessage.xMessageID )
|
||||||
|
{
|
||||||
|
case tmrCOMMAND_START :
|
||||||
|
/* Start or restart a timer. */
|
||||||
|
if( prvInsertTimerInActiveList( pxTimer, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.xMessageValue ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* The timer expired before it was added to the active timer
|
||||||
|
list. Process it now. */
|
||||||
|
//pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
|
||||||
|
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer, pxTimer->callback_arg );//modify by dave
|
||||||
|
|
||||||
|
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
|
||||||
|
{
|
||||||
|
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xMessage.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY );
|
||||||
|
configASSERT( xResult );
|
||||||
|
( void ) xResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tmrCOMMAND_STOP :
|
||||||
|
/* The timer has already been removed from the active list.
|
||||||
|
There is nothing to do here. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tmrCOMMAND_CHANGE_PERIOD :
|
||||||
|
pxTimer->xTimerPeriodInTicks = xMessage.xMessageValue;
|
||||||
|
configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) );
|
||||||
|
prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case tmrCOMMAND_DELETE :
|
||||||
|
/* The timer has already been removed from the active list,
|
||||||
|
just free up the memory. */
|
||||||
|
vPortFree( pxTimer );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
/* Don't expect to get here. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSwitchTimerLists( portTickType xLastTime )
|
||||||
|
{
|
||||||
|
portTickType xNextExpireTime, xReloadTime;
|
||||||
|
xList *pxTemp;
|
||||||
|
xTIMER *pxTimer;
|
||||||
|
portBASE_TYPE xResult;
|
||||||
|
|
||||||
|
/* Remove compiler warnings if configASSERT() is not defined. */
|
||||||
|
( void ) xLastTime;
|
||||||
|
|
||||||
|
/* The tick count has overflowed. The timer lists must be switched.
|
||||||
|
If there are any timers still referenced from the current timer list
|
||||||
|
then they must have expired and should be processed before the lists
|
||||||
|
are switched. */
|
||||||
|
while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE )
|
||||||
|
{
|
||||||
|
xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||||
|
|
||||||
|
/* Remove the timer from the list. */
|
||||||
|
pxTimer = ( xTIMER * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList );
|
||||||
|
vListRemove( &( pxTimer->xTimerListItem ) );
|
||||||
|
|
||||||
|
/* Execute its callback, then send a command to restart the timer if
|
||||||
|
it is an auto-reload timer. It cannot be restarted here as the lists
|
||||||
|
have not yet been switched. */
|
||||||
|
//pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer );
|
||||||
|
pxTimer->pxCallbackFunction( ( xTimerHandle ) pxTimer, pxTimer->callback_arg ); //modify by dave
|
||||||
|
|
||||||
|
if( pxTimer->uxAutoReload == ( unsigned portBASE_TYPE ) pdTRUE )
|
||||||
|
{
|
||||||
|
/* Calculate the reload value, and if the reload value results in
|
||||||
|
the timer going into the same timer list then it has already expired
|
||||||
|
and the timer should be re-inserted into the current list so it is
|
||||||
|
processed again within this loop. Otherwise a command should be sent
|
||||||
|
to restart the timer to ensure it is only inserted into a list after
|
||||||
|
the lists have been swapped. */
|
||||||
|
xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks );
|
||||||
|
if( xReloadTime > xNextExpireTime )
|
||||||
|
{
|
||||||
|
listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime );
|
||||||
|
listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer );
|
||||||
|
vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START, xNextExpireTime, NULL, tmrNO_DELAY );
|
||||||
|
configASSERT( xResult );
|
||||||
|
( void ) xResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pxTemp = pxCurrentTimerList;
|
||||||
|
pxCurrentTimerList = pxOverflowTimerList;
|
||||||
|
pxOverflowTimerList = pxTemp;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckForValidListAndQueue( void )
|
||||||
|
{
|
||||||
|
/* Check that the list from which active timers are referenced, and the
|
||||||
|
queue used to communicate with the timer service, have been
|
||||||
|
initialised. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
if( xTimerQueue == NULL )
|
||||||
|
{
|
||||||
|
vListInitialise( &xActiveTimerList1 );
|
||||||
|
vListInitialise( &xActiveTimerList2 );
|
||||||
|
pxCurrentTimerList = &xActiveTimerList1;
|
||||||
|
pxOverflowTimerList = &xActiveTimerList2;
|
||||||
|
xTimerQueue = xQueueCreate( ( unsigned portBASE_TYPE ) configTIMER_QUEUE_LENGTH, sizeof( xTIMER_MESSAGE ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE xTimerIsTimerActive( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xTimerIsInActiveList;
|
||||||
|
xTIMER *pxTimer = ( xTIMER * ) xTimer;
|
||||||
|
|
||||||
|
/* Is the timer in the list of active timers? */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
|
/* Checking to see if it is in the NULL list in effect checks to see if
|
||||||
|
it is referenced from either the current or the overflow timer lists in
|
||||||
|
one go, but the logic has to be reversed, hence the '!'. */
|
||||||
|
xTimerIsInActiveList = !( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) );
|
||||||
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
|
return xTimerIsInActiveList;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void *pvTimerGetTimerID( xTimerHandle xTimer )
|
||||||
|
{
|
||||||
|
xTIMER *pxTimer = ( xTIMER * ) xTimer;
|
||||||
|
|
||||||
|
return pxTimer->pvTimerID;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This entire source file will be skipped if the application is not configured
|
||||||
|
to include software timer functionality. If you want to include software timer
|
||||||
|
functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */
|
||||||
|
#endif /* configUSE_TIMERS == 1 */
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
2766
src/os/rtos/source/tasks.c.old
Normal file
2766
src/os/rtos/source/tasks.c.old
Normal file
File diff suppressed because it is too large
Load Diff
@ -129,7 +129,9 @@ tls_os_status_t tls_os_task_create(tls_os_task_t *task,
|
|||||||
* TLS_OS_ERROR
|
* TLS_OS_ERROR
|
||||||
*********************************************************************************************************
|
*********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
|
// This API call is not available in freertos 8.0.0
|
||||||
#if ( INCLUDE_vTaskDelete == 1 )
|
#if ( INCLUDE_vTaskDelete == 1 )
|
||||||
|
#if 0
|
||||||
tls_os_status_t tls_os_task_del(u8 prio,void (*freefun)(void))
|
tls_os_status_t tls_os_task_del(u8 prio,void (*freefun)(void))
|
||||||
{
|
{
|
||||||
if (0 == vTaskDeleteByPriority(configMAX_PRIORITIES - prio, freefun)){
|
if (0 == vTaskDeleteByPriority(configMAX_PRIORITIES - prio, freefun)){
|
||||||
@ -139,6 +141,7 @@ tls_os_status_t tls_os_task_del(u8 prio,void (*freefun)(void))
|
|||||||
|
|
||||||
return TLS_OS_ERROR;
|
return TLS_OS_ERROR;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void))
|
tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void))
|
||||||
{
|
{
|
||||||
@ -163,7 +166,7 @@ tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(voi
|
|||||||
* running when the event arrives.
|
* running when the event arrives.
|
||||||
*********************************************************************************************************
|
*********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
tls_os_status_t tls_os_task_suspend(tls_os_task_t *task)
|
tls_os_status_t tls_os_task_suspend(tls_os_task_t task)
|
||||||
{
|
{
|
||||||
vTaskSuspend(task);
|
vTaskSuspend(task);
|
||||||
|
|
||||||
@ -205,12 +208,18 @@ u8 tls_os_task_schedule_state()
|
|||||||
*
|
*
|
||||||
*********************************************************************************************************
|
*********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
tls_os_status_t tls_os_task_resume(tls_os_task_t *task)
|
tls_os_status_t tls_os_task_resume(tls_os_task_t task)
|
||||||
{
|
{
|
||||||
vTaskResume(task);
|
vTaskResume(task);
|
||||||
|
|
||||||
return TLS_OS_SUCCESS;
|
return TLS_OS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tls_os_status_t tls_os_task_resume_from_isr(tls_os_task_t task)
|
||||||
|
{
|
||||||
|
(void)xTaskResumeFromISR(task);
|
||||||
|
return TLS_OS_SUCCESS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1256,6 +1265,11 @@ u32 tls_os_timer_expirytime(tls_os_timer_t *timer)
|
|||||||
vTaskDelay(ticks);
|
vTaskDelay(ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tls_os_time_delay_until(u32 *previous_ticks , u32 ticks)
|
||||||
|
{
|
||||||
|
vTaskDelayUntil(previous_ticks, ticks);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*********************************************************************************************************
|
*********************************************************************************************************
|
||||||
* task stat info
|
* task stat info
|
||||||
@ -1274,9 +1288,8 @@ void tls_os_disp_task_stat_info(void)
|
|||||||
if(NULL == buf)
|
if(NULL == buf)
|
||||||
return;
|
return;
|
||||||
#if configUSE_TRACE_FACILITY
|
#if configUSE_TRACE_FACILITY
|
||||||
vTaskList((signed char *)buf);
|
vTaskList(buf);
|
||||||
#endif
|
#endif
|
||||||
printf("\n%s\nbuf_len : %d\n", buf, strlen(buf));
|
|
||||||
tls_mem_free(buf);
|
tls_mem_free(buf);
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user