項(xiàng)目中使用到rt—thread就會涉及到對操作系統(tǒng)的一個軟件框架的搭建過程思路,這里拿已經(jīng)完成城的項(xiàng)目做一些分享,希望對讀者有些啟發(fā)。
項(xiàng)目要求:讀取溫濕度,串口打印,數(shù)據(jù)定時發(fā)送,lcd顯示,平臺上傳,按鍵設(shè)置,SD 卡存儲等
系統(tǒng)涉及到的硬件由以下幾部分組成:
1.交互輸入部分:按鍵
2. 輸出部分:TFTLCD屏幕顯示,SD卡存儲,led燈報(bào)警
3. 傳感器采集:DHT11溫濕度采集
4. 通訊部分:串口,wifi模塊
5. 計(jì)時部分:RTC時鐘計(jì)時
硬件連接示意圖根據(jù)硬件的連接與系統(tǒng)要求實(shí)現(xiàn)的功能來看:
1.首先要做的就是根據(jù)硬件電路寫好底層驅(qū)動(HAL)
2.進(jìn)行函數(shù)的劃分與封裝,將應(yīng)用層需要的函數(shù)封裝好
3.進(jìn)行中斷函數(shù)的撰寫與封裝(可以將該這一步與第2步同時進(jìn)行)
4.由于中斷的優(yōu)先級比任何的線程優(yōu)先級都要高因此需要統(tǒng)籌線程與中斷的關(guān)系
5.繼續(xù)線程的規(guī)劃,線程優(yōu)先級定義及應(yīng)用層函數(shù)的撰寫
軟件程序結(jié)構(gòu):
項(xiàng)目系統(tǒng)要求定期發(fā)送數(shù)據(jù)到平臺,其中在定時器超函數(shù)中周期性采集溫濕度信息,并發(fā)送消息隊(duì)列到處理緩存?zhèn)鞲衅餍畔⒌木€程和超溫處理線程,同時發(fā)布采集到一次傳感器的事件。
超溫處理線程接收消息判斷是否超過溫度,wifi模塊通過串口2將溫濕度信息發(fā)送給wifi模塊,由wifi模塊實(shí)時上傳到服務(wù)器。同時串口溫度上傳任務(wù)同時接收定時器發(fā)送的事件和PC機(jī)通過串口1發(fā)送的獲取溫度標(biāo)志所觸發(fā)的事件。當(dāng)采集到傳感器信息且上位機(jī)要求獲取溫濕度信息的事情同時發(fā)生時,通過串口1向PC發(fā)送溫濕度信息。由于SD卡存儲緩慢,所以由溫濕度信息緩存線程在內(nèi)存池中申請內(nèi)存,并將獲取到的溫濕度信息緩存到內(nèi)存中,同時更新LCD曲線繪制的歷史溫濕度信息緩存。
LCD處理線程處理IO口中斷發(fā)送過來的標(biāo)志信息,并據(jù)此顯示相應(yīng)的菜單,溫度濕度信息,顯示所設(shè)定采樣頻率與閾值的情況等。
SD卡存儲任務(wù)作為后臺任務(wù),從緩存存儲溫濕度信息的內(nèi)存中讀取溫濕度信息,并通過FATFS文件系統(tǒng)將相應(yīng)的溫濕度信息存入SD卡,同時根據(jù)每片內(nèi)存的頭部時間信息以及定時器采樣頻率推算本片內(nèi)存中其他數(shù)據(jù)的時間信息,并將采樣時間一起保存到SD卡中。在存儲完一片內(nèi)存片后,釋放該內(nèi)存到內(nèi)存池之中。流程圖如下所示:
代碼部分這里貼出主函數(shù)中的基本邏輯框架:
int main(void)
{
/***********************掛載SD卡并打開文件*******************************/
while(SD_Init())//檢測不到SD卡
{
LCD_ShowString(30,150,200,16,16,"SD Card Error!");
LCD_ShowString(50,150,200,16,16,"Please Check! ");
}
//*****************消息隊(duì)列創(chuàng)建 *****************************************/
//申請內(nèi)存池
//初始化控制塊
rt_mp_init(&tem_mp, "temmp", &temmempool[0], sizeof(temmempool), mem_slice);
rt_mp_init(&hum_mp, "hummp", &hummempool[0], sizeof(hummempool), mem_slice);
rt_err_t result2;
/* 初始化消息隊(duì)列 */
result= rt_mq_init(& mq_DHT11_tem,
" mq_DHT11_tem",
&msg_DHT11_pool_tem[0], /* msg_pool */
sizeof(tem), /* 每個消息的大小*/
sizeof(msg_DHT11_pool_tem), /* msg_pool大小*/
RT_IPC_FLAG_FIFO);
result2 = rt_mq_init(& mq_DHT11_hum,
" mq_DHT11_hum",
&msg_DHT11_pool_hum[0], /* msg_pool */
sizeof(hum), /* 每個消息的大小*/
sizeof(msg_DHT11_pool_hum), /* msg_pool大小*/
RT_IPC_FLAG_FIFO);
//定時器線程
/* DHT11 TIMER */
DH11_timer = rt_timer_create("DHT11_get", timeout1,
RT_NULL, samp_freq,
RT_TIMER_FLAG_PERIODIC);
/* 啟動*/
if (DH11_timer != RT_NULL)
flag=rt_timer_start(DH11_timer );
if(flag==RT_EOK)
rt_kprintf("DH11_timer start successfull\n");
//***********************事件處理線程*******************************************/
uart_deal_event = /* 線程控制塊指針 */
rt_thread_create( "usart_deal_event", /* 線程名字 */
uart_deal_thread_entry, /* 線程入口函數(shù) */
RT_NULL, /* 線程入口函數(shù)參數(shù) */
256, /* 線程棧大小 */
2, /* 線程的優(yōu)先級 */
20); /* 線程時間片 */
/* 啟動線程,開啟調(diào)度 */
if (uart_deal_event != RT_NULL)
rt_thread_startup(uart_deal_event);
else
rt_kprintf("led_thread_creat_error");
////*******************創(chuàng)建內(nèi)存任務(wù)線程***********************************************************//
for (j = 0; j < 48; j++) ptr[j] = RT_NULL;
//創(chuàng)建線程
recevDHT11 = rt_thread_create("recevDHT11", recevDHT11_entry, RT_NULL,
512,
4 ,20);
if (recevDHT11 != RT_NULL)
rt_thread_startup(recevDHT11);
//*******************創(chuàng)建釋放內(nèi)存堆寫入SD卡線程***********************************************************//
thread_mp_release = rt_thread_create("thread_mp_release", thread_mp_release_entry, RT_NULL,
1024,
4, 20);
if (thread_mp_release != RT_NULL)
rt_thread_startup(thread_mp_release);
///*******************創(chuàng)LCD 顯示繪圖線程***********************************************************//
lcd_show= rt_thread_create("lcd_showwave", lcd_show_entry, RT_NULL,
512,
3, 30);
if (lcd_show != RT_NULL)
rt_thread_startup(lcd_show );
//*******************超溫處理線程的創(chuàng)建***********************************************************//
over_temhum = rt_thread_create("over_temhum ", overtem_entry, RT_NULL,
256,
1, 20);
if (lcd_show != RT_NULL)
rt_thread_startup(over_temhum );
//*******************wifi線程創(chuàng)建***********************************************************//
wifi= rt_thread_create("wifi ", wifi_entry, RT_NULL,
128,
2, 20);
if (wifi != RT_NULL)
rt_thread_startup(wifi);
//*************測試wifi模塊************************************************************************//
}
審核編輯:湯梓紅
-
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6695瀏覽量
123147 -
軟件框架
+關(guān)注
關(guān)注
0文章
21瀏覽量
9851 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1265瀏覽量
39851
發(fā)布評論請先 登錄
相關(guān)推薦
評論