找回密码
 立即注册
查看: 883|回复: 6

在FREERTOS任务外调用IapRead()读到的u8Ram512[]数据正常,同样的指令在FREERTOS任

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-14 16:40:15 | 显示全部楼层 |阅读模式
u8  xdata u8Ram512[512]; //EEPROM数据区512字读写映射于XRAM,尾2字校验和-----全局变量


/*** 读EEPROM到u8Ram512字节函数 ***/
void IapRead(u16 xdata Len,u8 code *xdata RomAddr,u8 *xdata RamAddr) //IAP读:字节长度,EEPROM字节首地址,XRAM字节首地址
{  while(Len--){*RamAddr++ = *RomAddr++;}
}


在FREERTOS任务外调用IapRead()读到的u8Ram512[]数据正常:指令如下
IapRead(512,IAP512Rd0,u8Ram512); //IAP读数据扇区0: 512字节长度,EEPROM字节首地址,XRAM字节首地址


u16Tmp = 0;
while(u16Tmp < 512)
{ WrTxBuf(u8Ram512[u16Tmp++]);                
        if(!TxBusy && (u16Tmp >= TxBufMax/3 || u16Tmp == 512)){ TxBusy = 1; TI = 1; } //启动发送
        while(TxBusy); //等待发送完
}


同样的指令,在FREERTOS任务内调用IapRead()读到的u8Ram512[]数据不正常!
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-15 12:14:19 | 显示全部楼层
同一xdata下的全局512字节数组,同样的指令在FREERTOS任务外访问xdata区间正常、在FREERTOS任务内访问xdata区间不正常,会不会是FREERTOS任务内访问xdata区间有什么特殊要求!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-04-30 07:46:22

33

主题

1079

回帖

2319

积分

荣誉版主

积分
2319
发表于 2024-4-16 11:57:52 | 显示全部楼层
形参强制指定了存储类型, 这个问题比较明显,
虽然这样做在不重入的情况下可能是没有问题的,
但是这是一个和OS很不兼容的习惯.
原因是: STC32 用 OS时一般都开全局重入, 形参和局部变量是走栈的,
这样强制指定以后, 编译器只能让它们走固定xdata地址传递了, 其实效率反而降低了.

一段短的代码很难看出问题, 可以的话, 你把整个项目打包发出来,
这边高手很多, 比如杨老师, 给您来段孤立疗法, 药到病除的那种.
乘风大佬也很热心, 一般的疑难杂症难不到他.

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-17 16:24:40 | 显示全部楼层
// 用Keil C251编译器,Memory Model设置XSmall模式,默认定义变量在edata,单时钟存取访问速度快,edata建议保留2K给堆栈使用
// 不需要快速访问的数组加xdata关键字定义到xdata空间

/****************** 功能说明 ***********************************


***************************************************************/

#include "FreeRTOS.h"
#include "semphr.h"                    //信号量头文件

#define u8 unsigned char
#define u16 unsigned int
#define u32 unsigned long
       
sbit SoftRst = IAP_CONTR^5; //增加软件复位控制位,置1软件复位
u8 xdata SysStart; //系统热启动标志:0x5a,其它值为冷启动标志

/***** 设置CopyRight信息******/

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
                                                                                                                                         
/************* 本地IO变量声明 **************/
                                                                                                                                         
sbit XA  = P1^4; //XA:DO/DI/AI4
sbit XB  = P1^5; //XB:DO/DI/AI5
sbit XC  = P1^6; //XC:DO/DI/AI6
sbit RX2 = P1^0; //RX2:DI //与其它板隔离握手DI
sbit TX2 = P1^1; //TX2:DO //与其它板隔离握手DO,运行指示灯
sbit SDA = P3^3; //SDA:DO/DI
sbit SCL = P3^2; //SCL:DO/DI
sbit RX  = P3^0; //RX:DI
sbit TX  = P3^1; //TX:DO
sbit HA  = P3^7; //HA:DI
sbit HB  = P1^2; //HB:DI/T2
sbit HC  = P1^7; //HC:DI/AI7
sbit M   = P3^5; //M:DI/T1工作于计数、计算无刷电机转速
sbit ZF  = P3^6; //ZF:DO,电机正转1,反转0
sbit VR  = P3^4; //VR:DO,电机使能及PWM,禁止0
bit  DcmEN; //电机使能1,禁止0

