用STM32CubeMx创建的FreeRTOS可以运行多少个实例

用STM32CubeMx创建的FreeRTOS可以运行多少个实例,第1张

我第一次使用STM32CubeMx,创建了一个简单的FreeRTOS代码。硬件平台是STM32F103RCT6。根据原代码,在freertosc文件内的函数 MX_FREERTOS_Init(void)内,调用osThreadCreate创建线程,默认生成的StartDefaultTask线程。我按照StartDefaultTask的代码,在 MX_FREERTOS_Init(void)内用osThreadCreate创建另外两个线程,分别为LEDTask和MeasureTempTask。

当三个线程同时创建的话,OS跑不起来,连StartDefaultTask都没有执行。

如果,只创建其中任意的两个线程,OS就可以跑起来。

FreeRTOS本身可以执行多个线程,但STM32CubeMx好像是用CMSIS来重新封装FreeRTOS,是不是CMSIS限制了执行线程的数量?

另外,我测试过,如果在StartDefaultTask线程内,创建另外的两个线程,OS除了执行StartDefaultTask线程外,只执行另外创建的第一个线程。

按地址传递(Passing by reference)是一个使函数返回多个值的有效方法。例如,下面是一个函数,它可以返回第一个输入参数的前一个和后一个数值。

// more than one returning value

#include <iostreamh>

void prevnext (int x, int& prev, int& next)

