Как заставить работать код MSP430 без использования библиотек? - PullRequest
0 голосов
/ 16 апреля 2020

Хорошо, поэтому я пытаюсь отказаться от Energia Texas Instruments в стиле Arduino Ide, и я использовал IAR для кодирования платы разработки серии Tiva C, где я мог использовать указатели на ячейки памяти для выполнения определенных c таких вещей, как переключение привел например. Мне было трудно сделать то же самое на плате разработчика под управлением MSP430FR5994 mcu, я знаю, что адрес памяти зеленого светодиодного контакта - PORT 1 PIN 1 ИЛИ P1.1 на плате. Я также включил заголовочный файл msp430.h для API для платы от моего ide. Чего я не понимаю, так это того, почему при отладке мой код меняет значение правильных регистров на правильные числа, но не меняет плату. Я также проверил, что он подключен к плате, так как он не будет продолжать отладку с отключенным. Мои прямые вопросы таковы: 1 Я должен иметь возможность изменять места в памяти без заголовочных файлов или каких-либо специальных API, если я знаю, что указанные адреса c правильные? 2 Я не видел ничего о синхронизации часов в листе данных, и в отладке я вижу, что эти регистры меняют значения, так что есть ли что-то кроме установки направления и значения вывода, которые мне нужно сделать? (Функция вывода по умолчанию - generi c gpio Я проверил, поэтому оставил этот регистр в покое. Любые идеи или указания на очевидные ошибки в моем подходе были бы очень полезны, спасибо. В приведенном ниже коде я использовал имена файлов заголовков, так как не мог заставить работать прямые указатели. Также я был сбит с толку техническим паспортом, так как базовый адрес для порта 1 был записан как 0200H, который представляет собой 5 шестнадцатеричных чисел, когда я ожидал 4, поскольку чип является 16-битной системой? это предположение? регистрируется во время отладки изображения

ti.com / lit / ds / symlink / msp430fr5994.pdf (таблица данных, порт 1 mem, стр. 130)

#include <msp430.h> 
/**
 * main.c
 */
int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    while(1){
    int i ;
    int j ;

    P1DIR = 2;
    //*((unsigned int *)0x204Hu) = 2;

    P1OUT = 2;
    //*((unsigned int *)0x202Hu)= 2;
    for( i = 0; i< 2 ; i++){}

    P1OUT = 0;
    //*((unsigned int *)0x202Hu)= 0;

    for (j = 0 ; j< 2; j++){}


    }

    return 0;
}

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

Это получено из одного из моих примеров, у меня нет удобной карты для тестирования, но она должна просто работать или быть близко.

startup.s

.word hang      /* 0xFFE0 */
.word hang      /* 0xFFE2 */
.word hang      /* 0xFFE4 */
.word hang      /* 0xFFE6 */
.word hang      /* 0xFFE8 */
.word hang      /* 0xFFEA */
.word hang      /* 0xFFEC */
.word hang      /* 0xFFEE */
.word hang      /* 0xFFF0 */
.word hang      /* 0xFFF2 */
.word hang      /* 0xFFF4 */
.word hang      /* 0xFFF6 */
.word hang      /* 0xFFF8 */
.word hang      /* 0xFFFA */
.word hang      /* 0xFFFC */
.word reset     /* 0xFFFE */

сброс .s

.global reset
reset:

      mov #0x03FF,r1
      call #notmain
      jmp hang

    .global hang
    hang:
      jmp hang

    .globl dummy
    dummy:
        ret

т. c

void dummy ( unsigned short );

#define WDTCTL     (*((volatile unsigned short *)0x015C))

#define P1OUT (*((volatile unsigned short *)0x0202))
#define P1DIR (*((volatile unsigned short *)0x0204))

void notmain ( void )
{
    unsigned short ra;

    WDTCTL = 0x5A80;

    P1DIR|=0x02;

    while(1)
    {
        P1OUT |= 0x0002;
        for(ra=0;ra<10000;ra++) dummy(ra);
        P1OUT &= 0xFFFD;
        for(ra=0;ra<10000;ra++) dummy(ra);
    }
}

memmap

MEMORY
{
    rom : ORIGIN = 0xC000, LENGTH = 0xFFE0-0xC000
    ram : ORIGIN = 0x1C00, LENGTH = 0x2C00-0x1C00
    vect : ORIGIN = 0xFFE0, LENGTH = 0x20
}
SECTIONS
{
    VECTORS : { startup.o } > vect
    .text :  { *(.text*) } > rom
    .bss : { *(.bss*) } > ram
    .data : { *(.data*) } > ram
}

build

msp430-gcc -Wall -O2 -c so.c -o so.o
msp430-ld -T memmap reset.o so.o startup.o -o so.elf
msp430-objdump -D so.elf > so.list
msp430-objcopy -O ihex so.elf out.hex

проверить вывод

so.elf:     file format elf32-msp430


Disassembly of section VECTORS:

0000ffe0 <VECTORS>:
    ffe0:   0a c0           bic r0, r10 
    ffe2:   0a c0           bic r0, r10 
    ffe4:   0a c0           bic r0, r10 
    ffe6:   0a c0           bic r0, r10 
    ffe8:   0a c0           bic r0, r10 
    ffea:   0a c0           bic r0, r10 
    ffec:   0a c0           bic r0, r10 
    ffee:   0a c0           bic r0, r10 
    fff0:   0a c0           bic r0, r10 
    fff2:   0a c0           bic r0, r10 
    fff4:   0a c0           bic r0, r10 
    fff6:   0a c0           bic r0, r10 
    fff8:   0a c0           bic r0, r10 
    fffa:   0a c0           bic r0, r10 
    fffc:   0a c0           bic r0, r10 
    fffe:   00 c0           bic r0, r0  

