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

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

[复制链接]
  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

    积分
    437
    发表于 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[]数据不正常!
    回复 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

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

    使用道具 举报

    该用户从未签到

    19

    主题

    519

    回帖

    1642

    积分

    荣誉版主

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

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

    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

    积分
    437
     楼主| 发表于 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); //死循环
    }
    /* ---------- 主函数 结束---------- */
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

    积分
    437
     楼主| 发表于 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区:任务外写读正常,任务内写读异常)
    麻烦大佬们分析下。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

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

    使用道具 举报

  • TA的每日心情
    奋斗
    1 小时前
  • 签到天数: 79 天

    [LV.6]常住居民II

    13

    主题

    31

    回帖

    437

    积分

    中级会员

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

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-4-30 11:53 , Processed in 0.067794 second(s), 56 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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