【问题标题】:Linked List From Flash memory transitioning into Ram从闪存过渡到 RAM 的链表
【发布时间】:2013-05-11 15:53:09
【问题描述】:

好吧,我是新来的,所以请放轻松:)

我目前正在使用 C 语言开发一个 uC,并在每次用户想要创建结构时使用链表来创建结构。示例:

typedef struct {
char*                   dataitem;
struct listelement      *link;
int16_t                 wordSize;
int16_t                 (*libWord)[Q];
char                    gpioValue;
}listelement;

listelement * AddItem (listelement * listpointer, char* name, int16_t size, int16_t wordLength, int16_t (*words)[L][Q]) {
// returns listPointer at the beginning of list
listelement * lp = listpointer;
listelement * listPointerTemp;
char ErrorHandler = NULL;
// are we at the end of the list?
if (listpointer != NULL) {
    // move down to the end of the list
    while (listpointer -> link != NULL)
    listpointer = listpointer -> link;
    listPointerTemp = listpointer;
    listpointer -> link = (struct listelement  *) malloc (sizeof (listelement));
    // on fail end links becomes NULL already above
    if(listpointer -> link != NULL){
        listpointer = listpointer -> link;
        listpointer -> link = NULL;
        listpointer -> wordSize = wordLength;

        listpointer -> dataitem = (char*) malloc ((size + 1)*sizeof(char));
        if(listpointer -> dataitem != NULL){
            for(int i=0; i<size ; i++){
                listpointer -> dataitem[i] = name[i];
            }
            listpointer -> dataitem[size] = NULL;

            listpointer -> libWord =  (int16_t(*)[Q])malloc(wordLength*Q*sizeof(int16_t));
            if(listpointer -> libWord != NULL){
                for (int16_t row=0 ; row < wordLength ; row++){
                    for (int col=0 ; col < Q ; col++){
                        listpointer -> libWord[row][col]  = words[0][row][col];
                    }
                }
                ErrorHandler = 1;
            }else{
                free(listpointer->dataitem);
                free(listpointer);
                listPointerTemp -> link = NULL;
            }
        }else{
            free(listpointer);
            listPointerTemp -> link = NULL;
        }
    }
    if(ErrorHandler == NULL){
        //failure
        usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
        usart_write_line(&AVR32_USART0,"Ran out of Memory!  Word not created.\r\n");
        usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
    }
    return lp;
}
else {
    listpointer = (struct listelement  *) malloc (sizeof (listelement));

    if(listpointer != NULL){
        listpointer -> link = NULL;
        listpointer -> wordSize = wordLength;

        listpointer -> dataitem = (char*) malloc (sizeof(name));
        if(listpointer -> dataitem != NULL){
            for(int16_t i=0; i<size ; i++){
                listpointer -> dataitem[i] = name[i];
            }

            listpointer -> libWord =  (int16_t(*)[Q])malloc(wordLength*Q*sizeof(int16_t));
            if(listpointer -> libWord != NULL){
                for (int16_t row=0 ; row < wordLength ; row++){
                    for (int col=0 ; col < Q ; col++){
                        listpointer -> libWord[row][col]  = words[0][row][col];
                    }
                }
                ErrorHandler = 1;
            }else{
                free(listpointer->dataitem);
                free(listpointer);
                listPointerTemp -> link = NULL;
            }
        }else{
            free(listpointer);
            listPointerTemp -> link = NULL;
        }
    }
    if(ErrorHandler == NULL){
        //failure
        usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
        usart_write_line(&AVR32_USART0,"Ran out of Memory!  Word not created.\r\n");
        usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
    }
    return listpointer;
}
}

所以现在我想使用 const 添加已经存储在内存中的结构:

    // start to include words, then merge into structures for user_interactive to link lists with
//////////////////////////////////////////////////////////////////////////////////////////////////
//                                          TRON
//////////////////////////////////////////////////////////////////////////////////////////////////

const int16_t libWord1[10][Q] = {   {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},        
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                            {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},    };


const char dataitem1[4] = {'T','r','o','n'};

const int16_t wordSize1 = 10, nameSize = 4;

//////////////////////////////////////////////////////////////////////////////////////////////////

// eventually change NULL to next link in link list
const listelement Tron = { dataitem1, NULL, wordSize1, libWord1, 0x00 }; 

好吧,即使你跳过所有这些,我只是想知道有什么好的方法可以以某种方式创建常量结构(我必须为 const 类型创建一个新的结构格式吗?)然后链接用户在启动时创建的链表的 Flash 部分创建第一个时的 RAM 链表?

如果需要更多信息,请告诉我。我尽量不在这里放太多代码。

谢谢!

