XC8: .asm to C ( i.e. Lowering One's Expectations)

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Got back to work this morning. Creating a separate .c file with the initialization values do eliminate the error -- so the proposed solution is correct. I still want to know specifically why the warning is thrown to begin with.

As feared, it does break the abstraction I was trying to create.

What'd be nice if MPLABX had a way to manage const string resources (separate from the actual code) and push them into program memory at the right place during build time. That doesn't exist, right?

Edit: BTW, thanks for your help, guys. For what it's worth: .asm is far more powerful for the things that I do. This excursion into embedded C is very frustrating for me. As a reminder, I've been coding C apps since 1994, and .asm since 1979. I am not a novice.
 

ApacheKid

Joined Jan 12, 2015
1,762
Got back to work this morning. Creating a separate .c file with the initialization values do eliminate the error -- so the proposed solution is correct. I still want to know specifically why the warning is thrown to begin with.

As feared, it does break the abstraction I was trying to create.

What'd be nice if MPLABX had a way to manage const string resources (separate from the actual code) and push them into program memory at the right place during build time. That doesn't exist, right?

Edit: BTW, thanks for your help, guys. For what it's worth: .asm is far more powerful for the things that I do. This excursion into embedded C is very frustrating for me. As a reminder, I've been coding C apps since 1994, and .asm since 1979. I am not a novice.
This could be a compiler error, they do exist. I too have worked with C extensively since 1990 and written and maintained large systems and APIs on minicomputers (high availability 24/7 trading and broking systems) and Windows 32bit then 64bit. I haven't used it much at all since 2014 or so and only resumed recently while playing with STM32 boards.

I'm curious about this question

What'd be nice if MPLABX had a way to manage const string resources (separate from the actual code) and push them into program memory at the right place during build time. That doesn't exist, right?
Is this a C specific question or perhaps a platform/implementation question? I'd expect any initialized static const entity to be placed into static storage or some static section (depending on the target OBJ file requirements).
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Is this a C specific question or perhaps a platform/implementation question?
It's a platform question. Many tool chains allow the inclusion of resource files (typically with a .res extenstion) where constant strings, numeric values, bitmaps, whatever, can be stored separate from the code, and invoked via labels or handles through associated library function calls. The constants get pushed into the object code image during build.

It's a really nice way to abstract the hard-coded data from the actual code.

I am assuming this functionality does not exist in MPLABX. Correct?
 

nsaspook

Joined Aug 27, 2009
16,333
Got back to work this morning. Creating a separate .c file with the initialization values do eliminate the error -- so the proposed solution is correct. I still want to know specifically why the warning is thrown to begin with.

As feared, it does break the abstraction I was trying to create.

What'd be nice if MPLABX had a way to manage const string resources (separate from the actual code) and push them into program memory at the right place during build time. That doesn't exist, right?

Edit: BTW, thanks for your help, guys. For what it's worth: .asm is far more powerful for the things that I do. This excursion into embedded C is very frustrating for me. As a reminder, I've been coding C apps since 1994, and .asm since 1979. I am not a novice.
Those are cards you are dealt with C the language.
Everything eventually needs an address so C must have some symbolic location for each resource that can be linked into the program if static allocation of resources is used.

I've not found using .c files for program resources restrictive for static allocation of resources but we all have our notions of what we want.
1668013051765.png
Init the GLCD and show a image foo_map
C:
void init_lcd_drv(LCD_DVR_STATE init_type)
{
    delay_freq = CORETIMER_FrequencyGet() / 1000000;
    switch (init_type) {
    case D_MISC:
    case D_INIT: // send the GLCD buffer data via DMA
        CSB_SetHigh(); // select SPI GLCD display, DOGXL240 @15MHz SPI clock
        delay_us(IS_DELAYPOWERUP); // > 400ms power up delay
        lcd_init();
        OledInit();
        OledSetCharUpdate(0); // manual LCD screen updates for speed
        OledMoveTo(bmp_x, bmp_y); // position image
        OledPutBmp(bmp_size, bmp_size, (uint8_t *) foo_map); // upload bitmap image from C array
        delay_us(BMP_DELAY); // show image for a bit
        break;
    default:
        break;
    }

}
C:
/*
 * File:   lcd_drv.h
 * Author: root
 *
 * Created on October 12, 2021, 7:01 PM
 */

#ifndef LCD_DRV_H
#define    LCD_DRV_H

#ifdef    __cplusplus
extern "C" {
#endif

#define DMA_MAGIC    1957
#define USE_DMA // use DMA spi driver

#ifdef USE_DMA
#define    DMA_GAP        1    // set to 0 for SPI byte gaps in DMA transmissions
#define DMA_STATE_M
#endif

#define EDOGS

    /*
     * DMA driver for DOGXL240 @15MHz SPI clock
     * 2021 XC32 and H3
     */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "definitions.h"                // SYS function prototypes
#ifdef __32MK0512MCJ048__X
#include "../src/config/mcj/peripheral/spi/spi_master/plib_spi_master_common.h"
#include "../src/config/mcj/peripheral/gpio/plib_gpio.h"
#include "../src/config/mcj/peripheral/dmac/plib_dmac.h"
#include "../src/config/mcj/peripheral/coretimer/plib_coretimer.h"
#endif
#ifdef __32MZ1025W104132__X
#include "../src/config/default/peripheral/spi/spi_master/plib_spi_master_common.h"
#include "../src/config/default/peripheral/gpio/plib_gpio.h"ww
#include "../src/config/default/peripheral/dmac/plib_dmac.h"
#include "../src/config/default/peripheral/coretimer/plib_coretimer.h"
#endif
#include "display_type.h"
#include "eadog.h"
#include "dogm-graphic.h"
#include "OledDriver.h"
#include "OledChar.h"
#include "OledGrph.h"

#include "device.h"

#define BMP_DELAY    3000000    // image display delay counts
#define bmp_x        60        // syoucreen positions of image
#define bmp_y        24
#define bmp_size    100        // x,y size of image
#define    BANK1        0xA000A000    // bank 1 frame buffer memory address
#define    BANK2        0x80030000    // bank 2 frame buffer memory address
    
#define LCD_DRIVER    "V1.002" 
#define LCD_ALIAS    "EADOG LCD"

    typedef enum {
        D_INIT,
        D_MISC,
    } LCD_DVR_STATE;

#define lcd_frame    0    // frame buffer 1 or 0

    void init_lcd_drv(LCD_DVR_STATE init_type);
    void lcd_version(void);

    extern const uint8_t foo_map[]; // image in flash array

#ifdef    __cplusplus
}
#endif

#endif    /* LCD_DRV_H */
foo.c
C:
#include "lcd_drv.h"

Image converted to C hex bitmap compatible with graphics buffer.
/*
 * image2cpp
 * created using https://javl.github.io/image2cpp/
 * plain bytes, Vertical - 1 bit per pixel
 */

const uint8_t foo_map[] = {
// 'foo', 100x100px
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xc1, 0xe1, 0xf1, 0xf9, 0xf9, 0xf9, 0xf1, 0xfd, 
// skip data ....
0x0e, 0x0c, 0x0c, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 
0x08, 0x08, 0x08, 0x08
};
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Don't blame your tools when a tack-hammer won't break a rock with the first hit. The tool is capable, just not in the way you want.
With embedded C, it feels opposite. I'm using a sledge hammer for something where a tack hammer is called for.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Float like a butterfly...
C:
CSB_SetHigh(); // select SPI GLCD display, DOGXL240 @15MHz SPI clock
        delay_us(IS_DELAYPOWERUP); // > 400ms power up delay
        lcd_init();
        OledInit();
        OledSetCharUpdate(0); // manual LCD screen updates for speed
        OledMoveTo(bmp_x, bmp_y); // position image
        OledPutBmp(bmp_size, bmp_size, (uint8_t *) foo_map); // upload bitmap image from C array
        delay_us(BMP_DELAY); // show image for a bit
        break;
This blocking code of yours is breaking my heart.
 

nsaspook

Joined Aug 27, 2009
16,333
C:
CSB_SetHigh(); // select SPI GLCD display, DOGXL240 @15MHz SPI clock
        delay_us(IS_DELAYPOWERUP); // > 400ms power up delay
        lcd_init();
        OledInit();
        OledSetCharUpdate(0); // manual LCD screen updates for speed
        OledMoveTo(bmp_x, bmp_y); // position image
        OledPutBmp(bmp_size, bmp_size, (uint8_t *) foo_map); // upload bitmap image from C array
        delay_us(BMP_DELAY); // show image for a bit
        break;
This blocking code of yours is breaking my heart.
It doesn't matter as it happens ONCE during boot and NEVER again. Using a non-blocking delay here gains NOTHING.

Pick your battles wisely.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Using a non-blocking delay here gains NOTHING.
If I've got lots of hardware to bring up to speed quickly, the gains of inherently non-blocking code are substantial.

And I wasn't even referring to the hard-coded delays. I meant the LCD function calls, each of which take many milliseconds to execute.

Tens of thousands of instruction cycles wasted!
 

ApacheKid

Joined Jan 12, 2015
1,762
It doesn't matter as it happens ONCE during boot and NEVER again. Using a non-blocking delay here gains NOTHING.

Pick your battles wisely.
Unless I misunderstand the platform you two are discussing, isn't the concept of "blocking" and "non-blocking" meaningless without a system that's running multiple threads? under an OS for example?
 

Ian Rogers

Joined Dec 12, 2012
1,136
Looking at your "original" init of said messages... The three strings are of unequal size, C doesn't like that..
You need one more char in the first string.
 

nsaspook

Joined Aug 27, 2009
16,333
If I've got lots of hardware to bring up to speed quickly, the gains of inherently non-blocking code are substantial.

And I wasn't even referring to the hard-coded delays. I meant the LCD function calls, each of which take many milliseconds to execute.

Tens of thousands instruction cycles wasted!
This embedded module is designed to run 7/24 for years non-stop. Boot times are not an issue.

You should know me better than that. All of the normal operational calls use DMA for background transfers for actual screen updates.
https://forum.allaboutcircuits.com/threads/definition-of-driver.190096/post-1774946
https://forum.allaboutcircuits.com/threads/real-world-application-for-rtos-ml.182350/post-1674337
 
Last edited:

nsaspook

Joined Aug 27, 2009
16,333
Unless I misunderstand the platform you two are discussing, isn't the concept of "blocking" and "non-blocking" meaningless without a system that's running multiple threads? under an OS for example?
No it's not meaningless where the controller has modules that don't need cpu because it has real hardware concurrency with things like DMA.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,330
Unless I misunderstand the platform you two are discussing, isn't the concept of "blocking" and "non-blocking" meaningless without a system that's running multiple threads? under an OS for example?
My code runs multiple threads via OS-less cooperative multitasking. Any wait loops consume instruction cycles that can used elsewhere.

Edit: changed "preemptive" to "cooperative".
 
Top