硬汉嵌入式论坛

 找回密码
 立即注册
查看: 762|回复: 5
收起左侧

[技术讨论] 函数返回状态如何设计

[复制链接]

16

主题

76

回帖

124

积分

初级会员

积分
124
发表于 2025-3-6 09:34:53 | 显示全部楼层 |阅读模式
自己捣鼓的一个程序,从网上获取时间和天气信息,显示到桌面上。我在写程序的过程中想通过返回值来确认执行状态,之前想省事就采用 HAL 库的枚举。

[C] 纯文本查看 复制代码
typedef enum 
{
HAL_OK       = 0x00U,
  HAL_ERROR    = 0x01U,
  HAL_BUSY     = 0x02U,
  HAL_TIMEOUT  = 0x03U
} HAL_StatusTypeDef;

使用的过程中感觉满足不了我的需求,有没有关于用以反馈函数运行状态的示例,或者我该如何去设计
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-3-6 10:04:50 | 显示全部楼层
比如我这个之前音乐播放器,事件标志组各种情况的返回值

[C] 纯文本查看 复制代码
if(os_evt_wait_or(0xFFFE, 0xFFFF) == OS_R_EVT)
        {
            xResult = os_evt_get ();
            switch (xResult)
            {
				/* 如果启用emWin多任务的话,此位是被emWin多任务使用 */
				case MusicTaskReserved_0:
					break;

				/* 实现快进快退 */
				case MusicTaskAudioAdjust_1:
					AUDIO_Pause();
					MP3_TimeSet(fout, ptMP3);

					/* 初始化部分变量 */
					ptMP3->pReadPos = ptMP3->pInputBuf;
					ptMP3->iBytesleft = fread(ptMP3->pInputBuf, 1, DecoderMP3BufSize, fout);

					/* 获取3帧解码好的数据 */
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer0, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer1, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					AUDIO_Resume();
					break;

				/* 暂停 */
				case MusicTaskAudioPause_2:
					AUDIO_Pause();
					break;

				/* 继续 */
				case MusicTaskAudioResume_3:
					AUDIO_Resume();
					break;

				/* 此位暂未使用 */
				case MusicTaskReserved_4:
					break;

				/* 开始播放 */
				case MusicTaskAudioPlay_5:
					/* 获取要播放mp3文件的相关信息 */
					GetMP3TagInfo((uint8_t *)filename, ptMP3);
					GetMP3DispInfo(ptMP3, &mp3FrameInfo);

					/* mp3文件被打开标志设置 */
					ucFileOpenFlag = 1;

					/* 打开MP3音频文件*/
					fout = fopen ((const char *)filename, "r");
					fseek(fout, ptMP3->uiFrameStart, SEEK_SET);
					MP3_TimeShow(fout, ptMP3);

					/* 初始化部分变量 */
					ptMP3->pReadPos = ptMP3->pInputBuf;
					ptMP3->iBytesleft = fread(ptMP3->pInputBuf, 1, DecoderMP3BufSize, fout);

					/* 初始化Helix MP3解码器 */
					mp3Decoder = MP3InitDecoder();

					/* 获取3帧解码好的数据 */
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer0, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer1, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);

					/* 初始化SAI音频接口进行播放 */
					AUDIO_Init(1, I2S_Standard_Phillips, SAI_DataSize_16b, ptMP3->uiSamplerate, mp3FrameInfo.nChans);
					Play_DMA_Init(ptMP3->pI2SBuffer0, ptMP3->pI2SBuffer1, ptMP3->usOutsamples);
					AUDIO_Play();
					break;

				/* 退出音频播放 */
				case MusicTaskAudioReturn_6:
					AUDIO_Stop();
					if(fout != NULL)
					{
						fclose (fout);
					}
					MP3FreeDecoder(mp3Decoder);
					os_free_mem(AppMalloc, ptMP3->pI2STempBuff);
					os_free_mem(AppMalloc, ptMP3->pI2SBuffer1);
					os_free_mem(AppMalloc, ptMP3->pI2SBuffer0);
					os_free_mem(AppMalloc, ptMP3->pInputBuf);
					os_free_mem(AppMalloc, ptMP3);
					return;

				/* 获取歌曲播放时间 */
				case MusicTaskAudioGetTime_7:
					if(ucFileOpenFlag == 1)
						MP3_TimeShow(fout, ptMP3);
					break;

				/* 开始播放,歌曲切换下一曲使用 */
				case MusicTaskAudioStart_8:
					/* 获取要播放mp3文件的相关信息 */
					GetMP3TagInfo((uint8_t *)filename, ptMP3);
					GetMP3DispInfo(ptMP3, &mp3FrameInfo);

					/* mp3文件被打开标志设置 */
					ucFileOpenFlag = 1;

					/* 打开MP3音频文件*/
					fout = fopen ((const char *)filename, "r");
					fseek(fout, ptMP3->uiFrameStart, SEEK_SET);
					MP3_TimeShow(fout, ptMP3);

					/* 初始化部分变量 */
					ptMP3->pReadPos = ptMP3->pInputBuf;
					ptMP3->iBytesleft = fread(ptMP3->pInputBuf, 1, DecoderMP3BufSize, fout);

					/* 初始化Helix MP3解码器 */
					mp3Decoder = MP3InitDecoder();

					/* 获取3帧解码好的数据 */
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer0, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					memcpy(ptMP3->pI2SBuffer1, ptMP3->pI2STempBuff, MaxOutputBufSize);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);

					/* 初始化SAI音频接口进行播放 */
					AUDIO_Init(1, I2S_Standard_Phillips, SAI_DataSize_16b, ptMP3->uiSamplerate, mp3FrameInfo.nChans);
					Play_DMA_Init(ptMP3->pI2SBuffer0, ptMP3->pI2SBuffer1, ptMP3->usOutsamples);
					AUDIO_Play();
					AUDIO_Pause();
					break;

				/* 当前使用的是缓冲0,填充缓冲1,并通过64点FFT实行频谱显示 */
				case MusicTaskAudioFillBuffer1_9:
					VedioSynCount--;
					if(hWinMusic != WM_HWIN_NULL)
					{
						DSP_FFT64(ptMP3->pI2SBuffer0);	
					}
					MP3_FillAudio((uint16_t *)ptMP3->pI2SBuffer1,
								  (uint16_t *)ptMP3->pI2STempBuff,
								  mp3FrameInfo.outputSamps);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					break;

				/* 当前使用的是缓冲1,填充缓冲0,并通过64点FFT实行频谱显示 */
				case MusicTaskAudioFillBuffer0_10:
					VedioSynCount--;
					if(hWinMusic != WM_HWIN_NULL)
					{
						DSP_FFT64(ptMP3->pI2SBuffer1);
					}
					MP3_FillAudio((uint16_t *)ptMP3->pI2SBuffer0,
								  (uint16_t *)ptMP3->pI2STempBuff,
								  mp3FrameInfo.outputSamps);
					GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
					break;

				/* 
				   早期设计的时候,为了防止视频播放任务一直占用文件系统,导致音频的DMA的
				   双缓冲都发消息过来,现在的版本进入这个消息的概率极小了。
				*/
				case MusicTaskWaitBuffer:
					#if 0 /* 这种方式有时候会多计算一次 */
						printf_MP3dbg("count = %d, ddd = %x\r\n", count, xResult);
						xResult = 0;
						while(os_sem_wait (&SemaphoreVedio, 0) == OS_R_OK)
						{
							xResult++;
							GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
						}
						printf_MP3dbg("count = %d, ddd = %x\r\n", count, xResult);
						count = 0;
					#else
						printf_MP3dbg("count = %d, ddd = %x\r\n", VedioSynCount, xResult);
						uiTempCount = VedioSynCount;
						VedioSynCount = 0;
						
						for(i = 0; i < uiTempCount; i++)
						{
							GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
						}
						
						/* 防止同步的过程中,count被改变,再进行一次 */
						for(i = 0; i < VedioSynCount; i++)
						{
							GetMP3DecoderData(fout, ptMP3->pI2STempBuff, &mp3FrameInfo, mp3Decoder, ptMP3);
						}
						printf_MP3dbg("count = %d, ddd = %x\r\n", VedioSynCount, xResult);
						VedioSynCount = 0;
					#endif
					break;

            /* 后5位暂未使用 */
            default:
                printf("xResult = %x\r\n", xResult);
                break;
            }
        }
