討論區快速選單
知識庫快速選單
程式設計俱樂部Facebook粉絲團 CSSLP認證,將資安落實在軟體開發中 政府補助!學嵌入式+物聯網
[ 回上頁 ] [ 討論區發言規則 ]
keil c simulator
更改我的閱讀文章字型大小
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/28 上午 10:52:19
請教各位前輩,以下為我的code

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

/* Standard include. */
#include <stdio.h>

/* The ITM port is used to direct the printf() output to the serial window in
the Keil simulator IDE. */
#define mainITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))
#define mainITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
#define mainDEMCR (*((volatile unsigned long *)(0xE000EDFC)))
#define mainTRCENA 0x01000000
#define ioMAX_MSG_LEN ( 100 )
/*
 * The tasks as described in the accompanying PDF application note.
 */
static void vReceiveTask( void *pvParameters );
static void vSendTask( void *pvParameters );

/*
 * Redirects the printf() output to the serial window in the Keil simulator
 * IDE.
 */
int fputc( int iChar, FILE *pxNotUsed );
void vPrintString(const char *pcString);
void vPrintString2(const char *pcString, int Number);

/*-----------------------------------------------------------*/

/* The queue used by both tasks. */
xQueueHandle xQueue1, xQueue2;

/* One array position is used for each task created by this demo. The
variables in this array are set and cleared by the trace macros within
FreeRTOS, and displayed on the logic analyzer window within the Keil IDE -
the result of which being that the logic analyzer shows which task is
running when. */
unsigned long ulTaskNumber[ configEXPECTED_NO_RUNNING_TASKS ];

/*-----------------------------------------------------------*/
long lValue = 0;

int main(void)
{
xQueue1 = xQueueCreate( 1, sizeof(unsigned long) );
xQueue2 = xQueueCreate( 1, sizeof(unsigned long) );

xTaskCreate( vReceiveTask, "Receiver", 100, (void *) lValue, 1, NULL );
xTaskCreate( vSendTask, "Sender", 100, (void *) lValue, 1, NULL );

vTaskStartScheduler();

for( ;; );
}
/*-----------------------------------------------------------*/

作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/28 上午 10:53:17
static void vSendTask( void *pvParameters )
{
const portTickType xTicksToWait = 10 / portTICK_RATE_MS;
portBASE_TYPE xStatus;
portBASE_TYPE xStatus2;
long lSendValue;

lSendValue = (long) pvParameters;

for( ;; )
{
xStatus = xQueueReceive(xQueue2, &lSendValue, xTicksToWait);

if(xStatus == pdTRUE && lSendValue == lValue)
{
vPrintString2("vSendTask Receive from Queue: ", (char)lValue);
lValue++;
lSendValue++;
xStatus2 = xQueueSend( xQueue1, &lValue, 0);
if(xStatus2 == pdTRUE)
{
vPrintString2("vSendTask Send to Queue: ", (char)lValue);
}
}
else
{
vPrintString("No Send\r\n");
}
}
}
static void vReceiveTask( void *pvParameters )
{
const portTickType xTicksToWait = 10 / portTICK_RATE_MS;
portBASE_TYPE xStatus3;
portBASE_TYPE xStatus4;
long lReceiveValue;

lReceiveValue = (long) pvParameters;

xStatus3 = xQueueSend( xQueue2, &lReceiveValue, 0);

if(xStatus3 == pdTRUE)
{
vPrintString2("vReceiveTask Send to Queue: ", (char)lValue);
}

for( ;; )
{
xStatus3 = xQueueReceive(xQueue1, &lReceiveValue, xTicksToWait);

if(xStatus3 == pdTRUE && lReceiveValue == lValue)
{
vPrintString2("vReceiveTask Receive from Queue: ", (char)lValue);
lValue++;
lReceiveValue++;
xStatus4 = xQueueSend( xQueue2, &lValue, 0);
if(xStatus4 == pdTRUE)
{
vPrintString2("vReceiveTask Send to Queue: ", (char)lValue);
}
}
else
{
vPrintString("No Receive\r\n");
}
}
}
int fputc( int iChar, FILE *pxNotUsed )
{
/* Just to avoid compiler warnings. */
( void ) pxNotUsed;

if( mainDEMCR & mainTRCENA )
{
while( mainITM_Port32( 0 ) == 0 );
mainITM_Port8( 0 ) = iChar;
   }

   return( iChar );
}