/************* 本地IO变量声明 结束 **************/
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————                                                                                                                                         

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
// ++++++++++ STC32G12K128 EEPROM描述 开始 ++++++++++

//STC32G12K128 EEPROM设置4K(0x1000),IAP基地址0xFE0000
#define IapBase   0xFE0000

#define u32RunCnt0Wr (IAP512Wr7 + 0)  //冷启动计数4字节:写地址
#define u32RunCnt0Rd (IAP512Rd7 + 0)  //冷启动计数4字节:读地址
#define u32RunCnt1Wr (IAP512Wr7 + 4)  //热启动计数4字节:写地址
#define u32RunCnt1Rd (IAP512Rd7 + 4)  //热启动计数4字节:读地址
#define IcFlgWr      (IAP512Wr7 + 15) //芯片标记字节写地址:擦除后读不是0xFF或写0x00后读不等为标记成功
#define IcFlgRd      (IAP512Rd7 + 15) //芯片标记字节读地址:擦除后读不是0xFF或写0x00后读不等为标记成功

#define IAP512Wr7 0x000 //写数据扇区7地址 标记
#define IAP512Rd7 (IapBase + IAP512Wr7) //读数据扇区7地址 保留
#define IAP512Wr6 0x200 //写数据扇区6地址 保留
#define IAP512Rd6 (IapBase + IAP512Wr6) //读数据扇区6地址 保留
#define IAP512Wr5 0x400 //写数据扇区5地址 保留
#define IAP512Rd5 (IapBase + IAP512Wr5) //读数据扇区5地址 保留
#define IAP512Wr4 0x600 //写数据扇区4地址 保留
#define IAP512Rd4 (IapBase + IAP512Wr4) //读数据扇区4地址 保留
#define IAP512Wr3 0x800 //写数据扇区3地址 保留
#define IAP512Rd3 (IapBase + IAP512Wr3) //读数据扇区3地址 保留
#define IAP512Wr2 0xA00 //写数据扇区2地址 保留
#define IAP512Rd2 (IapBase + IAP512Wr2) //读数据扇区2地址 保留

#define IAP512Wr1 0xC00 //写数据扇区1地址 为扇区0的备份
#define IAP512Rd1 (IapBase + IAP512Wr1) //读数据扇区1地址 为扇区0的备份
#define IAP512Wr0 0xE00 //写数据扇区0地址 工作
#define IAP512Rd0 (IapBase + IAP512Wr0) //读数据扇区0地址 工作


//以下FA0~FFF参数共96字节,上电UART发送
#define BpsSel   IAP512Rd0+0x1A0   //BPS选择:0_2400,1_9600,2_38400,3_57600,4_115200,5_230400,6_460800,7_921600
u8 far *BusId0          = IAP512Rd0+0x1A1; //总线地址0设定:1~31
u8 far *BusId1          = IAP512Rd0+0x1A2; //总线地址1设定:1~31
u8 far *BusId2          = IAP512Rd0+0x1A3; //总线地址2设定:1~31
u8 far *BusId3          = IAP512Rd0+0x1A4; //总线地址3设定:1~31
u8 far *DrvMod          = IAP512Rd0+0x1A5; //电机类型:0两线有刷,1三线无刷无感,2三线无刷有感,3四线步进

//10字节:保留

//16字节:P:BLD_B3  221123
//16字节:A:BLD_B3  221123
//16字节:U:MQCE_V1 221123
//16字节:8位生产日期 + 6位生产编号 + 18位身份编号

#define u32IcId           IAP512Rd0+512-16 //4字节 芯片ID字
#define u32UiId           IAP512Rd0+512-12 //4字节 上位机ID字
//3字节 保留
#define u8TxSector  IAP512Rd0+512-5  //1字节 开机发送8个扇区使能(1)标志,bit0~7分别对应0~7数据扇区发送使能
#define u16AppAcc          IAP512Rd0+512-4  //2字节 为程序区累加和
#define u16DataAcc         IAP512Rd0+512-2  //2字节 为数据区累加和

// ++++++++++ STC32G12K128 EEPROM描述 结束 ++++++++++
//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

