安富莱_STM32-V5开发板_FreeRTOS教程(V1.0)
static QueueHandle_t xQueue1 = NULL
static QueueHandle_t xQueue2 = NULL
typedef struct Msg
{
uint8_t ucMessageID
uint16_t usData[2]
uint32_t ulData[2]
}MSG_T
MSG_T g_tMsg
/*
*********************************************************************************************************
* 函 数 名: AppObjCreate
* 功能说明: 创建任务通信机制
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void AppObjCreate (void)
{
xQueue1 = xQueueCreate(10, sizeof(uint8_t))
if( xQueue1 == 0 )
{
/* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
}
/* 创建 10 个存储指针变量的消息队列,由于 CM3/CM4 内核是 32 位机,一个指针变量占用 4 个字节 */
xQueue2 = xQueueCreate(10, sizeof(struct Msg *))
if( xQueue2 == 0 )
{
/* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
}
}
//初始化定义
uint8_t ucCount = 0
/* while循环里实现向 xQueue2 发送数据 */
ucCount++
/* 向消息队列发数据,如果消息队列满了,等待 10 个时钟节拍 */
if( xQueueSend(xQueue1,
(void *) &ucCount,
(TickType_t)10) != pdPASS )
{
/* 发送失败,即使等待了 10 个时钟节拍 */
printf("向 xQueue1 发送数据失败,即使等待了 10 个时钟节拍\r\n")
}
else
{
/* 发送成功 */
printf("向 xQueue1 发送数据成功\r\n")
}
//初始化定义
MSG_T *ptMsg
/* 初始化结构体指针 */
ptMsg = &g_tMsg
/* 初始化数组 */
ptMsg->ucMessageID = 0
ptMsg->ulData[0] = 0
ptMsg->usData[0] = 0
/* while循环里实现向 xQueue2 发送数据 */
ptMsg->ucMessageID++
ptMsg->ulData[0]++
ptMsg->usData[0]++
/* 使用消息队列实现指针变量的传递 */
if(xQueueSend(xQueue2, /* 消息队列句柄 */
(void *) &ptMsg, /* 发送结构体指针变量 ptMsg 的地址 */
(TickType_t)10) != pdPASS )
{
/* 发送失败,即使等待了 10 个时钟节拍 */
printf("向 xQueue2 发送数据失败,即使等待了 10 个时钟节拍\r\n")
}
else
{
/* 发送成功 */
printf("向 xQueue2 发送数据成功\r\n")
}
static QueueHandle_t xQueue1 = NULL
/*
*********************************************************************************************************
* 函 数 名: vTaskMsgPro
* 功能说明: 使用函数 xQueueReceive 接收任务 vTaskTaskUserIF 发送的消息队列数据(xQueue1)
* 形 参: pvParameters 是在创建该任务时传递的形参
* 返 回 值: 无
* 优 先 级: 3
*********************************************************************************************************
*/
static void vTaskMsgPro(void *pvParameters)
{
BaseType_t xResult
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(300)/* 设置最大等待时间为 300ms */
uint8_t ucQueueMsgValue
while(1)
{
xResult = xQueueReceive(xQueue1, /* 消息队列句柄 */
(void *)&ucQueueMsgValue, /* 存储接收到的数据到变量 ucQueueMsgValue 中 */
(TickType_t)xMaxBlockTime)/* 设置阻塞时间 */
if(xResult == pdPASS)
{
/* 成功接收,并通过串口将数据打印出来 */
printf("接收到消息队列数据 ucQueueMsgValue = %d\r\n", ucQueueMsgValue)
}
else
{
/* 超时 */
bsp_LedToggle(1)
bsp_LedToggle(4)
}
}
}
/*
*********************************************************************************************************
* 函 数 名: vTaskLED
* 功能说明: 使用函数 xQueueReceive 接收任务 vTaskTaskUserIF 发送的消息队列数据(xQueue2)
* 形 参: pvParameters 是在创建该任务时传递的形参
* 返 回 值: 无
* 优 先 级: 2
*********************************************************************************************************
*/
static void vTaskLED(void *pvParameters)
{
MSG_T *ptMsg
BaseType_t xResult
const TickType_t xMaxBlockTime = pdMS_TO_TICKS(200)/* 设置最大等待时间为 200ms */
while(1)
{
xResult = xQueueReceive(xQueue2, /* 消息队列句柄 */
(void *)&ptMsg, /* 这里获取的是结构体的地址 */
(TickType_t)xMaxBlockTime)/* 设置阻塞时间 */
if(xResult == pdPASS)
{
/* 成功接收,并通过串口将数据打印出来 */
printf("接收到消息队列数据 ptMsg->ucMessageID = %d\r\n", ptMsg->ucMessageID)
printf("接收到消息队列数据 ptMsg->ulData[0] = %d\r\n", ptMsg->ulData[0])
printf("接收到消息队列数据 ptMsg->usData[0] = %d\r\n", ptMsg->usData[0])
}
else
{
/* 超时 */
bsp_LedToggle(2)
bsp_LedToggle(3)
}
}
}
/*按键或什么外部触发启动定时器*/
printf("启动单次定时器中断,50ms 后在定时器中断给任务 vTaskMsgPro 发送消息\r\n")
bsp_StartHardTimer(1 ,50000, (void *)TIM_CallBack1)
printf("启动单次定时器中断,50ms 后在定时器中断给任务 vTaskLED 发送消息\r\n")
bsp_StartHardTimer(2 ,50000, (void *)TIM_CallBack2)
/*
*********************************************************************************************************
* 函 数 名: TIM_CallBack1 和 TIM_CallBack2
* 功能说明: 定时器中断的回调函数,此函数被 bsp_StartHardTimer 所调用。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static uint32_t g_uiCount = 0/* 设置为全局静态变量,方便数据更新 */
static void TIM_CallBack1(void)
{
BaseType_t xResult
BaseType_t xHigherPriorityTaskWoken = pdFALSE
/* 中断消息处理,此处省略 */
……
g_uiCount++
/* 向消息队列发数据 */
xQueueSendFromISR(xQueue1,
(void *)&g_uiCount,
&xHigherPriorityTaskWoken)
/* 如果 xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken)
}
static void TIM_CallBack2 (void)
{
MSG_T *ptMsg
BaseType_t xHigherPriorityTaskWoken = pdFALSE
/* 中断消息处理,此处省略 */
……
/* 初始化结构体指针 */
ptMsg = &g_tMsg
/* 初始化数组 */
ptMsg->ucMessageID++
ptMsg->ulData[0]++
ptMsg->usData[0]++
/* 向消息队列发数据 */
xQueueSendFromISR(xQueue2,
(void *)&ptMsg,
&xHigherPriorityTaskWoken)
/* 如果 xHigherPriorityTaskWoken = pdTRUE,那么退出中断后切到当前最高优先级任务执行 */
portYIELD_FROM_ISR(xHigherPriorityTaskWoken)
}
对了,还有重要的一点忘记说明了,用不带OS的APP运行正常,加入OS后就运行一段时间就进入HardFaultException。。。。跳转之前的 *** 作如下:{taskENTER_CRITICAL()//访问临界区资源vDiableAll()__MSR_MSP(*(vu32*)IAP_ADDR)//stm32的第一个4bytes的地址存放的是SP(*(void(*)(void))(*(vu32*)(IAP_ADDR+4)))()//第二个4bytes存放的是RESET的}
查看原帖>>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)