{

STM32W108两点间及多点间的通信实例很多,技术上很简单,可参考如下代码进行调试:

程序的设计基于SimpleMac协议栈进行,根据官方提供的MAC协议栈示例代码进行的裁剪更改,

功能描述:向参数中传入的地址发送类型负载类型为PT_LED的数据包

输入参数:vddMillivolts为发送的16位数据,dstShortAddr为目的地址,sendDirectly为调用不同发送函数的表示符。

输出参数:无

/

voidsendVddDataPacket2(u16 vddMillivolts, u16 dstShortAddr, boolean sendDirectly)

{

u8 packet[128];

//对数据包进行包装

packet[0] = (15+2); //长度

packet[1] = FCF_DATA + FCF_ACKREQ +FCF_INTRAPAN; //帧类型

packet[2] = FCF_SHORTDST + FCF_SHORTSRC; //地址类型

currSeqNum++; //数据包序列号

packet[3] = currSeqNum;

packet[4] =(ST_RadioGetPanId()>>0)&0xFF; //目标PAN ID

packet[5] =(ST_RadioGetPanId()>>8)&0xFF;

packet[6] =(dstShortAddr>>0)&0xFF; //目标Node ID

packet[7] =(dstShortAddr>>8)&0xFF;

packet[8] =(ST_RadioGetNodeId()>>0)&0xFF; //源PAN ID

packet[9] =(ST_RadioGetNodeId()>>8)&0xFF;

packet[10] = PT_LED; //数据包类型

packet[11] =(vddMillivolts>>0)&0xFF; //发送的16位数据

packet[12] = (vddMillivolts>>8)&0xFF;

//归零Tx SFD有效负载,MSB用于指示SFD有效

packet[13] = 0;

packet[14] = 0;

packet[15] = 0;

enqueueTxPacket(sendDirectly,dstShortAddr, packet, 13); //调用发送函数

//发送完成后令LED_D3先灭后亮闪烁一次,之后串口输出“send already!”

#ifdefPLANET_ROLE

halSetLed(LED_D3);

halCommonDelayMilliseconds(500);//500ms

halClearLed(LED_D3);

#endif

printf("send already!\r\n");

}

接收数据

/

功能描述:对接收的数据包进行解析解码处理,并根据不同类型的数据包执行不同的 *** 作,数据包信息通过数据包回调函数保存在结构体变量rxData中

输入参数:无

输出参数:无

/

voidprocessRxPacket(void)

{

//不同的数据包类型,不同的处理

switch(packetType) {

case (GENERIC_DATA_PACKET): //普通类型数据包

RX_DETAILS(printf("GENERIC_DATA_PACKET\r\n");)

#ifdefSUN_ROLE

case (LED_PACKET): //PT_LED数据包

printf("Message from myPLANET\r\n");

halSetLed(LED_D1); //点亮LED

halCommonDelayMilliseconds(500);//延时500ms

halClearLed(LED_D1);

break;

#endif

case (SUN_SEARCH_PACKET): //处理搜索父节点的数据包

RX_DETAILS(printf("SUN_SEARCH_PACKET\r\n");)

for(i=0;i<PLANET_TABLE_SIZE;i++) //扫描子节点数组

{

if(!planetTable[i]active) //判断是否有有效空间

{

packet[0] = (24+2); //数据包长度

packet[1] = FCF_DATA; //帧类型

packet[2] = FCF_LONGDST +FCF_LONGSRC; //地址类型

currSeqNum++; //数据包序列号

packet[3]=currSeqNum;

packet[4] =(0xFFFF>>0)&0xFF; //16位短目标地址

packet[5] =(0xFFFF>>8)&0xFF;

memcpy((packet+6), longSrcAddr, 8);//64位长目标地址

packet[14] =(ST_RadioGetPanId()>>0)&0xFF; //16位源PAN ID

packet[15] =(ST_RadioGetPanId()>>8)&0xFF;

memcpy((packet+16), ST_RadioGetEui64(),8); //64位长源地址

packet[24] = PT_SUN_AVAILABLE; //负载类型

enqueueTxPacket(TRUE, 0xFFFF, packet,0); //广播

break;

}

}

break;

case (SUN_AVAILABLE_PACKET): //SUN节点发送的父节点可用数据包

RX_DETAILS(printf("SUN_AVAILABLE_PACKET\r\n");)

if(availableSunFound) //如果已加入网络,则停止父节点搜索

{

return;

}

if(srcPanId!=MyPANID) //如果PANID不同,则不处理此数据包

{

goto stopProcessing;

}

availableSunFound=TRUE;

ST_RadioSetPanId(srcPanId); //设置节点PANID

packet[0] = (22+2); //数据包长度

packet[1] = FCF_DATA + FCF_ACKREQ +FCF_INTRAPAN; //帧类型

packet[2] = FCF_LONGDST + FCF_LONGSRC; //地址类型

currSeqNum++; //数据包序列号

packet[3]=currSeqNum;

packet[4] =(ST_RadioGetPanId()>>0)&0xFF; //16位短目标地址

packet[5] =(ST_RadioGetPanId()>>8)&0xFF;

memcpy((packet+6), longSrcAddr, 8); //64位长目标地址

memcpy((packet+14), ST_RadioGetEui64(),8); //64位长源地址

packet[22] = PT_JOIN_REQUEST; //负载类型

enqueueTxPacket(TRUE, 0xFFFF, packet, 0);//单播发送请求加入网络数据包

break;

case (JOIN_REQUEST_PACKET): //SUN节点收到请求加网的包

RX_DETAILS(printf("JOIN_REQUEST_PACKET\r\n");) //串口终端显示

{

u8 flag=0;

u8 pt= PT_JOIN_DENIED; //负载类型

u8 assignedShortId[2] = {0xFE, 0xFF};

packet[0] = (24+2); //数据包长度

packet[1] = FCF_DATA + FCF_ACKREQ +FCF_INTRAPAN; //帧类型

packet[2] = FCF_LONGDST + FCF_LONGSRC;//地址类型

currSeqNum++; //数据包序列号

packet[3]=currSeqNum;

packet[4] =(ST_RadioGetPanId()>>0)&0xFF; //16位短目标地址

packet[5] =(ST_RadioGetPanId()>>8)&0xFF;

memcpy((packet+6), longSrcAddr, 8);//64位长目标地址

memcpy((packet+14), ST_RadioGetEui64(),8); //64位长源地址

/搜寻表中是否存在与加网节点相同的64位长地址,如果有则覆盖,若没有则继续遍历表/

for(i=0;i<PLANET_TABLE_SIZE;i++)

{

u8 k=0;

while(k<8)

{

if(planetTable[i]longAddr[k]!=rxDatapacket[14+k])

break;

k++;

}

if(k==8)

{

planetTable[i]active = TRUE;

shortAddrCounter++;

planetTable[i]shortAddr =shortAddrCounter;

pt = PT_JOIN_ACCEPTED; //允许加入网络负载类型

assignedShortId[0] =(shortAddrCounter>>0)&0xFF;

assignedShortId[1] =(shortAddrCounter>>8)&0xFF;

printf("Join: Planet 0x%04X(index %d) has joined the network\r\n",

shortAddrCounter, i);

flag=1;

break;

}

}

if(flag==0) //如果没有找到相同长地址,则查找空缺位置加进去

{

for(i=0;i<PLANET_TABLE_SIZE;i++)

if(!planetTable[i]active) {

planetTable[i]active = TRUE;

shortAddrCounter++;

planetTable[i]shortAddr =shortAddrCounter;

memcpy(planetTable[i]longAddr, longSrcAddr,8);

pt = PT_JOIN_ACCEPTED; //允许加入网络负载类型

assignedShortId[0] =(shortAddrCounter>>0)&0xFF;

assignedShortId[1] =(shortAddrCounter>>8)&0xFF;

printf("Join: Planet 0x%04X(index %d) has joined the network\r\n",

shortAddrCounter, i);

break;

}

}

packet[22] = pt; //负载类型

packet[23] = assignedShortId[0];

packet[24] = assignedShortId[1];

enqueueTxPacket(TRUE, 0xFFFF, packet,0); //单播回应

}

break;

case (JOIN_ACCEPTED_PACKET): //PLANET节点处理加入网络允许数据包

RX_DETAILS(printf("JOIN_ACCEPTED_PACKET\r\n");)

ST_RadioSetNodeId((rxDatapacket[payloadStart+1]<<0)|

(rxDatapacket[payloadStart+2]<<8));//设置NodeID

networkJoinedStopSearching = TRUE; //加入网络成功,停止搜索

break;

case (JOIN_DENIED_PACKET): //PLANET节点处理加入网络拒绝数据包

RX_DETAILS(printf("JOIN_DENIED_PACKET\r\n");)

ST_RadioSetPanId(0xFFFF); //重设PANID

break;

……

……

default:

RX_DETAILS(printf("Unknown payloadtype\r\n");)

goto stopProcessing;

}

stopProcessing:

rxDatapacketBeingProcessed = FALSE;

}

具体的调试过程中,进行灵活堂握。

 用keil 5构建模板工程。在keil顶部选Project->New uVision Project, 输入工程名称,进入device选择界面。注意,因为keil 5变成了在线安装Package的模式(即刚安装好软件并不附带各种芯片的包,用哪个下哪个),如果你已经安装了ST的Package,不要用那个Package!!Keil 5暂时不兼容官方库,如果用了的话编译会报错。解决方案:1使用附带的ARM - ARM Cortex M3    2如果还不行就下载我这个吧,下载好之后模板就全部构建完成了。

在你想要创建工程的文件夹下创建三个文件夹:Library、Project和Output,把刚才创建的工程所有文件剪切进Project文件夹。好了之后,我们需要添加库函数文件。解压库函数包,把解压目录下Library文件夹中的CM3文件夹和STM32F10x_StdPeriph_Driver文件夹复制到工程目录下Library文件夹下,把标准库目录下的:STM32F10x_StdPeriph_Lib_V350\Project\STM32F10x_Std Periph_Template文件夹下的mainc、stm32f10x_confh、stm32f10x_ith、 stm32f10x_itc 拷贝到你的工程\Project目录下。

用keil打开你刚才创建的工程,右键点击Source Group->Manage Project Item

int UART_WriteBuf(u8 byCom, u8 pBuf, u16 Len)

{

int i = 0;;

if(Len == 0)

return 0;

switch(byCom)

{

case 1 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_ITConfig(USART1, USART_IT_TC, ENABLE);

USART_SendData(USART1, pBuf);

break;

case 2 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_ITConfig(USART2, USART_IT_TC, ENABLE);

USART_SendData(USART2, pBuf);

break;

case 3 :

Uart_datasend_len = Len - 1;

Uart_dataj = 1;

memmove(Uart_datasend_buff,pBuf,Len);

USART_SendData(USART3, pBuf);

USART_ITConfig(USART3, USART_IT_TXE, ENABLE);

break;

}

return Len;

}

void USART3_IRQHandler(void)

{

int j = 0;

if(USART_GetITStatus(USART3,USART_IT_RXNE))

{

USART_ClearITPendingBit(USART3,USART_IT_RXNE);

Uart_datarec_buff[Uart_datarec_len] = USART_ReceiveData(USART3);

Uart_datarec_len ++;

if(Uart_datarec_len >= UART_DATA_SIZE) //防止数组越界

Uart_datarec_len = UART_DATA_SIZE - 1;

}

else if(USART_GetITStatus(USART3,USART_IT_TXE))

{

USART_ClearITPendingBit(USART3,USART_IT_TXE);

USART_ClearFlag(USART3,USART_FLAG_TC);

if(Uart_dataj <= Uart_datasend_len)

{

// printf("TC = %d,TXE = %d,FLAG_TC = %d\n\r",USART_GetITStatus(USART3,USART_IT_TC),USART_GetITStatus(USART3,USART_IT_TXE),USART_GetFlagStatus (USART3,USART_FLAG_TC));

USART_SendData(USART3,Uart_datasend_buff[Uart_dataj]);

while(j < 800)

j++;

// printf("interrupt:j = %d,len = %d,buff[%d] = %c,buff = %s\n\n\r",Uart_dataj,Uart_datalen,Uart_dataj,Uart_databuff[Uart_dataj],Uart_databuff);

}

else

USART_ITConfig(USART3, USART_IT_TXE, DISABLE);

Uart_dataj++;

}

}

以上就是关于用STM32CubeMx创建的FreeRTOS可以运行多少个实例全部的内容,包括:用STM32CubeMx创建的FreeRTOS可以运行多少个实例、stm32例子中I2C_EE程序里出现main.c(49): error: #18: expected a ")怎么解决急。、谁有通调试通过的STM32W108无线射频zigbee芯片的两点间通信的实例分享一下,谢谢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9732088.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-01
下一篇2023-05-01

发表评论

登录后才能评论

评论列表(0条)

    保存