#define IcIdLen                           4          //ID字节数
#define IcIdAddr                           (&CHIPID3) //4字节(高位在前),STC32G芯片CHIPID:3测试台号低字节,4~6测试流水编号
#define VRefAddr                           (&CHIPID7) //2字节(高位在前),STC32G芯片CHIPID:7~8 1.19V基准实际值mV:

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

u32 far *u32RomIndex; //EEPROM访问指针
//u16 far *u16RomIndex; //EEPROM访问指针
u8  far *u8RomIndex;  //EEPROM访问指针
//u32 *u32RamIndex; //xdata访问指针
//u16 *u16RamIndex; //xdata访问指针
//u8  xdata *u8RamIndex; //xdata访问指针u8
//u8  u8Ram512[512]; //EEPROM数据区512字读写映射,尾2字校验和(数组定义在edata区:任务外写读正常,任务内写读正常)
u8  xdata u8Ram512[512]; //EEPROM数据区512字读写映射,尾2字校验和(数组定义在xdata区:任务外写读正常,任务内写读异常)


//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//总线串口1参数
//报文格式:1、报头:0xAB,0xBA;2、地址:1字节;3、数据长度:1字节;4、数据:n字节,5、1~4累加和:2字节
#define RxBufMax 128 //环形接收缓冲区最大字节数(在xdata区超594字节MCU会异常重启),实际数据区最大每节拍31字节,最长报文:31+6=37字节
u16 RxBufCnt,RxBufWr,RxBufRd; //接收缓冲区(等于RxBufMax时满,指针循环):接收字节计数(写+1,读-1),写指针,读指针
u8 RxBuf[RxBufMax]; //接收缓冲区FIFO环形队列 !!!!!!!!!! 缓冲区在edata稳定 不可以在xdata!!!!!!!!!!

#define TxBufMax 128 //发送缓冲区最大字节数
u16 TxBufCnt,TxBufWr,TxBufRd; //发送缓冲区(等于TxBufMax时满,指针循环):发送字节计数(写+1,读-1),写指针,读指针
u8 TxBuf[TxBufMax]; //发送缓冲区FIFO环形队列 !!!!!!!!!! 缓冲区在edata稳定 也可以在xdata!!!!!!!!!!
bit TxBusy; //1为发送忙标志

//初始化uart1函数 @33.1776MHz
void Uart1Ini(void)
{ //RS422总线Uart1(使用T1 1T): 系统24MHz,8位数据,1位停止,@33.1776MHz       
        //BPS选择:0_2400,1_9600,2_38400,3_57600,4_115200,5_230400,6_460800,7_921600
        u8 xdata u8tmp;       
        SCON = 0x50; AUXR |= 0x40; AUXR &= 0xFE; TMOD &= 0x0F; //8位数据 可变波特率 T1时钟1T模式 串口1选T1为波特率发生器(16位自动重置) 定时器模式       
        /*u8RomIndex = BpsSel; u8tmp = *u8RomIndex;
        if     (u8tmp == 0) {TH1 = 0xF2; TL1 = 0x80;} // 0_2400
        else if(u8tmp == 1) {TH1 = 0xFC; TL1 = 0xA0;} // 1_9600
        else if(u8tmp == 2) {TH1 = 0xFF; TL1 = 0x28;} // 2_38400
        else if(u8tmp == 3) {TH1 = 0xFF; TL1 = 0x70;} // 3_57600
        else if(u8tmp == 4) {TH1 = 0xFF; TL1 = 0xB8;} // 4_115200
        else if(u8tmp == 5) {TH1 = 0xFF; TL1 = 0xDC;} // 5_230400
        else if(u8tmp == 6) {TH1 = 0xFF; TL1 = 0xFE;} // 6_460800
        else if(u8tmp == 7) {TH1 = 0xFF; TL1 = 0xF7;} // 7_921600
        else*/                                                           {TH1 = 0xFF; TL1 = 0xB8;} // 其它设置默认_115200
        TxBusy = 0; //复位发送忙标志
        ET1 = 0; TR1 = 1; RI = 0; TI = 0; ES = 1; REN = 1; //禁止T1中断 T1开始计时 清接收中断标志 清发送中断标志 接收允许 允许串口1中断
        RxBufCnt = 0; RxBufWr = 0; RxBufRd = 0; TxBufCnt = 0; TxBufWr = 0; TxBufRd = 0; //初始接收、发送缓冲区指针
} //初始化uart1函数结束
//******************************************************************************

