- 简化OS操作
- 对于跑蓝牙协议栈,uart的操作一定要在线程中完成,不然会出现指针异常。
使用ATCMD时,请一定要去图像化界面–BLE–ICALL数量加+1,两个都要哦 - 重定义标准库堆栈: Options–Linker–Extra Options-- 增加:–redirect malloc=os_malloc
–redirect free=os_free
// 【请在全局区调用】
// 声明线程
#pragma data_alignment=8
OS_THREAD_DECLARE(edebug, 2048);
// 声明事件组
OS_EVENT_DECLARE(edebug);
// 声明消息的队列对象
OS_MSG_DECLARE(edebug);
// 从堆栈模块传递的应用程序事件。该类型由应用程序定义,因为它可以随意将事件排队到自己。
typedef struct __PACKED { // object data type
uint8_t *data;
uint8_t len;
queue_msg_event_t event;
} edebug_queue_t;
// 声明软件定时器
OS_TIMER_DECLARE_N(test);
// 【请在函数中使用】
// 创建事件组
OS_EVENT_CREATE(edebug);
// 创建消息队列
OS_MSG_CREATE(edebug);
// 创建软件定时器
OS_TIMER_CREATE(test, OS_TIMER_PERIODIC, 500, NULL);
OS_TIMER_START(test);
static void timer_test_cb(UArg arg) {
if (GPIO_read(CONFIG_GPIO_UWB_RDY) == 0) {
LOGD(“0”);
GPIO_write(CONFIG_GPIO_UWB_RDY, 1);
} else {
LOGD(“1”);
GPIO_write(CONFIG_GPIO_UWB_RDY, 0);
}
}
完整demo
/********************************************************************************
* @file edebug_cc26xx.c
* @author jianqiang.xue
* @version V2.0.0
* @date 2023-03-08
* @brief 对于跑蓝牙协议栈,uart的操作一定要在线程中完成,不然会出现指针异常。
使用ATCMD时,请一定要去图像化界面--BLE--ICALL数量加+1,两个都要哦
重定义标准库堆栈: Options--Linker--Extra Options-- 增加:--redirect malloc=os_malloc
--redirect free=os_free
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "os_api.h"
#include <ti_drivers_config.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/gpio/GPIOCC26XX.h>
/* Private Includes ----------------------------------------------------------*/
#include "edebug.h"
/* Private Define ------------------------------------------------------------*/
#define USE_WAKEUP_PIN
#ifdef USE_WAKEUP_PIN
#define WAKEUP_PIN(state) GPIO_write(CONFIG_GPIO_INT5, state); // 低电平--唤醒 高电平--睡眠
#else
#define WAKEUP_PIN(state)
#endif
#define EDEBUG_WRITE_EVT UTIL_QUEUE_EVENT_ID // Event_Id_30
#define EDEBUG_MOVE_DATA_EVT Event_Id_27
#define ET_ALL_EVENTS (EDEBUG_WRITE_EVT | EDEBUG_MOVE_DATA_EVT)
/* Private Variables ---------------------------------------------------------*/
#if defined(ATCMD_EN) || defined(UART_OUT)
#include <ti/drivers/UART.h>
#include <ti/drivers/uart/UARTCC26XX.h>
#include "ti_drivers_config.h"
static UART_Handle g_uart_handle = NULL;
#ifdef ATCMD_EN
static char g_tx_buff[RX_MAX_LEN] = {0};
static char g_rx_buff[RX_MAX_LEN] = {0};
static bool g_init = false;
// 声明线程
#pragma data_alignment=8
OS_THREAD_DECLARE(edebug, 2048);
// 声明事件组
OS_EVENT_DECLARE(edebug);
// 声明消息的队列对象
OS_MSG_DECLARE(edebug);
// 声明软件定时器
//OS_TIMER_DECLARE_N(test);
// 从堆栈模块传递的应用程序事件。该类型由应用程序定义,因为它可以随意将事件排队到自己。
typedef struct __PACKED { // object data type
uint8_t *data;
uint8_t len;
queue_msg_event_t event;
} edebug_queue_t;
extern atcmd_info_t atcmd$$Base;
extern atcmd_info_t atcmd$$Limit;
static atcmd_pack_t* g_pack = NULL;
#endif
#endif
#include <inc/hw_types.h>
#define IOID2PIN(ioid) (1 << ioid)
extern const GPIOCC26XX_Config GPIOCC26XX_config;
typedef struct {
uint8_t ioid;
uint8_t added; /* 0 = pin has not been added to gpioPinState */
uint16_t config;
} PinConfig;
uint_fast8_t GPIO_read2(uint_least8_t index)
{
unsigned int value;
PinConfig *config = (PinConfig *) &GPIOCC26XX_config.pinConfigs[index];
uint16_t type = config->config & 0x07;
if (type % 2) { // 奇数-输入脚
value = GPIO_readMultiDio(IOID2PIN(config->ioid));
value = value & (IOID2PIN(config->ioid)) ? 1 : 0;
} else { // 偶数-输出脚
value = (HWREG(GPIO_BASE + GPIO_O_DOUT31_0) >> config->ioid) & 1;
}
// LOGD("%d,%d,%x,%x,%x", index, config->ioid, value, type, IOID2PIN(config->ioid));
return (value);
}
static void timer_test_cb(UArg arg) {
//GPIO_toggle(CONFIG_GPIO_WAKEUP);
//LOGD("IO:%d", GPIO_read2(CONFIG_GPIO_WAKEUP));
}
#if defined(ATCMD_EN) || defined(UART_OUT)
/**
* @brief 发送AT指令,不需要应答
* @note 举例: AT+TEST=123 ecu_ble_send_atcmd("AT+TEST=", "123", strlen("123"));
* @param at_head: AT指令头
* @param data: 数据
* @param len: 长度
* @retval 0--成功 -1 --申请pool失败 -2 --线程不存在 -3 --没有分配块区
* -4 --没有创建msg队列 -5 --堆区剩余空间不足 -6 --put队列失败(队列满)
*/
int8_t edebug_send_atcmd(char* at_head, uint8_t* data, uint8_t len) {
uint8_t *p = malloc(len + strlen(at_head) + strlen("\r\n") + 1); // 开辟空间存放数据
uint8_t p_len = 0;
if (p == NULL) return -5;
memcpy(p, at_head, strlen(at_head)); // 写报头
p_len = strlen(at_head);
memcpy(p + p_len, data, len); // 写数据
p_len += len;
memcpy(p + p_len, "\r\n", strlen("\r\n"));
// 写报尾
p_len += strlen("\r\n");
int8_t ret = edebug_enqueue_msg(QUEUE_MSG_EVENT_SEND, p, p_len);
free(p);
return ret;
}
/**
* @brief 消息入队,然后由线程发送
* @param pData: 待发送数据
* @param len: 数据长度
* @param event: queue_msg_event_t
* @retval 0--成功 -1 --条件不满足 -2 --线程不存在 -3 --队列创建失败(空间不足)
* -4 --没有创建msg队列 -5 --堆区剩余空间不足 -6 --put队列失败(队列满)
*/
int8_t edebug_enqueue_msg(queue_msg_event_t event, void* data, uint8_t len) {
if (g_uart_handle == NULL && event == QUEUE_MSG_EVENT_SEND)
return -1;
if (OS_EVENT_HANDLE(edebug) == NULL)
return -2;
if (OS_MSG_QUEUE_HANDLE(edebug) == NULL)
return -4;
uint8_t *p = NULL;
if (event < 0x80) {
p = malloc(len);
if (p == NULL) return -5;
memcpy(p, data, len);
}
edebug_queue_t* pMsg = malloc(sizeof(edebug_queue_t));
// Create dynamic pointer to message.
if (pMsg) {
pMsg->len = len;
pMsg->data = p;
pMsg->event = event;
// Enqueue the message.
uint8_t success = OS_MSG_ENQUEUE_MSG_N(edebug, pMsg);
if (success) return 0;
free(pMsg);
}
if (event < 0x80) free(p);
return -3;
}
void edebug_send(uint8_t* data, uint16_t len) {
if (g_init) {
int8_t ret = edebug_enqueue_msg(QUEUE_MSG_EVENT_SEND, data, len);
if (ret != 0) {
#ifdef UART_OUT
WAKEUP_PIN(0);
if (g_uart_handle == NULL) return;
UART_write(g_uart_handle, data, (int)len);
WAKEUP_PIN(1);
#endif
return;
}
}
}
#endif
#ifdef ATCMD_EN
static void uart_read_callback(UART_Handle handle, void* rx_buff, size_t size) {
edebug_enqueue_msg(QUEUE_MSG_EVENT_RECEIVE, rx_buff, size);
UART_read(handle, g_rx_buff, RX_MAX_LEN);
}
bool atcmd_msg_handle(atcmd_pack_t* pack) {
bool match = false;
atcmd_info_t* atcmd;
for (atcmd = &atcmd$$Base; atcmd < &atcmd$$Limit; atcmd++) {
if (atcmd->name != (char *)0xFFFFFFFF) { // 针对FLASH默认值为0xFFFFFFFFF时,不进行比较
if (strncmp((char*)(pack->data), atcmd->name, strlen(atcmd->name)) == 0) {
match = true;
break;
}
}
}
if (match) {
// 裁剪 AT^XXXX=(保留)\r\n
pack->len -= (strlen(atcmd->name) + 2); // 3 == \r\n
pack->data += strlen(atcmd->name); // 移除前面的内容,并包含'=' or '?' or '=?'
pack->data[pack->len + 1] = '\0';
if (atcmd->callback(pack) == 2) {
g_pack = pack;
}
return 0;
}
return -1;
}
bool atcmd_asysn_response(uint8_t *data, uint8_t len) {
if (g_pack) g_pack->reply(data, len);
return 0;
}
#endif
static void uart_init(void) {
#if defined(ATCMD_EN) || defined(UART_OUT)
if (g_uart_handle) return;
/* Call driver init functions */
UART_init();
UART_Params params;
/* Create a UART with data processing off. */
UART_Params_init(¶ms);
params.writeMode = UART_MODE_BLOCKING;
params.writeDataMode = UART_DATA_BINARY;
params.readMode = UART_MODE_CALLBACK;
params.readDataMode = UART_DATA_BINARY;
params.baudRate = 256000;
#ifdef ATCMD_EN
params.readCallback = uart_read_callback;
#endif
// Open the UART and initiate the first read
#ifdef CONFIG_DISPLAY_UART
g_uart_handle = UART_open(CONFIG_DISPLAY_UART, ¶ms);
#else
g_uart_handle = UART_open(CONFIG_UART_0, ¶ms);
#endif
if (!g_uart_handle) while(1);
g_init = true;
#endif
#ifdef ATCMD_EN
UART_control(g_uart_handle, UARTCC26XX_CMD_RX_FIFO_FLUSH, NULL); // 清空接收缓存区
UART_control(g_uart_handle, UARTCC26XX_CMD_RETURN_PARTIAL_ENABLE, NULL); // 开启空闲接收回调
UART_read(g_uart_handle, g_rx_buff, RX_MAX_LEN);
#endif
}
static void uart_deinit(void) {
if (g_uart_handle == NULL) return;
UART_writeCancel(g_uart_handle);
UART_readCancel(g_uart_handle);
UART_close(g_uart_handle);
g_uart_handle = NULL;
}
/**
* @brief 初始化 线程事件组/RTT/UART
* @note 硬件外设初始化
*/
static void _init(void) {
#ifdef RTT_OUT
SEGGER_RTT_Init();
SEGGER_RTT_SetTerminal(0);
#else
uart_init();
#endif
}
#ifdef ATCMD_EN
static void edebug_task_init(void) {
// 创建事件组
OS_EVENT_CREATE(edebug);
// 创建消息队列
OS_MSG_CREATE(edebug);
// 创建软件定时器
//OS_TIMER_CREATE(test, OS_TIMER_PERIODIC, 500, NULL);
//OS_TIMER_START(test);
_init();
}
static int flashcmd_cmd_2640_read(flashcmd_pack_t* pack) {
uint8_t buff[20] = "nonsupport\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int flashcmd_cmd_tbox_read(flashcmd_pack_t* pack) {
uint8_t buff[20] = "nonsupport\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int flashcmd_cmd_2642_read(flashcmd_pack_t* pack) {
uint8_t buff[20] = "nonsupport\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int flashcmd_cmd_se_applet_read(flashcmd_pack_t* pack) {
uint8_t buff[20] = "nonsupport\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int flashcmd_cmd_se_cos_read(flashcmd_pack_t* pack) {
uint8_t buff[20] = "nonsupport\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int flashcmd_cmd_ee_data_read(flashcmd_pack_t* pack) {
return 0;
}
/**
* @brief flash命令 接收处理
* @note flash管理_V1.4_20211027.xls 通过串口向2642的外部flash读取数据
* @param *pack: 数据指针
* @retval 0--失败 1--成功
*/
static bool flashcmd_msg_handle(flashcmd_pack_t *pack) {
if (pack == NULL) return false;
if (pack->len < 7) return false;
if (pack->data[0] == 0x3C && pack->data[1] == 0xC3) {
// CMD_2640_READ 2640 img升级文件,取出
if (pack->data[2] == 0x00 && pack->data[3] == 0x01) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_2640_read(pack);
return true;
}
// CMD_S9_READ(在BOOT中有效,通过ECU刷写S9) CMD_TBOX_READ(在APP中有效)
else if (pack->data[2] == 0x00 && pack->data[3] == 0x03) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_tbox_read(pack);
return true;
}
// CMD_2642_READ 2642 img升级文件,取出
else if (pack->data[2] == 0x00 && pack->data[3] == 0x05) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_2642_read(pack);
return true;
}
// CMD_SE_APPLET_READ se_applet img升级文件,取出
else if (pack->data[2] == 0x00 && pack->data[3] == 0x07) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_se_applet_read(pack);
return true;
}
// CMD_SE_COS_READ se_cos img升级文件,取出
else if (pack->data[2] == 0x00 && pack->data[3] == 0x09) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_se_cos_read(pack);
return true;
}
// CMD_EE_DATA_READ ee_data 2642辅助存储的ee数据,取出
else if (pack->data[2] == 0x00 && pack->data[3] == 0x0B) {
// 裁剪 0x3CC3 CMD(2byte)(保留)\r\n
pack->len -= (4 + 2); // 2 == \r\n
pack->data += 4; // 移除前面的内容
pack->data[pack->len + 1] = '\0';
flashcmd_cmd_ee_data_read(pack);
return true;
}
}
return false;
}
static void queue_dispose(void) {
while (! OS_MSG_IS_EMPTY(edebug)) {
edebug_queue_t* pmsg = (edebug_queue_t*) OS_MSG_DEQUEUE_MSG(edebug);
if (pmsg == NULL) continue;
switch (pmsg->event) {
case QUEUE_MSG_EVENT_DEINIT:
WAKEUP_PIN(1);
uart_deinit();
break;
case QUEUE_MSG_EVENT_INIT:
WAKEUP_PIN(0);
uart_init();
break;
case QUEUE_MSG_EVENT_RECEIVE:
if (strncmp((char *)pmsg->data, "AT+", 3) == 0) {
atcmd_pack_t pack;
pack.data = pmsg->data;
pack.len = pmsg->len;
pack.reply = edebug_send;
atcmd_msg_handle(&pack);
} else if (pmsg->len > 2 && pmsg->data[0] == 0x3c && pmsg->data[1] == 0xc3) {
flashcmd_pack_t pack;
pack.data = pmsg->data;
pack.len = pmsg->len;
pack.reply = edebug_send;
flashcmd_msg_handle(&pack);
}
break;
case QUEUE_MSG_EVENT_RX_TIMEOUT:
break;
// 最低优先级处理
case QUEUE_MSG_EVENT_SEND:
if (g_uart_handle == NULL) return;
WAKEUP_PIN(0);
UART_write(g_uart_handle, pmsg->data, (int)pmsg->len);
WAKEUP_PIN(1);
break;
default:
break;
}
if (pmsg->event < 0x80) free(pmsg->data);
free(pmsg);
}
}
static void task_edebug(UArg arg0, UArg arg1) {
edebug_task_init();
LOGD("start");
for (;;) {
uint32_t events;
events = OS_EVENT_PEND(edebug);
if (events & EDEBUG_WRITE_EVT) {
queue_dispose();
}
if (events & EDEBUG_MOVE_DATA_EVT) {
}
}
}
#endif
//*****************************
bool edebug_is_normal(void) {
return g_uart_handle ? true : false;
}
void edebug_init(void) {
#ifdef ATCMD_EN
OS_THREAD_CREATE(edebug, OS_PRIORITY_LOW);
#endif
}
static uint8_t g_mode = 0;
static bool lock = 0;
void log_trace(const char* format, ...) {
va_list p;
int len;
if (g_mode) goto s;
if (lock) return;
lock = true;
s:
va_start(p, format);
len = vsprintf(g_tx_buff, format, p);
va_end(p);
edebug_send((uint8_t *)g_tx_buff, len);
lock = false;
}
void edebug_set_mode(uint8_t mode) {
g_mode = mode;
}
#ifdef ATCMD_EN
// 在功能模块中定义一个标准函数
static int test0(atcmd_pack_t *pack) {
uint8_t buff[20] = "test0\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int test1(atcmd_pack_t *pack) {
uint8_t buff[20] = "test1\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
static int test2(atcmd_pack_t *pack) {
if (pack->len == 0)
return -1;
uint8_t argc = 1; //'='后面如果有长度,就一定有1个参数
// 计算参数个数
for (uint16_t i = 0; i < pack->len; i++) {
if (pack->data[i] == ',')
argc++;
}
if (argc != 2) return -1;
uint8_t buff[20] = "";
uint32_t num = 0, num1 = 0;
sscanf((char*)(pack->data), "%d,%d", &num, &num1);
snprintf((char*)buff, 20, "%d,%d"AT_OK, num, num1);
pack->reply(buff, strlen((char*)buff));
return 1;
}
static int test3(atcmd_pack_t *pack) {
uint8_t buff[20] = "test3\r\n";
strcat((char*)buff, AT_OK);
pack->reply(buff, strlen((char*)buff));
return 0;
}
// 注册AT指令,传入标准函数
ATCMD_INIT("AT+TEST=?", test0);
ATCMD_INIT("AT+TEST?", test1);
ATCMD_INIT("AT+TEST=", test2);
ATCMD_INIT("AT+TEST", test3);
#endif
/********************************************************************************
* @file os_api.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2023-03-07
* @brief 支持 TI_OS
********************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "os_api.h"
/* Public function prototypes -----------------------------------------------*/
/*********************************OS_KERNEL***********************************/
os_status os_kernel_initialize(void) {
/* Initialize ICall module */
ICall_init();
return OS_OK;
}
os_status os_kernel_start(void) {
/* enable interrupts and start SYS/BIOS */
BIOS_start();
return OS_OK;
}
uint32_t os_kernel_stop(void) {
BIOS_exit(0);
return OS_OK;
}
os_status os_delay(uint32_t ms) {
Task_sleep(ms);
return OS_OK;
}
uint32_t os_get_tick(void) {
return Clock_getTicks();
}
uint32_t os_get_state(void) {
return OS_OK;
}
void* os_malloc(uint32_t size) {
return ICall_malloc((uint16_t)size);
}
void* os_calloc(uint32_t size) {
return ICall_malloc((uint16_t)size);
}
uint8_t os_free(void* p) {
ICall_free(p);
return 0;
}
/********************************************************************************
* @file os_api.h
* @author jianqiang.xue
* @version V1.0.0
* @date 2023-03-07
* @brief 支持 TI_OS
********************************************************************************/
#ifndef OS_API_H_
#define OS_API_H_
#include <stdint.h>
#include <stdbool.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <icall.h>
#include "util.h"
/// Timeout value.
#define OS_WAIT_FOREVER 0xFFFFFFFFU ///< wait forever timeout value
/************************************OS_KERNEL************************************/
typedef enum {
OS_OK = 0, ///< function completed; no error or event occurred.
OS_EVENT_SIGNAL = 0x08, ///< function completed; signal event occurred.
OS_EVENT_MESSAGE = 0x10, ///< function completed; message event occurred.
OS_EVENT_MAIL = 0x20, ///< function completed; mail event occurred.
OS_EVENT_TIMEOUT = 0x40, ///< function completed; timeout occurred.
OS_ERROR_PARAMETER = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
OS_ERROR_RESOURCE = 0x81, ///< resource not available: a specified resource was not available.
OS_ERROR_TIMEOUTRESOURCE = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
OS_ERROR_ISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
OS_ERROR_ISRRECURSIVE = 0x83, ///< function called multiple times from ISR with same object.
OS_ERROR_PRIORITY = 0x84, ///< system cannot determine priority or thread has illegal priority.
OS_ERROR_NOMEMORY = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
OS_ERROR_VALUE = 0x86, ///< value of a parameter is out of range.
OS_ERROR_OS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
} os_status;
os_status os_kernel_initialize (void);
os_status os_kernel_start(void);
uint32_t os_kernel_stop(void);
os_status os_delay(uint32_t ms);
uint32_t os_get_tick(void);
uint32_t os_get_state(void);
void* os_malloc(uint32_t size);
void* os_calloc(uint32_t size);
uint8_t os_free(void *p);
/************************************OS_THREAD************************************/
typedef enum {
OS_PRIORITY_IDLE = 0, // idle (lowest)
OS_PRIORITY_LOW = 1, // low
OS_PRIORITY_BELOWNORMAL = 2, // below normal
OS_PRIORITY_NORMAL = 3, // normal (default)
OS_PRIORITY_ABOVENORMAL = 4, // above normal
OS_PRIORITY_HIGH = 5, // high 【BLE协议栈任务】
OS_PRIORITY_REALTIME = 6, // realtime (highest)
OS_PRIORITY_ERROR = 0x84 // system cannot determine priority or thread has illegal priority
} os_priority_t;
// 定义线程所需的变量和回调声明(请在全局区调用)
#define OS_THREAD_DECLARE(name, stacksz) \
static uint8_t g_task_##name##_stack[stacksz]; \
static void task_##name(UArg arg0, UArg arg1); \
static const uint16_t g_task_##name##_stacksz = stacksz; \
Task_Struct g_task_##name##_t;
// 创建线程(请在函数中使用)
#define OS_THREAD_CREATE(name, PRIORITY) { \
Task_Params task_##name##_params; \
Task_Params_init(&task_##name##_params); \
task_##name##_params.stack = g_task_##name##_stack; \
task_##name##_params.stackSize = g_task_##name##_stacksz; \
task_##name##_params.priority = PRIORITY; \
Task_construct(&g_task_##name##_t, task_##name, &task_##name##_params, NULL); \
}
/************************************OS_TIMER************************************/
typedef enum {
OS_TIMER_ONCE = 0, ///< one-shot timer
OS_TIMER_PERIODIC = 1 ///< repeating timer
} os_timer_t;
#define OS_TIMER_STRUCT(name) g_##name##_timer_struct
// 定义软定时器所需的变量和回调声明(请在全局区调用)
#define OS_TIMER_DECLARE_N(name) \
Clock_Struct g_##name##_timer_struct; \
static void timer_##name##_cb(UArg arg);
// 创建软定时器并指定周期类型(单次/循环)(请在函数中使用)
#define OS_TIMER_CREATE(name, cycle_t, cycle_ms, arg) { \
if (cycle_t == OS_TIMER_ONCE) { \
Util_constructClock(&g_##name##_timer_struct, timer_##name##_cb, \
cycle_ms, 0, false, (UArg)arg); \
} else { \
Util_constructClock(&g_##name##_timer_struct, timer_##name##_cb, \
cycle_ms, cycle_ms, false, (UArg)arg); \
} \
}
// 软定时器是运行状态吗
#define OS_TIMER_IS_RUNNING() Util_isActive(&g_##name##_timer_struct)
// 启动软定时器(请在函数中使用)
#define OS_TIMER_START(name) { \
Util_startClock(&g_##name##_timer_struct); \
}
// 启动软定时器(请在函数中使用)
#define OS_TIMER_RESTART(name, ms) { \
Util_restartClock(&g_##name##_timer_struct, ms); \
}
// 停止软定时器(请在函数中使用)
#define OS_TIMER_STOP(name) { \
Util_stopClock(&g_##name##_timer_struct); \
}
/************************************OS_QUEUE************************************/
#define OS_MSG_QUEUE_STRUCT(name) g_##name##_queue_struct
#define OS_MSG_QUEUE_HANDLE(name) g_##name##_queue_handle
// 定义消息队列所需的变量和回调声明(请在全局区调用)
#define OS_MSG_DECLARE(name) \
Queue_Struct g_##name##_queue_struct; \
Queue_Handle g_##name##_queue_handle;
// 创建消息队列(请在函数中使用)
#define OS_MSG_CREATE(name) g_##name##_queue_handle = Util_constructQueue(&g_##name##_queue_struct)
// 消息入队
#define OS_MSG_ENQUEUE_MSG(name, sync_handle, pmsg) Util_enqueueMsg(g_##name##_queue_handle, sync_handle, (uint8_t*)pmsg);
// 消息入队(使用默认线程ID)
#define OS_MSG_ENQUEUE_MSG_N(name, pmsg) Util_enqueueMsg(g_##name##_queue_handle, g_##name##_event, (uint8_t*)pmsg);
// 消息出队
#define OS_MSG_DEQUEUE_MSG(name) Util_dequeueMsg(g_##name##_queue_handle)
// 消息队列(数量)是空吗
#define OS_MSG_IS_EMPTY(name) Queue_empty(g_##name##_queue_handle)
/************************************OS_EVENT************************************/
#define OS_EVENT_HANDLE(name) g_##name##_event
#define OS_EVENT_ID(name) g_##name##_entity_id
// 定义事件所需的变量和回调声明(请在全局区调用)
#define OS_EVENT_DECLARE(name) \
ICall_SyncHandle g_##name##_event; /* 用于全局检查消息的源和/或目的地的实体ID*/ \
ICall_EntityID g_##name##_entity_id; /* 用于全局检查消息的源和/或目的地的实体ID */
// 创建事件组(请在函数中使用)
#define OS_EVENT_CREATE(name) ICall_registerApp(&g_##name##_entity_id, &g_##name##_event)
// 发送事件
#define OS_EVENT_POST(name, event) Event_post(g_##name##_event, event)
// 等待事件
#define OS_EVENT_PEND(name) Event_pend(g_##name##_event, Event_Id_NONE, ET_ALL_EVENTS, ICALL_TIMEOUT_FOREVER)
/************************************OS_SEM************************************/
#define OS_SEM_STRUCT(name) g_##name##_sem_struct
#define OS_SEM_HANDLE(name) g_##name##_sem_handle
// 定义事件所需的变量和回调声明(请在全局区调用)
#define OS_SEM_DECLARE(name) \
Semaphore_Struct g_##name##_sem_struct; \
Semaphore_Handle g_##name##_sem_handle;
// 创建信号量(请在函数中使用) 构造一个用作资源锁的信号量对象,初始计数为num
#define OS_SEM_CREATE(name, num) { \
Semaphore_Params sem_params_##name; \
Semaphore_Params_init(&sem_params_##name); \
Semaphore_construct(&g_##name##_sem_struct, num, &sem_params_##name); \
g_##name##_sem_handle = Semaphore_handle(&g_##name##_sem_struct); \
}
// 发送信号量
#define OS_SEM_POST(name) Semaphore_post(g_##name##_sem_handle)
// 等待信号量 ms=-1 无限等待 ms=0 不等待 返回值:false-timeout true--ok
#define OS_SEM_PEND(name, ms) Semaphore_pend(g_##name##_sem_handle, ms)
#endif
中断开关 source\ti\devices\cc13x2_cc26x2\driverlib\cpu.c
//*****************************************************************************
//
// !\brief禁用所有外部中断
// !
// !使用此功能禁用所有系统中断。该函数为:
// !实现为CPSID指令的包装器函数。
// !
// !\return返回输入项\b PRIMASK的状态
//
//*****************************************************************************
external uint32_t CPUcpsid(void);
//*****************************************************************************
//
// !获取当前的中断状态。
// !
// !使用该函数可以检索中断的当前状态。这
// !函数实现为一个包装器函数,返回的状态
// !PRIMASK。
// !
// !\return返回\b PRIMASK的状态(表示是否中断
// !启用或禁用)。
//
//*****************************************************************************
externn uint32_t CPUprimask(void);
//*****************************************************************************
//
// !\brief启用所有外部中断
// !
// !使用此功能启用所有系统中断。该函数为:
// !实现为CPSIE指令的包装函数。
// !
// !\return返回输入项\b PRIMASK的状态
//
//*****************************************************************************
externn uint32_t CPUcpsie(void);
//*****************************************************************************
//
// !获取中断优先级禁用级别。
// !
// !使用此函数获取将被禁用的优先级
// !优先级较低的中断。
// !
// !\return返回\b BASEPRI寄存器的值
//
//*****************************************************************************
CPUbasepriGet(void);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
2020-03-28 [ESP8266] 最新的SDK,下载办法