Disassembly of section .text:

0000c000 <reset>:
    c000:   31 40 ff 03     mov #1023,  r1  ;#0x03ff
    c004:   b0 12 0e c0     call    #0xc00e 
    c008:   00 3c           jmp $+2         ;abs 0xc00a

0000c00a <hang>:
    c00a:   ff 3f           jmp $+0         ;abs 0xc00a

0000c00c <dummy>:
    c00c:   30 41           ret         

0000c00e <notmain>:
    c00e:   0b 12           push    r11     
    c010:   b2 40 80 5a     mov #23168, &0x015c ;#0x5a80
    c014:   5c 01 
    c016:   a2 d3 04 02     bis #2, &0x0204 ;r3 As==10
    c01a:   a2 d3 02 02     bis #2, &0x0202 ;r3 As==10
    c01e:   0b 43           clr r11     
    c020:   0f 4b           mov r11,    r15 
    c022:   b0 12 0c c0     call    #0xc00c 
    c026:   1b 53           inc r11     
    c028:   3b 90 10 27     cmp #10000, r11 ;#0x2710
    c02c:   f9 23           jnz $-12        ;abs 0xc020
    c02e:   b2 f0 fd ff     and #-3,    &0x0202 ;#0xfffd
    c032:   02 02 
    c034:   0b 43           clr r11     
    c036:   0f 4b           mov r11,    r15 
    c038:   b0 12 0c c0     call    #0xc00c 
    c03c:   1b 53           inc r11     
    c03e:   3b 90 10 27     cmp #10000, r11 ;#0x2710
    c042:   f9 23           jnz $-12        ;abs 0xc036
    c044:   ea 3f           jmp $-42        ;abs 0xc01a

выглядит хорошо, таблица векторов есть и указывает на правильное место и т. Д. c.

10 000 может быть недостаточно, чтобы увидеть мигание светодиода.

Из таблицы видно, что 0x202 - это P1OUT, а 0x204 - это P1DIR

И вы должны запрограммировать его на плату. Я использую mspdebug для плат, которые у меня есть, но эта программа, возможно, перестала работать на eval досках с некоторого времени go. и mspdebug поддерживал формат Intel hex. Поэтому используйте objcopy для других форматов.

Если вы не хотели использовать инструменты gnu, вам все равно придется иметь дело с таблицей векторов и bootstrap перед кодом C, если вы пытаетесь отойдите от чьей-то песочницы и займитесь своими делами.

Вы на правильном пути, это может быть так же просто, как ваши циклы задержки слишком малы или оптимизированы, поскольку написаны как мертвый код.

Если вы полагаетесь на инициализацию .bss или .data, то у вас есть больше работы в сценарии компоновщика и bootstrap. У меня нет, поэтому у меня нет этой проблемы, на самом деле интересно, почему .data был в этом скрипте компоновщика ...

Я сопоставил адреса с таблицей с вашей стороны, увеличив шансы на успех. Если вы используете внешнюю функцию и передаете в нее переменную l oop (внешняя может быть C или asm, не имеет значения), оптимизатор не удалит ее как мертвый код. Или добавьте volatile в переменную l oop и проверьте разборку, чтобы убедиться, что она не была удалена.

0 голосов
/ 17 апреля 2020

См. Раздел 12.3.1 MSP430FR59xx. Руководство пользователя. .

. После сброса BOR все выводы порта имеют высокий импеданс с триггерами Шмитта и их функции модуля отключены. предотвратить любые перекрестные токи. Приложение должно инициализировать все выводы порта, включая неиспользуемые (Раздел 12.3.2), в качестве входного высокого импеданса, входного сигнала с понижающим напряжением, входного сигнала с повышающим напряжением, высокого выходного сигнала или низкого уровня выходного сигнала в соответствии с потребностями приложения путем настройки PxDIR, PxREN, PxOUT и PxIES. соответственно. Эта инициализация вступает в силу, как только бит LOCKLPM5 в регистре PM5CTL (описанный в главе PMM) очищается; до тех пор входы / выходы остаются в состоянии высокого импеданса с отключенными триггерными входами Шмитта.

А вот примерный код blinky, представленный в примерах кода MSP430FR599x, доступных для загрузки здесь: здесь .

#include <msp430.h>

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // Stop WDT

    // Configure GPIO
    P1OUT &= ~BIT0;                         // Clear P1.0 output latch for a defined power-on state
    P1DIR |= BIT0;                          // Set P1.0 to output direction

    PM5CTL0 &= ~LOCKLPM5;                   // Disable the GPIO power-on default high-impedance mode
                                            // to activate previously configured port settings

    while(1)
    {
        P1OUT ^= BIT0;                      // Toggle LED
        __delay_cycles(100000);
    }
}

Возможно, вам нужно добавить эту строку PM5CTL0 &= ~LOCKLPM5; в ваш код.

И затем пошагово пройти по коду в отладчике, чтобы увидеть светодиод. Потому что, если вы позволите вашему коду работать на полной скорости, петли задержки будут слишком короткими, чтобы наблюдать за светодиодом fla sh вашим глазом.

...