//*****写发送字节至缓冲区函数*****
u16 WrTxBuf(u8 SendByte,u16 TxBufAcc) //TxBufAcc传入参数可留空
{ while(TxBufCnt >= TxBufMax) //发送缓冲区满则等待
        { //xSemaphoreTake(xSemaphoreUart1, 0);
                ulTaskNotifyTake(pdTRUE,0); //等待任务通知
        }
  ES = 0; //关uart1中断,防止与串口中断函数中相关共用变量冲突
        if(TxBufWr >= TxBufMax){ TxBufWr = 0; }
        else if(TxBufWr == 0xffff){ TxBufWr = TxBufMax - 1; }
  TxBuf[TxBufWr++] = SendByte; TxBufCnt++;
        if(TxBufWr >= TxBufMax){ TxBufWr = 0; }
        else if(TxBufWr == 0xffff){ TxBufWr = TxBufMax - 1; }
  TxBufAcc += SendByte;
  ES = 1; //开uart1中断
        return TxBufAcc; //返回发送字节累加和
} //*****写发送字节至缓冲区函数结束*****

//*****读接收数据、指针越限处理函数*****
u8 RdRxLmt(void)
{ u8 Tmp = 0;
        ES = 0; //关uart1中断,防止与串口中断函数中相关共用变量冲突
  if(RxBufCnt)
        {        if(RxBufRd >= RxBufMax){ RxBufRd = 0; }
                else if(RxBufRd == 0xffff){ RxBufRd = RxBufMax - 1; }
                Tmp = RxBuf[RxBufRd++]; RxBufCnt--;
                if(RxBufRd >= RxBufMax){ RxBufRd = 0; }
                else if(RxBufRd == 0xffff){ RxBufRd = RxBufMax - 1; }
        }
        ES = 1; //开uart1中断
  return Tmp; //返回接收区读取的1字节
} //*****UART1读接收数据、指针越限处理函数结束*****

//*******************************************************************************

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//任务函数定义

/* 任务句柄 */
TaskHandle_t Uart1_Task_Handler; //UART1RI任务句柄
TaskHandle_t Pulse_Task_Handler; //Pulse心跳任务句柄
//SemaphoreHandle_t xSemaphoreUart1; //Uart1信号量定义
//SemaphoreHandle_t xSemaphorePulse; //Pulse信号量定义

//*****Uart1通讯中断程序开始,接收中断RI,发送中断TI,RI/TI软件清除*****
void UART1_ISR (void) interrupt UART1_VECTOR
{ BaseType_t xHigherPriorityTaskWoken;
        if(RI == 1)
  { RI = 0;                 
    if(RxBufWr >= RxBufMax){ RxBufWr = 0; } else if(RxBufWr == 0xffff){ RxBufWr = RxBufMax - 1; }
    RxBuf[RxBufWr++] = SBUF; RxBufCnt++;
    if(RxBufWr >= RxBufMax){ RxBufWr = 0; } else if(RxBufWr == 0xffff){ RxBufWr = RxBufMax - 1; }
                //xSemaphoreGiveFromISR(xSemaphoreUart1,&xHigherPriorityTaskWoken);
                vTaskNotifyGiveFromISR(Uart1_Task_Handler,&xHigherPriorityTaskWoken);
  }
  if(TI == 1)
  { TI = 0;
    if(TxBufCnt)
                { TxBusy = 1;
                       
                        if(TxBufRd >= TxBufMax){ TxBufRd = 0; } else if(TxBufRd == 0xffff){ TxBufRd = TxBufMax - 1; }
                        SBUF = TxBuf[TxBufRd]; TxBuf[TxBufRd++] = 0; TxBufCnt--;
                        if(TxBufRd >= TxBufMax){ TxBufRd = 0; } else if(TxBufRd == 0xffff){ TxBufRd = TxBufMax - 1; }
                       
                        //REN = 0;
                }
    else
                { TxBusy = 0;
                        //REN = 1;
                }
                //xSemaphoreGiveFromISR(xSemaphoreUart1,&xHigherPriorityTaskWoken);
                vTaskNotifyGiveFromISR(Uart1_Task_Handler,&xHigherPriorityTaskWoken);
  }
} //*****通讯中断程序结束*****

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

