【问题标题】:XC16 Put a data table in PSV memory (PIC)XC16 将数据表放入 PSV 内存 (PIC)
【发布时间】:2021-02-19 18:26:31
【问题描述】:

我想在 Flash 中放置一个表格并直接从我的 C 程序中读取它。根据 Microchip 的说法,这是由 __attribute__((space(psv))) 完成的。但是,作为 microchip 周围的大多数事情,他们自己的示例效果不佳(通常已过时且未更新):https://microchipdeveloper.com/16bit:psv

这就是我想要做的:

uint16_t __attribute__((space(psv))) ConfDiskImage[] = {
    /*AOUT*/ 0x01E0,0x0004,0x3333,0x4053,
    /*   1*/ 0x01E1,0x0012,0x0005,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*   2*/ 0x01E2,0x0012,0x0006,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*   3*/ 0x01E3,0x0012,0x0007,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*EOD */ 0x0000,0x0000
};

当我编译时,我得到:"warning: ignoring space attribute applied to automatic ConfDiskImage"

我正在使用 MPLAB X IDE 5.45 和 XC16-gcc v1.50。 微控制器:dsPIC33EP256MC506

关于如何让它留在闪存中(不被复制到 RAM)并使用指针直接从闪存读取它的任何想法?

【问题讨论】:

  • 尝试添加 const 说明符。
  • 没有上下文[更多代码],我猜...您将其定义为函数范围变量(来自“自动”)。我认为您拥有的是(例如):int main(void) { uint16_t __attribute__((space(psv))) ConfDiskImage[] = { ... }; } 您可能需要的是全局范围(例如):uint16_t __attribute__((space(psv))) ConfDiskImage[] = { ... }; int main(void) { } 如果您添加了static,您原来的可能工作
  • @Craig Estey DOH!!!我很确定这是问题所在。我把它作为一个测试概念扔进去,所以我很确定它在 main 函数中。为了我的辩护,星期五晚上在办公室已经很晚了:)我会在星期一马上处理。

标签: c memory pic xc16


【解决方案1】:

我怀疑您真正需要的内容可能更多,但您提出的问题的简单答案是使用 const 存储类。

例如:

/*
 * File:   main.c
 * Author: dan1138
 * Target: dsPIC33EP256MC506
 * Compiler: XC16 v1.61
 * IDE: MPLABX v5.45
 *
 * Created on February 19, 2021, 11:56 PM
 */

#pragma config ICS = PGD2, JTAGEN = OFF, ALTI2C1 = OFF, ALTI2C2 = OFF, WDTWIN = WIN25
#pragma config WDTPOST = PS32768, WDTPRE = PR128, PLLKEN = ON, WINDIS = OFF
#pragma config FWDTEN = OFF, POSCMD = NONE, OSCIOFNC = ON, IOL1WAY = OFF, FCKSM = CSECMD
#pragma config FNOSC = FRCDIVN, PWMLOCK = OFF, IESO = ON, GWRP = OFF, GCP = OFF

#include "xc.h"

const uint16_t ConfDiskImage[] = {
    /*AOUT*/ 0x01E0,0x0004,0x3333,0x4053,
    /*   1*/ 0x01E1,0x0012,0x0005,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*   2*/ 0x01E2,0x0012,0x0006,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*   3*/ 0x01E3,0x0012,0x0007,0x0000,0x0000,0x0000,0x4120,0x0000,0x0000,0x0000,0x4120,
    /*EOD */ 0x0000,0x0000
};

int main(void) 
{
    const uint16_t *pData;
    
    pData = ConfDiskImage; /* point to the start of the image */
    /*
     * Walk the image
     */
    for(;;)
    {
        if((!*pData) && (!*pData+1))
        {
            /* At end of image point to the start */
            pData = ConfDiskImage;
        }
        pData++; /* skip record type */
        pData += 1+*pData/2;
    }
    return 0;
}

【讨论】:

  • 我也这样做了,但正如@Craig Estey 指出的那样,这可能是因为它主要作为本地范围。我会在星期一检查。
  • 你没有发布一个完整的、可构建的示例程序。我发布了一个完整的示例,可以满足您的要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
相关资源
最近更新 更多