回复

使用道具 举报

16

主题

76

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2025-3-6 10:55:16 | 显示全部楼层
eric2013 发表于 2025-3-6 10:04
比如我这个之前音乐播放器,事件标志组各种情况的返回值

[mw_shl_code=c,true]if(os_evt_wait_or(0xFFFE ...

大佬你这是状态机吧。可能我没有表达清楚,只是需要反馈该函数执行结果
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-3-6 12:19:03 | 显示全部楼层
刘心武 发表于 2025-3-6 10:55
大佬你这是状态机吧。可能我没有表达清楚,只是需要反馈该函数执行结果

我这个不是状态机,是命令,返回值不同的命令处理。
回复

使用道具 举报

16

主题

76

回帖

124

积分

初级会员

积分
124
 楼主| 发表于 2025-3-6 13:38:26 | 显示全部楼层
eric2013 发表于 2025-3-6 12:19
我这个不是状态机,是命令,返回值不同的命令处理。

好的,我晚上学习学习
回复

使用道具 举报

2

主题

71

回帖

77

积分

初级会员

积分
77
发表于 2025-3-6 17:23:30 | 显示全部楼层
这只是HAL库的函数返回值,执行HAL开头的函数得到的是这些结果
用户程序自己写枚举就好
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:24 , Processed in 0.041421 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表