/*******************************************************************************
* 函 数 名     : vUart1_Task
* 函数功能     : uart1接收报文解析、执行、返回报文
* 输    入     : 无
* 输    出     : 无
*******************************************************************************/

//接收报文格式1(可变长度7+n字节):1、报头:0xAB,0xBA;2、地址:1字节;3、数据长度:2字节;4、数据:n字节,5、1~4累加和:2字节
//接收报文格式2(固定长度6字节):1、报头:0xAB,0xBA;2、地址:1字节;3、控制字节:1字节;4、1~3累加和:2字节
//接收地址字节:B5~B0=1~63接收地址;B7B6=00数据报文,B7B6=01电机控制报文,B7B6=10过程控制报文按广播接收,地址匹配返回状态数据
//应答数据长度:1字节
/* ---------- Uart1任务函数 ---------- */
portTASK_FUNCTION( vUart1_Task, pvParameters )
{        u16 RxBufCntTmp0,RxBufRdTmp0; //保存报头第0字节指针用
        u16 RxBufCntTmp1,RxBufRdTmp1; //保存报头第1字节指针用(本报文出错,下一报头扫描指针)
        u8 RxId,CtrlByte; //接收: 报文地址,控制字节
        u16 DataLen,u16Acc; //接收: 数据长度,计算累加和
  u8 *RxData; //数据段指针,从数据块长度开始至数据块结束(报文的3~4段)
        u16 TxBufAcc; //发送报文累加和
        u8 ErrNum; //报文出错代号
        u32 ErrCnt0 = 0; //报头AB出错计数
        u32 ErrCnt1 = 0; //报头BA出错计数
        u32 ErrCnt2 = 0; //报文ACC出错计数
        u32 OkCnt = 0; //报文ACC正确计数
               
        u8 u8Tmp; u16 u16Tmp; u32 u32Tmp;
       
        /* 未使用的变量和参数,请使用UNUSED宏进行处理,以免出现编译警告 */
        UNUSED( pvParameters );
       
L_START:
        while(1) //任务死循环
        {
                ErrNum = 0; //清出错码
                DataLen = 0; //复位数据段长度          
                // *****无报文循环等待uart1接收中断发送信号 *****
                while( RxBufCnt < 6 ) //最短报文6字节(节拍及电机类)
                { //xSemaphoreTake(xSemaphoreUart1, portMAX_DELAY); //等待信号量,设portMAX_DELAY无超时
                        ulTaskNotifyTake(pdTRUE,0); //等待任务通知,设portMAX_DELAY无超时,比信号量少占RAM、任务切换更快
                        if(!TxBufCnt) { TxBusy = 0; } //清发送忙标志
                }
               
                //波特率修改报文,如:BPS=NN,N为0~7
                if(RxBuf[RxBufRd + 0]=='B' && RxBuf[RxBufRd + 1]=='P' && RxBuf[RxBufRd + 2]=='S'  && RxBuf[RxBufRd + 3]=='=' && RxBuf[RxBufRd + 4]== RxBuf[RxBufRd + 5])
                { RxBufCnt = 0;

                        // ...........以下为测试指令...........
                        //FREERTOS任务外执行:定义在xdata的数组u8Ram512[]写读测试,发送2次0~255共512字节
                        //IapRead(512,IAP512Rd0,u8Ram512); //读数据扇区0 数组u8Ram512[]写
                        u16Tmp = 0;
                        while(u16Tmp < 512)
                        { //以下指令ABCD四选一分别测试
                                //*指令A*/ WrTxBuf(u8Ram512[u16Tmp++]); // 保持任务外写入数据(0~255,0~255),读数据与写入不一致、能发送
                                //*指令B*/ u8Tmp = u8Ram512[u16Tmp]; WrTxBuf(u16Tmp++ & 255); // 读数组、能发送
                                //*指令C*/ u8Ram512[u16Tmp] = u16Tmp & 255; WrTxBuf(u16Tmp++ & 255);     // 写数组:没有发送、MCU无复位、RX2未变,心跳Pulse任务闪灯正常
                                /*指令D*/ u8Ram512[u16Tmp] = u16Tmp & 255; WrTxBuf(u8Ram512[u16Tmp++]); // 写数组:没有发送、MCU无复位、RX2未变,心跳Pulse任务闪灯正常       
                               
                                if(!TxBusy && (u16Tmp >= TxBufMax/3 || u16Tmp == 512)){ TxBusy = 1; TI = 1; RX2 = ~RX2; } //启动发送,RX2监测
                                while(TxBusy); //等待发送完
                        }
                        // 测试结果:数组u8Ram512[]读正常、写异常
                        //
                        // ...........测试指令 结束...........
                }

        } //任务死循环尾部  读接收缓冲区结束,返回报头扫描
       
        vTaskDelete(NULL); /* 正常情况下不会运行到此处, 为安全起见, 若由于程序异常而导致运行到此处, 则需删除任务 */
        SoftRst = 1; // @@@@@@@@@@ 软件复位        @@@@@@@@@@
}
/* ---------- Uart1任务函数 结束---------- */

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