所以这里是变化和效果:

// start to include words, then merge into structures for user_interactive to link lists with
//////////////////////////////////////////////////////////////////////////////////////////////////
//                                          TRON
//////////////////////////////////////////////////////////////////////////////////////////////////

const int16_t libWord1[10][Q] = {   {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},        
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
                                    {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},    };

//////////////////////////////////////////////////////////////////////////////////////////////////
//                                          ON
//////////////////////////////////////////////////////////////////////////////////////////////////

const int16_t libWord2[10][Q] = {   {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},        
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
                                    {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1},    };

//////////////////////////////////////////////////////////////////////////////////////////////////

// eventually change NULL to next link in link list
const listelement* Tron = { "Tron", NULL, 10, libWord1, 0x00 };
// next element links to Tron . . .
const listelement* On = { "On", Tron, 10, libWord2, 0x01 };
// next element links to On . . . and so on . . .

listelement* constLinkInit(void){
    return On;
}

我知道我没有做你的全局结构数组,但忽略了它并使用函数将最后一个结构传递给另一个文件中的这个人。

listelement *listpointer;

    // initially listpointer is initialized to NULL but now set to end of link list of FLASH
    listpointer = constLinkInit();

即使传递给 listpointer (On) 的地址是正确的,当指向下一个链接时,像我对用户定义的结构所做的那样动态地打印链接(它已经工作)失败了。

void PrintQueue (listelement * listpointer) {
    usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
    if (listpointer == NULL){
        usart_write_line(&AVR32_USART0,"queue is empty!\r\n");
    }else{
        //usart_write_line(&AVR32_USART0,"               Word List                    \r\n");
        //usart_write_line(&AVR32_USART0,"--------------------------------------------\r\n");
        while (listpointer != NULL) {
            //usart_write_line(&AVR32_USART0, listpointer -> dataitem);
            //usart_write_line(&AVR32_USART0,"\r\n");
            //writeCOM_int_array(listpointer -> libWord , listpointer -> wordSize);
            listpointer = listpointer -> link;   // <---- FAILS HERE
        }
    }
    usart_write_line(&AVR32_USART0,"\r\n--------------------------------------------\r\n");
}

当指向下一个链接时,它会转到错误的地址。 . .

感谢您的帮助!

【问题讨论】:

  • 顺便说一句:链表代码很糟糕,恕我直言。它可以缩小到其大小的 1/3 左右。 BTW2:(*libWord)[Q]; 是什么东西?只是一个固定大小的指针数组?
  • 是的,你很可能会比我写得更好,这就是为什么我要问你们,“专家”:)。简单地说,它是固定在列中的,但在代码中因行而异。
  • 请注意 dataitem1 不是 NUL 终止的。应该是:char dataitem1[] = "Tron";char *dataitem1 = "Tron";(是的,我知道,你正在传递一个 size 参数,但它看起来过于复杂。)
  • 新代码是“谢谢”下面的所有内容,但是我同意在我看到你是如何做到的之前它过于复杂。谢谢!
  • 请添加-&gt;dataitem 元素的意图。它应该包含什么,指针或实际数据? (IMO 其用法与其定义冲突)

标签: c linked-list embedded


【解决方案1】:

这样的事情应该可以工作:

#include <stdlib.h>
#include <stdint.h>

#define Q 5


typedef struct {
 char                    *dataitem;
 struct listelement      *link;
 int16_t                 wordSize;
 int16_t                 (*libWord)[Q];
 char                    gpioValue;
 } listelement;

int16_t zzz[Q] = { 11, 22,33,44,55};

listelement global_array[] =
{{ "Sron", global_array+1, 2, zzz , 0 }
,{ "Tron", global_array+2, 2, zzz , 0 }
,{ "Uron", global_array+3, 2, zzz , 0 }
,{ "Vron", NULL          , 2, zzz , 0 }
};

【讨论】:

  • 所以我试图在你的例子中制作 const listelement global_array[] 但是当指向下一个链接时它会转到错误的地址。 . .想法?
  • 如果它是 const (或者更糟:在 ROM 中),您无法更改最终的 ->link 指针,因此您将无法向列表中添加任何内容。顺便说一句:您必须找到一种方法来区分 fixed 节点和 malloc()ed 节点。当给定一个指向非动态对象的指针时,Free() 肯定会使你的程序崩溃。
  • 我就是这么想的。我将发布一个简化的示例,说明我的意思是尝试使用定义为 const 的两个单词来尝试您的代码,以及在调试模式下会发生什么。 . .
  • ROM/RAM 信息已编码在指针中。您可以在致电free()之前查看地址。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2018-05-14
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
相关资源
最近更新 更多