項目中使用到rt—thread就會涉及到對操作系統的一個軟件框架的搭建過程思路,這里拿已經完成城的項目做一些分享,希望對讀者有些啟發。
項目要求:讀取溫濕度,串口打印,數據定時發送,lcd顯示,平臺上傳,按鍵設置,SD 卡存儲等
系統涉及到的硬件由以下幾部分組成:
1.交互輸入部分:按鍵
2. 輸出部分:TFTLCD屏幕顯示,SD卡存儲,led燈報警
3. 傳感器采集:DHT11溫濕度采集
4. 通訊部分:串口,wifi模塊
5. 計時部分:RTC時鐘計時
硬件連接示意圖根據硬件的連接與系統要求實現的功能來看:
1.首先要做的就是根據硬件電路寫好底層驅動(HAL)
2.進行函數的劃分與封裝,將應用層需要的函數封裝好
3.進行中斷函數的撰寫與封裝(可以將該這一步與第2步同時進行)
4.由于中斷的優先級比任何的線程優先級都要高因此需要統籌線程與中斷的關系
5.繼續線程的規劃,線程優先級定義及應用層函數的撰寫
軟件程序結構:
項目系統要求定期發送數據到平臺,其中在定時器超函數中周期性采集溫濕度信息,并發送消息隊列到處理緩存傳感器信息的線程和超溫處理線程,同時發布采集到一次傳感器的事件。
超溫處理線程接收消息判斷是否超過溫度,wifi模塊通過串口2將溫濕度信息發送給wifi模塊,由wifi模塊實時上傳到服務器。同時串口溫度上傳任務同時接收定時器發送的事件和PC機通過串口1發送的獲取溫度標志所觸發的事件。當采集到傳感器信息且上位機要求獲取溫濕度信息的事情同時發生時,通過串口1向PC發送溫濕度信息。由于SD卡存儲緩慢,所以由溫濕度信息緩存線程在內存池中申請內存,并將獲取到的溫濕度信息緩存到內存中,同時更新LCD曲線繪制的歷史溫濕度信息緩存。
LCD處理線程處理IO口中斷發送過來的標志信息,并據此顯示相應的菜單,溫度濕度信息,顯示所設定采樣頻率與閾值的情況等。
SD卡存儲任務作為后臺任務,從緩存存儲溫濕度信息的內存中讀取溫濕度信息,并通過FATFS文件系統將相應的溫濕度信息存入SD卡,同時根據每片內存的頭部時間信息以及定時器采樣頻率推算本片內存中其他數據的時間信息,并將采樣時間一起保存到SD卡中。在存儲完一片內存片后,釋放該內存到內存池之中。流程圖如下所示:
代碼部分這里貼出主函數中的基本邏輯框架:
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! ");
}
//*****************消息隊列創建 *****************************************/
//申請內存池
//初始化控制塊
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;
/* 初始化消息隊列 */
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, /* 線程入口函數 */
RT_NULL, /* 線程入口函數參數 */
256, /* 線程棧大小 */
2, /* 線程的優先級 */
20); /* 線程時間片 */
/* 啟動線程,開啟調度 */
if (uart_deal_event != RT_NULL)
rt_thread_startup(uart_deal_event);
else
rt_kprintf("led_thread_creat_error");
////*******************創建內存任務線程***********************************************************//
for (j = 0; j < 48; j++) ptr[j] = RT_NULL;
//創建線程
recevDHT11 = rt_thread_create("recevDHT11", recevDHT11_entry, RT_NULL,
512,
4 ,20);
if (recevDHT11 != RT_NULL)
rt_thread_startup(recevDHT11);
//*******************創建釋放內存堆寫入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);
///*******************創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 );
//*******************超溫處理線程的創建***********************************************************//
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線程創建***********************************************************//
wifi= rt_thread_create("wifi ", wifi_entry, RT_NULL,
128,
2, 20);
if (wifi != RT_NULL)
rt_thread_startup(wifi);
//*************測試wifi模塊************************************************************************//
}
審核編輯:湯梓紅
-
操作系統
+關注
關注
37文章
6876瀏覽量
123578 -
軟件框架
+關注
關注
0文章
22瀏覽量
9895 -
RT-Thread
+關注
關注
31文章
1305瀏覽量
40302
發布評論請先 登錄
相關推薦
評論