/* ---------- 心跳Pulse任务函数 ---------- */
portTASK_FUNCTION( vPulse_task, pvParameters )
{
        u16 count = 0;
       
        /* 未使用的变量和参数,请使用UNUSED宏进行处理,以免出现编译警告 */
        UNUSED( pvParameters );
   
  while(1)
  {
                // 等待信号量(无超时) 如果INCLUDE_vTaskSuspend置位“1”,则指定阻塞时间置portMAX_DELAY会导致任务阻塞时间不确定(不会超时)
                //xSemaphoreTake(xSemaphorePulse, portMAX_DELAY); //等待信号量(无超时)
    if (++count > 500){ TX2 = ~TX2; count = 0; } //闪灯周期计数,运行指示闪灯
               
                //DI、AI采集
                   
    vTaskDelay(1); //运行其它任务、等待延时1mS
  } // 任务死循环 尾部
   
  vTaskDelete(NULL); /* 正常情况下不会运行到此处,为安全起见,若由于程序异常而导致运行到此处,则需删除任务 */
        SoftRst = 1; // @@@@@@@@@@ 软件复位        @@@@@@@@@@
}
/* ---------- 心跳Pulse任务函数 结束---------- */

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//开机信息发送
void InfoSend(void)
{ u16 xdata u16Cnt; u16 xdata u16Tmp; u8 xdata u8Tmp;        u8 xdata u8Tmp2; u8 xdata u8Cnt; u32 xdata u32Tmp;
       
        if(SysStart == 0xA5 && (RSTFLAG & 0xa) > 0) //***** 热系统启动标志则:计数(供故障重启判断) *****
        {
                WrTxBuf(RSTFLAG); TxBusy = 1; TI = 1; while(TxBusy); //发送复位标志位、延时,用于判断复位原因

                // !!!!!热重启拦截,测试完屏蔽指令!!!!!
                u32Tmp = 1000000; while(u32Tmp--){ if(!u32Tmp){ RX2 = ~RX2; u32Tmp = 1000000;} if(SBUF == 0x55){ break; } } //测试时:循环闪灯,接收0x55跳出

        }
       
        if(SysStart == 0xA5) { return; } //热系统启动标志则:退出

        // ...........以下为测试指令...........
        //FREERTOS任务外执行:定义在xdata的数组u8Ram512[]写读测试,发送2次0~255共512字节
        //IapRead(512,IAP512Rd0,u8Ram512); //读数据扇区0 数组u8Ram512[]写
        u16Tmp = 0;
        while(u16Tmp < 512)
        { u8Ram512[u16Tmp] = u16Tmp & 255; //数组u8Ram512[]写
                WrTxBuf(u8Ram512[u16Tmp++]); //数组u8Ram512[]读               
                if(!TxBusy && (u16Tmp >= TxBufMax/3 || u16Tmp == 512)){ TxBusy = 1; TI = 1; } //启动发送
                while(TxBusy); //等待发送完
        }
        // 测试结果:正常
        // ...........测试指令 结束...........

} //开机信息发送结束

//——————————————————————————————————————————————————————————————————————————————————————————————————————————————————