void vPrintString2(const char *pcString, int Number)
{
taskENTER_CRITICAL();
{
printf("%s : %d\r\n", pcString, Number);
fflush(stdout);
}
taskEXIT_CRITICAL();
}


void vPrintString(const char *pcString)
{
taskENTER_CRITICAL();
{
printf("%s", pcString);
fflush(stdout);
}
taskEXIT_CRITICAL();
}
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/28 上午 10:56:51
想請問的問題為 : 正常的情況下會先Send後Receive ,但有時候會出現Receive後又Receive的情況,請教該如何解決,和這是為什麼會發生這樣的scheduler,感恩!
作者 : gmailjoey(建中) 貼文超過200則
[ 貼文 206 | 人氣 0 | 評價 190 | 評價/貼文 0.92 | 送出評價 13 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/7/28 下午 06:29:41
>想請問的問題為 : 正常的情況下會先Send後Receive ,
>但有時候會出現Receive後又Receive的情況,
>請教該如何解決,和這是為什麼會發生這樣的scheduler,感恩!

你所用的fflush()函式是一個不穩定的函式,
在不同版本與不同平台的C++編譯器之中,
它的支援有許多差別。
有的版本不支援fflush()的多執行緒,
有的新版本則有支援fflush(),
詳細情況要問現在有在做程式開發的大大,
才能得到進一步的了解。

作者 : wallace_tsou(Wallace) 貼文超過200則
[ 貼文 244 | 人氣 314 | 評價 960 | 評價/貼文 3.93 | 送出評價 6 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為最佳解答 2015/7/29 上午 09:51:07
這是MCU的程式,看到使用FreeRTOS,表示fflush()相關細節必須由使用者自己去注意。Compiler無法得知使用RTOS型式,故無法提供多執行緒相關保護。
fflush()會影響printf(),而printf()的底層是fputc()。所以問題在fputc()上。
fputc()確實沒有做多執行緒保護是會產生問題。另一個問題是它使用Busy Loop,這個使行為強迫變成單工,又因無法退出回歸FreeRTOS去管理,會破壞執行緒應有行為。就形成樓主問題。
在RTOS下,請不要使用Busy Loop,一但使用,行為就不會依作業系統應有行為執行。
FreeRTOS有許多範例,請參照正確範例。因為改版很快,我還在使用7.4版,可能有版本差異。還是找到自己版本的範例去執行。
作者 : gmailjoey(建中) 貼文超過200則
[ 貼文 206 | 人氣 0 | 評價 190 | 評價/貼文 0.92 | 送出評價 13 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/29 下午 12:35:53
謝謝大大的說明!
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/30 上午 10:26:43

>這是MCU的程式,看到使用FreeRTOS,表示fflush()相關細節必須由使用者自己去注意。Compiler無法得知使用RTOS型式,故無法提供多執行緒相關保護。
>fflush()會影響printf(),而printf()的底層是fputc()。所以問題在fputc()上。
>fputc()確實沒有做多執行緒保護是會產生問題。另一個問題是它使用Busy Loop,這個使行為強迫變成單工,又因無法退出回歸FreeRTOS去管理,會破壞執行緒應有行為。就形成樓主問題。
>在RTOS下,請不要使用Busy Loop,一但使用,行為就不會依作業系統應有行為執行。
>FreeRTOS有許多範例,請參照正確範例。因為改版很快,我還在使用7.4版,可能有版本差異。還是找到自己版本的範例去執行。


謝謝前輩,我會努力精進的!
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/7/31 下午 03:37:56
謝謝各位前輩

小弟找出問題點了

原來是我只有把print的字串 數字 用CRITICAL SECTION 包起來 變數遞增的地方沒有包到 所以出了error!

所以 critical section 是相當好用的 function !
 板主 : Daniel
 > 資訊類作業 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 資訊類作業 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
資訊類作業
1 Raymond 4540 
2 Ben 2880 
3 青衫 2260 
4 ozzy 1540 
5 HKLN.net 1010 
6 Daniel 780 
7 joe 740 
8 小朱 570 
9 Benson 440 
10 鬼翼@娃娃魚 400 
資訊類作業
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.0625