/* ---------- 主函数 结束---------- */
void main( void )
{
  /* 系统初始化 */
  WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
        EAXFR = 1; //允许访问扩展XFR

  P0M1 = 0x00;   P0M0 = 0x00;     //设置为准双向口
  P1M1 = 0x00;   P1M0 = 0x00;     //设置为准双向口
  P2M1 = 0x00;   P2M0 = 0x00;     //设置为准双向口
  P3M1 = 0x00;   P3M0 = 0x00;     //设置为准双向口
  P4M1 = 0x00;   P4M0 = 0x00;     //设置为准双向口
  P5M1 = 0x00;   P5M0 = 0x00;     //设置为准双向口
  P6M1 = 0x00;   P6M0 = 0x00;     //设置为准双向口
  P7M1 = 0x00;   P7M0 = 0x00;     //设置为准双向口

        Uart1Ini(); //串口1初始化
       
  // !!!!!!!!!! Uart中断服务中使用信号量管理 !!!!!!!!!!
        //xSemaphoreUart1 = xSemaphoreCreateBinary(); //Uart1二值信号量创建
        //xSemaphoreGive(xSemaphoreUart1);//发送新信号量
  //xSemaphorePulse = xSemaphoreCreateBinary(); //心跳Pulse二值信号量创建
        //xSemaphoreGive(xSemaphorePulse);//发送新信号量

        //等待信号量,如果INCLUDE_vTaskSuspend置位“1”,则指定阻塞时间置portMAX_DELAY时无超时
        //xSemaphoreTake(xSemaphoreUart1, 0); //读信号量后清除
        //xSemaphoreTake(xSemaphorePulse, 0); //读信号量后清除

  /* ---------- 创建任务 ---------- */
        xTaskCreate((TaskFunction_t )vUart1_Task,        /* 指向任务函数的指针 */
                                (const char*    )"Uart1_task",             /* 任务的文本名字,只会在调试中用到 */
                                (uint16_t       )configDEFAULT_STACK_SIZE, /* 栈深度 */
                                (void*          )NULL,                     /* 没有任务参数 */
                                (UBaseType_t    )configDEFAULT_PRIORITIES, /* 任务运行优先级 */
                                (TaskHandle_t*  )&Uart1_Task_Handler);     /* 任务句柄 */
                               
        xTaskCreate((TaskFunction_t )vPulse_task,        /* 指向任务函数的指针 */
                                (const char*    )"Pulse_task",             /* 任务的文本名字,只会在调试中用到 */
                                (uint16_t       )configDEFAULT_STACK_SIZE, /* 栈深度 */
                                (void*          )NULL,                     /* 没有任务参数 */
                                (UBaseType_t    )configDEFAULT_PRIORITIES, /* 任务运行优先级 */
                                (TaskHandle_t*  )&Pulse_Task_Handler);     /* 任务句柄 */
        /* ---------- 创建任务 结束 ---------- */
                               
        InfoSend(); //开机信息发送       
        SysStart = 0xA5;//置已启动标志,启动时判断:是否热复位重启或上电启动
        RSTFLAG = 0x1f; //InfoSend函数中使用了复位标志位RSTFLAG,清除各复位标志位(B7~B5保留)
       
  /* ---------- 启动任务调度器开始任务调度 ---------- */
  vTaskStartScheduler();
   
  /* !!!!!!!!!! 正常情况下不会运行到此处 !!!!!!!!!! */
        SoftRst = 1; // @@@@@@@@@@ 软件复位        @@@@@@@@@@
  while (1); //死循环
}
/* ---------- 主函数 结束---------- */
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-17 16:29:18 | 显示全部楼层
FreeRTOs任务portTASK_FUNCTION( vUart1_Task, pvParameters )内://u8  u8Ram512[512]; //EEPROM数据区512字读写映射,尾2字校验和(数组定义在edata区:任务外写读正常,任务内写读正常)
u8  xdata u8Ram512[512]; //EEPROM数据区512字读写映射,尾2字校验和(数组定义在xdata区:任务外写读正常,任务内写读异常)
麻烦大佬们分析下。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-18 11:06:22 | 显示全部楼层
STC32G12K128 FREERTOS任务内xdata区域如何访问?与下表哪些项目设置相关?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:232
  • 最近打卡:2025-04-30 11:43:15

26

主题

67

回帖

1184

积分

金牌会员

积分
1184
发表于 2024-4-18 11:07:40 | 显示全部楼层
截图202404181106354967.jpg
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:55 , Processed in 0.158605 second(s), 87 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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